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 { FLAGS } from './ids';
import { INTERACTABLES, type InteractableDef } from './interactables';

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

/** Источник света: точка в тайлах или все тайлы заданных id; радиус в юнитах. */
export interface LightSourceDef {
    id: string;
    /** Центр источника в тайлах (центр ромба: +0.5); для at/tiles — одно из двух. */
    at?: { x: number; y: number };
    /** Альтернатива: свет на каждом тайле этого id (позиции из карты). */
    tiles?: number[];
    /** Радиус в юнитах (1 юнит = тайл; по умолчанию 3). */
    radius?: number;
    /** Цвет свечения (по умолчанию 0xf2b45a — тёплый F1). */
    color?: number;
    /** Яркость (по умолчанию 0.9). */
    intensity?: number;
    /** Амплитуда мерцания 0..1 (по умолчанию 0 — ровный). */
    flicker?: number;
    /** Источник активен только при наличии (whenFlag) / отсутствии (notFlag) флага. */
    whenFlag?: string;
    notFlag?: string;
    /** Ночной источник: горит при факторе ночи ≥ 0.5 (вечер/ночь по часам). */
    whenNight?: boolean;
}

/** Освещение области: ambient (multiply-цвет) + статические источники. */
export interface LightingDef {
    /** 0xffffff — не трогает сцену; тёмный/цветной — тон и затемнение сцены. */
    ambient?: number;
    /** Ночной ambient (когда стоит флаг вечера); нет — ночь не меняет тон. */
    nightAmbient?: number;
    /** Закатный тон (золотой час); нет — движковый DEFAULT_DUSK_COLOR. */
    duskColor?: number;
    sources?: LightSourceDef[];
}

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';
    /** Освещение: ambient-тон + статические источники (очаг, окна). */
    lighting?: LightingDef;
    /** Локальные амбиент-слои поверх областного (вода, гул башни, дома). */
    ambienceLayers?: AmbienceLayerDef[];
    /** Зоны наката (необязательно). */
    hazards?: HazardDef[];
    /** Сборный тайл (лунный колокольчик): клик по нему — сбор. Нет — в области не собирается. */
    harvestTile?: number;
    /** Спавны пейзажных оленей (тайлы). */
    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',
        // Солнечный выжженный день: тёплый почти-белый. Вечером — золотой час
        // и синяя ночь: прорези колокольчиков несут свет.
        lighting: {
            ambient: 0xf7f4ea,
            nightAmbient: 0x3e4658,
            sources: [
                {
                    id: 'bells',
                    tiles: [TILES.BELLFLOWER],
                    color: 0xf2cd68,
                    radius: 1.0,
                    intensity: 0.65,
                    flicker: 0.15,
                    whenNight: true
                }
            ]
        },
        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',
        // Светлый день у прудов (туман даёт молочность сам); ночью — глухая
        // синева, туман читается прорезями.
        lighting: { ambient: 0xf2f0e8, nightAmbient: 0x444c60 },
        // Вода прудов слышна у берега — тихий плеск поверх ветрового амбиента.
        // Глобальный ветер + вода у берегов (громкость — от дистанции).
        ambienceLayers: [
            { key: 'ambience/wind', volume: 0.3 },
            // Вода — только вплотную к берегу и совсем тихо (у нас лужи, не море).
            { key: 'ambience/ponds_water', tiles: [TILES.WATER], radius: 2.5, volume: 0.22 }
        ],
        // Свежий накат — низины у берегов: без вощёного полотна здесь не дышать.
        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,
        // Лунные колокольчики собираются только у прудов (квест «Три цветка»).
        harvestTile: TILES.BELLFLOWER,
        // Один олень на северо-западном берегу.
        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
            },
            // Восточный край: тропа в Ржавую рощу (акт 2).
            { tile: { x: 26, y: 10 }, target: { kind: 'area', area: 'rust_grove', entry: { x: 2, y: 10 } } }
        ],
        interactables: INTERACTABLES.zvenets,
        atmosphere: 'ash',
        // Светлый тёплый день деревни; вечером — золотой час, синяя ночь и
        // тёплые окна трёх домов; после звонка — холодный отсвет от башни.
        lighting: {
            ambient: 0xf5f2ea,
            nightAmbient: 0x454c62,
            sources: [
                // Окна — на теле спрайта дома (тело занимает тайл выше-левее базового);
                // днём не горят, зажигаются вечером.
                { id: 'window_elder', at: { x: 6.5, y: 5.5 }, radius: 1.2, intensity: 0.65, flicker: 0.1, whenNight: true },
                { id: 'window_north', at: { x: 17.5, y: 4.5 }, radius: 1.2, intensity: 0.65, flicker: 0.1, whenNight: true },
                { id: 'window_shop', at: { x: 20.5, y: 8.5 }, radius: 1.2, intensity: 0.65, flicker: 0.1, whenNight: true },
                {
                    id: 'tower_resonance',
                    at: { x: 14, y: 7 },
                    color: 0x4a737f,
                    radius: 2.5,
                    intensity: 0.6,
                    flicker: 0.25,
                    whenFlag: FLAGS.rang_tower
                }
            ]
        },
        // Гул колокола башни и скрипы вагонных щитов — слышны вблизи источников.
        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 }
        ]
    },
    // --- акт 2: роща, разъезд, подземелье ---
    rust_grove: {
        id: 'rust_grove',
        name: 'Ржавая роща',
        ambience: 'ambience/ponds',
        spawn: { x: 2, y: 10 },
        npcs: [],
        enemies: [
            { kind: 'crawler', tile: { x: 6, y: 6 } },
            { kind: 'crawler', tile: { x: 17, y: 7 } },
            {
                kind: 'spitter',
                tile: { x: 18, y: 16 },
                patrol: { points: [{ x: 18, y: 16 }, { x: 20, y: 14 }], pauseSec: 1.4 }
            },
            { kind: 'heavy', tile: { x: 7, y: 15 } }
        ],
        transitions: [
            // Тропа обратно в Звенец.
            { tile: { x: 1, y: 10 }, target: { kind: 'area', area: 'zvenets', entry: { x: 25, y: 10 } } },
            // Тропа на восток: к Старому разъезду.
            { tile: { x: 22, y: 10 }, target: { kind: 'area', area: 'old_siding', entry: { x: 2, y: 10 } } }
        ],
        atmosphere: 'ash',
        interactables: INTERACTABLES.rust_grove,
        // Роща чуть темнее лугов: мёртвый лес глушит свет; ночью — глухая синева.
        lighting: { ambient: 0xe9e6da, nightAmbient: 0x39405a },
        // Ветер в проводах: гул башни не слышен, только кабельный звон.
        ambienceLayers: [{ key: 'ambience/wind', volume: 0.4 }]
    },
    old_siding: {
        id: 'old_siding',
        name: 'Старый разъезд',
        ambience: 'ambience/ponds',
        spawn: { x: 2, y: 10 },
        npcs: [],
        enemies: [
            { kind: 'crawler', tile: { x: 7, y: 9 } },
            {
                kind: 'spitter',
                tile: { x: 18, y: 8 },
                patrol: { points: [{ x: 18, y: 8 }, { x: 19, y: 6 }], pauseSec: 1.2 }
            },
            {
                kind: 'heavy',
                tile: { x: 18, y: 16 },
                patrol: { points: [{ x: 18, y: 16 }, { x: 15, y: 17 }], pauseSec: 2 }
            }
        ],
        transitions: [
            // Тропа обратно в рощу.
            { tile: { x: 1, y: 10 }, target: { kind: 'area', area: 'rust_grove', entry: { x: 21, y: 10 } } },
            // Люк-ступени вниз, в зал Старой Машины (наступил — спустился).
            {
                tile: { x: 15, y: 15 },
                label: 'Люк в подземелье',
                target: { kind: 'area', area: 'machine_hall', entry: { x: 6, y: 9 } },
                duration: 0.6
            }
        ],
        atmosphere: 'ash',
        // Разъезд темнее рощи: рельсы тянут свет в землю; ночью — глубокая тьма.
        lighting: { ambient: 0xe4e2d8, nightAmbient: 0x343a50 },
        // Гул снизу: Машина дышит у люка (та же нота, что башня Звенца).
        ambienceLayers: [
            { key: 'ambience/wind', volume: 0.25 },
            { key: 'ambience/tower_hum', at: { x: 15, y: 15 }, radius: 7, volume: 0.45 }
        ],
        // Свежий накат наметало у рельсов: без полотна рядом с люком не дышать.
        hazards: [
            {
                name: 'Накат у рельсов',
                requiresItem: 'cloth',
                tiles: [
                    { x: 13, y: 15 },
                    { x: 14, y: 15 },
                    { x: 16, y: 15 },
                    { x: 15, y: 14 },
                    { x: 16, y: 16 },
                    { x: 17, y: 15 }
                ]
            }
        ]
    },
    machine_hall: {
        id: 'machine_hall',
        name: 'Зал Старой Машины',
        spawn: { x: 6, y: 9 },
        npcs: [],
        enemies: [],
        transitions: [
            // Проём в нижней стене: шаг — назад наверх, к люку.
            { tile: { x: 6, y: 10 }, target: { kind: 'return' }, duration: 0.2 }
        ],
        atmosphere: 'none',
        interactables: INTERACTABLES.machine_hall,
        // Под землёй темно; единственный свет — холодное тление устья печи.
        lighting: {
            ambient: 0x3e4252,
            sources: [
                {
                    id: 'machine_mouth',
                    at: { x: 5.5, y: 1.5 },
                    color: 0x4a737f,
                    radius: 3.5,
                    intensity: 0.55,
                    flicker: 0.3
                }
            ]
        },
        // Гул здесь — везде: это её грудная клетка.
        ambienceLayers: [{ key: 'ambience/tower_hum', volume: 0.6 }]
    },
    // --- интерьеры: рамка 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',
        // Тёмный холодный интерьер (без света окна выглядят как улица);
        // очаг: тлеет, пока квест не закрыт, после — горит ровнее и ярче.
        lighting: {
            ambient: 0x54586a,
            sources: [
                {
                    id: 'hearth_low',
                    at: { x: 8.5, y: 0.5 },
                    radius: 4,
                    intensity: 0.75,
                    flicker: 0.35,
                    notFlag: FLAGS.quest_bells_done
                },
                {
                    id: 'hearth_high',
                    at: { x: 8.5, y: 0.5 },
                    radius: 5,
                    intensity: 1.05,
                    flicker: 0.2,
                    whenFlag: FLAGS.quest_bells_done
                }
            ]
        }
    },
    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',
        // Полутёмная лавка: лампа над прилавком.
        lighting: {
            ambient: 0x5a5e70,
            sources: [{ id: 'counter_lamp', at: { x: 5.5, y: 3.5 }, radius: 3, intensity: 0.7, flicker: 0.05 }]
        }
    }
};

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