/**
 * NPC «Пепельных луга»: определения (id/имя/позиция v1/диалоги/флаг
 * знакомства), размещения по флагу сюжета (Клинт появляется в роще только
 * после крючка Милы — контент не живёт вне своей главы). Позиция v1 —
 * в тайлах (центр тайла = координата); в воксели конвертирует сцена
 * (tileCenter). Перенос v1, тайл-мост тот же.
 */
import { FLAGS, type FlagId } from './ids';
import type { MannequinPalette } from '@rpg/engine';

/** NPC локации: диалоги и флаг сюжета после первого разговора. */
export interface NpcDef {
    id: string;
    name: string;
    /** id области (v1: статичные жили в городе; в v2 область — явно). */
    area: string;
    /** Позиция ног в тайлах v1 (центр тайла = координата + 0.5). */
    pos: { x: number; y: number };
    /** Тайл привязки (floor от pos; вычисляется — в контенте не писать). */
    tile: { x: number; y: number };
    /** Первый диалог (когда флаг ещё не поднят). */
    dialogueFirst: string;
    /** Повторный диалог. */
    dialogueRepeat: string;
    /** Флаг, поднимаемый после первого диалога (ставит сам граф). */
    flagKey: FlagId;
    /** Палитра модели (голова/торс/ноги/рукава) — дизайн персонажа. */
    colors: MannequinPalette;
}

/** NPC из raw-определения (тайл-мост общий для статичных и размещений). */
function npcFrom(d: Omit<NpcDef, 'tile'>): NpcDef {
    return { ...d, tile: { x: Math.floor(d.pos.x), y: Math.floor(d.pos.y) } };
}

/** Статичные NPC: старейшина и торговка — в Звенце. */
export const NPCS: NpcDef[] = [
    npcFrom({
        id: 'elder',
        name: 'Старейшина Ирвин',
        area: 'zvenets',
        // Не вплотную ни к двери дома (13,12), ни к колодцу (16,13): кнопка
        // действия берёт ближайшую цель, E у двери/колодца не должен звать
        // Ирвина — он стоит юго-западнее, вне радиуса их тайлов подхода.
        pos: { x: 12.5, y: 15.5 },
        dialogueFirst: 'elder_first',
        dialogueRepeat: 'elder_repeat',
        flagKey: FLAGS.met_elder,
        // Старейшина: седые волосы, тёплая кожа (не в тон волосам — иначе
        // лицо сливается с сединой и читается как череп), зелёный плащ
        colors: {
            skin: '#a89a82', hair: '#b8b4a4', torso: '#5d7050', legs: '#4a4440',
            arms: '#4a4440', boots: '#3a3532', belt: '#6e5a3a',
        },
    }),
    npcFrom({
        id: 'trader',
        name: 'Торговка Мила',
        area: 'zvenets',
        // Не вплотную к двери лавки (43,19): E у двери не должен звать Милу.
        pos: { x: 40.5, y: 20.5 },
        dialogueFirst: 'trader_first',
        dialogueRepeat: 'trader_repeat',
        flagKey: FLAGS.met_mila,
        // Мила: тёмные волосы, ржаво-красный сарафан, светлые штаны
        colors: {
            skin: '#a87f5c', hair: '#4a3223', torso: '#a05a44', legs: '#c9b18a',
            arms: '#a05a44', boots: '#5a4632', belt: '#c9a04a',
        },
    })
];

/**
 * Размещения NPC по флагу: персонаж появляется в области, когда флаг сюжета
 * поднят (и пропадает, если сценарий его снимет).
 */
export interface NpcPlacement {
    /** Флаг, при котором NPC стоит на карте. */
    flag: FlagId;
    def: NpcDef;
}

export const NPC_PLACEMENTS: NpcPlacement[] = [
    {
        // Кузнец-починщик стоит у своего резонатора в роще после крючка Милы.
        flag: FLAGS.act2_hook,
        def: npcFrom({
            id: 'clint',
            name: 'Клинт',
            area: 'rust_grove',
            pos: { x: 23.5, y: 17.5 },
            dialogueFirst: 'clint_first',
            dialogueRepeat: 'clint_repeat',
            flagKey: FLAGS.met_clint,
            // Клинт: тёмная шапка, медный фартук, тёмные штаны
            colors: {
                skin: '#8a7565', hair: '#4a4038', torso: '#c07a3a', legs: '#4d4a46',
                arms: '#8a5230', boots: '#3a3632', belt: '#5a4632',
            },
        })
    }
];

/** NPC области: статичные + размещения по поднятым флагам. */
export function npcsForArea(area: string, hasFlag: (f: FlagId) => boolean): NpcDef[] {
    const statics = NPCS.filter((n) => n.area === area);
    const placed = NPC_PLACEMENTS.filter((p) => p.def.area === area && hasFlag(p.flag)).map((p) => p.def);
    return [...statics, ...placed];
}