import type { NpcDef } from './npcs';
import type { EnemyKindId, EnemyPatrolDef } from './enemies';
import { NPCS } from './npcs';
import type { ItemId } from './items';
import { TILES } from './map';
import { INTERACTABLES, type InteractableDef } from './interactables';

/**
 * Области демо-среза (улица и интерьер — общий контекст). Карты хранятся
 * файлами assets/maps/<id>.map (формат rpg-map, RLE) и загружаются через
 * parseMap в BootScene.
 */
export type AreaId = 'meadows' | 'ponds' | 'zvenets' | 'house_elder' | 'shop';

/** Куда ведёт переход: в другую область (с точкой входа) или назад, откуда вошли. */
export type TransitionTarget =
    | { kind: 'area'; area: AreaId; entry: { x: number; y: number } }
    | { kind: 'return' };

/**
 * Единый механизм переходов: выходы между локациями (step), двери/порталы/
 * колодцы (click). Первая подходящая по тайлу и триггеру — срабатывает.
 */
export interface TransitionDef {
    /** Тайл-триггер. */
    tile: { x: number; y: number };
    /** Подпись для подсказки при близости (позже) и снапшота. */
    label?: string;
    target: TransitionTarget;
    /** step — наступил (по умолчанию), click — клик по тайлу (двери, порталы). */
    trigger?: 'step' | 'click';
    /** Условия: не выполнены — переход не срабатывает, герой получает lockedText. */
    requiresFlag?: string;
    requiresItem?: ItemId;
    lockedText?: string;
    /** Длительность fade (сек), по умолчанию 0.4. */
    duration?: number;
}

/** Зона опасности (накат): герой без нужного предмета еле идёт и рискует голосом. */
export interface HazardDef {
    name: string;
    /** Тайлы низины (свежий пласт пепла). */
    tiles: { x: number; y: number }[];
    /** Без чего нельзя дышать здесь (по умолчанию — полотно-маска). */
    requiresItem?: ItemId;
}

/** Локальный амбиент-слой: громкость из дистанции до ближайшего тайла/точки. */
export interface AmbienceLayerDef {
    /** Ключ лупа (Game.AUDIO_KEYS). */
    key: string;
    /** Тайлы-источники (иды из TILES); пусто/нет — точка at. */
    tiles?: number[];
    /** Точка-источник в тайлах (центр башни и т.п.). */
    at?: { x: number; y: number };
    /** Радиус слышимости в юнитах (за ним слой молчит); нет at/tiles — глобальный слой. */
    radius?: number;
    /** Громкость (для глобального — константа; по умолчанию 0.5). */
    volume?: number;
}

export interface AreaDef {
    id: AreaId;
    name: string;
    /** Амбиент области (кроссфейд при переходе, ключ из Game.AUDIO_KEYS); нет — тишина. */
    ambience?: string;
    /** Музыкальная тема области (ключ из data/music.ts, спек-музыка); нет — тишина. */
    theme?: string;
    /** Стартовый тайл (новая игра / респаун / фолбэк return). */
    spawn: { x: number; y: number };
    npcs: NpcDef[];
    enemies: { kind: EnemyKindId; tile: { x: number; y: number }; patrol?: EnemyPatrolDef }[];
    transitions: TransitionDef[];
    /** Интерактивные объекты (сундуки, очаги, прилавки). */
    interactables?: InteractableDef[];
    /** Атмосферные частицы: 'ash' — пепел, 'fog' — туман прудов, 'none' — интерьер. */
    atmosphere: 'ash' | 'fog' | 'none';
    /** Локальные амбиент-слои поверх областного (вода, гул башни, дома). */
    ambienceLayers?: AmbienceLayerDef[];
    /** Зоны наката (необязательно). */
    hazards?: HazardDef[];
    /** Спавны пейзажных оленей (тайлы). */
    fauna?: { x: number; y: number }[];
}

export const AREAS: Record<AreaId, AreaDef> = {
    meadows: {
        id: 'meadows',
        name: 'Выжженные луга',
        ambience: 'ambience/meadows',
        theme: 'meadows',
        spawn: { x: 14, y: 14 },
        npcs: [],
        enemies: [
            { kind: 'crawler', tile: { x: 8, y: 9 } },
            { kind: 'crawler', tile: { x: 10, y: 7 } },
            // Плевун кружит у северо-восточных бугров.
            {
                kind: 'spitter',
                tile: { x: 19, y: 6 },
                patrol: { points: [{ x: 19, y: 6 }, { x: 22, y: 5 }], pauseSec: 1.2 }
            },
            { kind: 'crawler', tile: { x: 22, y: 21 } },
            // Тяжеловес бродит вдоль юго-западной низины.
            {
                kind: 'heavy',
                tile: { x: 6, y: 22 },
                patrol: { points: [{ x: 6, y: 22 }, { x: 4, y: 20 }], pauseSec: 2 }
            }
        ],
        transitions: [
            // Северо-западный угол: тропа на Серые пруды.
            { tile: { x: 2, y: 2 }, target: { kind: 'area', area: 'ponds', entry: { x: 3, y: 3 } } },
            // Тропа в Звенец (деревня-мастерская).
            { tile: { x: 26, y: 14 }, target: { kind: 'area', area: 'zvenets', entry: { x: 3, y: 10 } } },
            // Встречный колодец: звон в Звенец (клик по тайлу колодца).
            {
                tile: { x: 22, y: 20 },
                label: 'Старый колодец',
                target: { kind: 'area', area: 'zvenets', entry: { x: 9, y: 7 } },
                trigger: 'click',
                duration: 0.2
            }
        ],
        atmosphere: 'ash',
        interactables: INTERACTABLES.meadows,
        // Глобальный ветер: порывы свистят выше базового амбиента лугов.
        ambienceLayers: [{ key: 'ambience/wind', volume: 0.3 }],
        // Безгласные олени у берегов прудов — подходят к звону.
        fauna: [
            { x: 9, y: 18 },
            { x: 12, y: 20 }
        ]
    },
    ponds: {
        id: 'ponds',
        name: 'Серые пруды',
        ambience: 'ambience/ponds',
        spawn: { x: 3, y: 3 },
        npcs: [],
        enemies: [
            { kind: 'crawler', tile: { x: 4, y: 11 } },
            { kind: 'crawler', tile: { x: 9, y: 18 } },
            { kind: 'spitter', tile: { x: 18, y: 10 } },
            { kind: 'spitter', tile: { x: 18, y: 18 } },
            { kind: 'heavy', tile: { x: 13, y: 17 } }
        ],
        transitions: [
            // Обратно на луга.
            { tile: { x: 2, y: 2 }, target: { kind: 'area', area: 'meadows', entry: { x: 3, y: 3 } } }
        ],
        atmosphere: 'fog',
        // Вода прудов слышна у берега — тихий плеск поверх ветрового амбиента.
        // Глобальный ветер + вода у берегов (громкость — от дистанции).
        ambienceLayers: [
            { key: 'ambience/wind', volume: 0.3 },
            { key: 'ambience/ponds_water', tiles: [TILES.WATER], radius: 5, volume: 0.35 }
        ],
        // Свежий накат — низины у берегов: без вощёного полотна здесь не дышать.
        hazards: [
            {
                name: 'Свежий накат',
                requiresItem: 'cloth',
                tiles: [
                    { x: 5, y: 16 },
                    { x: 6, y: 17 },
                    { x: 7, y: 17 },
                    { x: 8, y: 18 },
                    { x: 9, y: 18 },
                    { x: 10, y: 18 },
                    { x: 11, y: 19 },
                    { x: 12, y: 19 },
                    { x: 13, y: 18 },
                    { x: 14, y: 18 },
                    { x: 15, y: 17 },
                    { x: 4, y: 9 },
                    { x: 3, y: 8 },
                    { x: 15, y: 6 },
                    { x: 16, y: 4 }
                ]
            }
        ],
        interactables: INTERACTABLES.ponds,
        // Один олень на северо-западном берегу.
        fauna: [{ x: 4, y: 6 }]
    },
    zvenets: {
        id: 'zvenets',
        name: 'Звенец',
        ambience: 'ambience/zvenets',
        spawn: { x: 14, y: 10 },
        npcs: NPCS,
        enemies: [],
        transitions: [
            // Тропа обратно на луга.
            { tile: { x: 2, y: 10 }, target: { kind: 'area', area: 'meadows', entry: { x: 25, y: 14 } } },
            // Колодец у дома Ирвина: телепорт на луга (клик; встречный лугам).
            {
                tile: { x: 9, y: 6 },
                label: 'Старый колодец',
                target: { kind: 'area', area: 'meadows', entry: { x: 22, y: 21 } },
                trigger: 'click',
                duration: 0.2
            },
            // Двери: клик по дому — внутрь (вход у проёма; выход — kind 'return').
            {
                tile: { x: 7, y: 6 },
                label: 'Дом Ирвина',
                target: { kind: 'area', area: 'house_elder', entry: { x: 5, y: 7 } },
                trigger: 'click',
                duration: 0.2
            },
            {
                tile: { x: 21, y: 9 },
                label: 'Лавка Милы',
                target: { kind: 'area', area: 'shop', entry: { x: 5, y: 7 } },
                trigger: 'click',
                duration: 0.2
            }
        ],
        interactables: INTERACTABLES.zvenets,
        atmosphere: 'ash',
        // Гул колокола башни и скрипы вагонных щитов — слышны вблизи источников.
        ambienceLayers: [
            { key: 'ambience/tower_hum', at: { x: 14, y: 7 }, radius: 8, volume: 0.5 },
            { key: 'ambience/houses', tiles: [TILES.HOUSE], radius: 5, volume: 0.4 }
        ]
    },
    // --- интерьеры: рамка WALL, пол FLOOR, дверной проём снизу ---
    house_elder: {
        id: 'house_elder',
        name: 'Дом Ирвина',
        spawn: { x: 5, y: 7 },
        npcs: [],
        enemies: [],
        transitions: [
            // Проём в нижней стене: шаг наружу — назад, откуда вошёл.
            { tile: { x: 5, y: 8 }, target: { kind: 'return' }, duration: 0.2 }
        ],
        interactables: INTERACTABLES.house_elder,
        atmosphere: 'none'
    },
    shop: {
        id: 'shop',
        name: 'Лавка Милы',
        spawn: { x: 5, y: 7 },
        npcs: [],
        enemies: [],
        transitions: [{ tile: { x: 5, y: 8 }, target: { kind: 'return' }, duration: 0.2 }],
        interactables: INTERACTABLES.shop,
        atmosphere: 'none'
    }
};

/** Область по id (фолбэк 'meadows' — для старых сейвов и пустых id). */
export function areaOf(id: string | null | undefined): AreaDef {
    return AREAS[(id ?? 'meadows') as AreaId] ?? AREAS.meadows;
}