/**
 * decoFactories — реестр декораций ландшафта GD (v2 — на готовых GLB Kenney).
 *
 * Используем nature-kit (Kenney CC0) — те же модели что в гладком ландшафте
 * (см. SmoothDecoManager). Все .glb лежат в /public/kubikon-assets/models/nature-kit/.
 *
 * Структура каталога:
 *   10 эпох × 10 моделей = 100. Для эпох без природы (Кибер) — пустой массив,
 *   юзер просто не выбирает ничего и декораций на тех уровнях не будет.
 *
 * Каждая фабрика возвращает (scene, id) => { root: TransformNode, dispose() }.
 * Под капотом: SceneLoader.LoadAssetContainerAsync(...) — кэшируется по file-name.
 */
import {
    SceneLoader, TransformNode, Vector3,
} from '@babylonjs/core';
import '@babylonjs/loaders/glTF';

const ASSET_ROOT = '/kubikon-assets/models/nature-kit/';

// Кэш загруженных AssetContainer'ов (по file → container).
// Когда юзер открывает превью одного и того же id повторно — не грузим заново.
const _containerCache = new Map();   // file → Promise<container>

/** Универсальная загрузка GLB с кэшем. Возвращает массив instantiated meshes. */
async function loadGlb(file, scene) {
    let promise = _containerCache.get(file);
    if (!promise) {
        promise = SceneLoader.LoadAssetContainerAsync(ASSET_ROOT, file, scene);
        _containerCache.set(file, promise);
    }
    const container = await promise;
    // instantiateModelsToScene создаёт независимые копии — можно ставить в любую сцену
    return container.instantiateModelsToScene();
}

/** Фабрика — обёртка над loadGlb. Возвращает root + dispose, scale настраиваемый. */
function makeGlb(file, opts = {}) {
    const { scale = 1.0, rotY = 0 } = opts;
    return (scene, id) => {
        const root = new TransformNode(`deco_${id}`, scene);
        // Параллельно начинаем загружать GLB и сразу возвращаем root. Когда модель
        // загрузится — паррентим её к root. Это позволяет рендерить root сразу.
        loadGlb(file, scene).then((result) => {
            try {
                if (root.isDisposed && root.isDisposed()) {
                    // root уже удалён — disposить инстанцию
                    for (const m of result.rootNodes) m.dispose();
                    return;
                }
                for (const rn of result.rootNodes) {
                    rn.parent = root;
                }
                root.scaling = new Vector3(scale, scale, scale);
                root.rotation.y = rotY;
            } catch (e) { console.warn('[deco] mount failed', file, e); }
            // Сохраним handle для dispose
            root._glbResult = result;
        }).catch((e) => {
            console.warn('[deco] load failed', file, e);
        });
        return {
            root,
            dispose: () => {
                try {
                    if (root._glbResult) {
                        for (const m of root._glbResult.rootNodes) {
                            try { m.dispose(false, true); } catch (e) {}
                        }
                    }
                    root.dispose();
                } catch (e) {}
            },
        };
    };
}

// =========================================================================
// КАТАЛОГ
// =========================================================================

export const DECO_CATALOG = [];

function add(epoch, num, title, file, scale = 1.0) {
    DECO_CATALOG.push({
        id: `d${epoch}_v${num}`,
        epoch,
        title,
        file,
        scale,                                  // <-- доступно для GdForest
        make: makeGlb(file, { scale }),
    });
}

// ---------- Эпоха I — Лес (10) ----------
// Scale тут — итоговый множитель ВНУТРИ GdForest (умножается на 0.85-1.20).
// Kenney модели после bake — обычно 0.2-1.5м, надо ×10-25 чтобы получить
// деревья 3-6м (вдвое выше игрока для заметного бэкграунда).
add(1,  1, 'Дуб',              'tree_oak.glb', 12);
add(1,  2, 'Большое дерево',   'tree_default.glb', 10);
add(1,  3, 'Толстое дерево',   'tree_fat.glb', 10);
add(1,  4, 'Высокое дерево',   'tree_tall.glb', 14);
add(1,  5, 'Малое дерево',     'tree_small.glb', 8);
add(1,  6, 'Детальное дерево', 'tree_detailed.glb', 11);
add(1,  7, 'Куст',             'grass_leafsLarge.glb', 6);
add(1,  8, 'Гриб красный',     'mushroom_redGroup.glb', 5);
add(1,  9, 'Гриб тан',         'mushroom_tanGroup.glb', 5);
add(1, 10, 'Большой камень',   'stone_largeA.glb', 8);

// ---------- Эпоха II — Горы (10) ----------
add(2,  1, 'Сосна высокая',    'tree_pineTallA.glb', 16);
add(2,  2, 'Сосна круглая A',  'tree_pineRoundA.glb', 11);
add(2,  3, 'Сосна круглая B',  'tree_pineRoundB.glb', 11);
add(2,  4, 'Сосна малая',      'tree_pineSmallA.glb', 7);
add(2,  5, 'Сосна по умолч.',  'tree_pineDefaultA.glb', 13);
add(2,  6, 'Камень большой A', 'stone_largeA.glb', 9);
add(2,  7, 'Камень большой B', 'stone_largeB.glb', 9);
add(2,  8, 'Камень высокий A', 'stone_tallA.glb', 10);
add(2,  9, 'Камень высокий B', 'stone_tallB.glb', 10);
add(2, 10, 'Камень малый',     'stone_smallTopA.glb', 5);

// ---------- Эпоха III — Город (10) ----------
add(3,  1, 'Дерево парка',     'tree_default.glb', 10);
add(3,  2, 'Дерево парка 2',   'tree_oak.glb', 10);
add(3,  3, 'Куст-кустарник',   'grass_leafsLarge.glb', 6);
add(3,  4, 'Тумба-камень A',   'stone_smallA.glb', 5);
add(3,  5, 'Тумба-камень B',   'stone_smallB.glb', 5);
add(3,  6, 'Тумба-камень C',   'stone_smallC.glb', 5);
add(3,  7, 'Цветок жёлтый',    'flower_yellowB.glb', 10);
add(3,  8, 'Цветок красный',   'flower_redB.glb', 10);
add(3,  9, 'Цветок фиолет',    'flower_purpleB.glb', 10);
add(3, 10, 'Куст-трава',       'grass_large.glb', 5);

// ---------- Эпоха IV — Город ночью (10) ----------
add(4,  1, 'Тёмное дерево',    'tree_default_dark.glb', 10);
add(4,  2, 'Тёмный дуб',       'tree_oak_dark.glb', 11);
add(4,  3, 'Тёмное толстое',   'tree_fat_darkh.glb', 10);
add(4,  4, 'Тёмное детальное', 'tree_detailed_dark.glb', 11);
add(4,  5, 'Тёмная сосна',     'tree_cone_dark.glb', 11);
add(4,  6, 'Камень малый A',   'stone_smallA.glb', 5);
add(4,  7, 'Камень малый D',   'stone_smallD.glb', 5);
add(4,  8, 'Камень малый E',   'stone_smallE.glb', 5);
add(4,  9, 'Камень flat A',    'stone_smallFlatA.glb', 5);
add(4, 10, 'Камень flat B',    'stone_smallFlatB.glb', 5);

// ---------- Эпоха V — Пустыня (10) ----------
add(5,  1, 'Кактус высокий',   'cactus_tall.glb', 9);
add(5,  2, 'Кактус малый',     'cactus_short.glb', 7);
add(5,  3, 'Пальма',           'tree_palm.glb', 12);
add(5,  4, 'Пальма короткая',  'tree_palmShort.glb', 9);
add(5,  5, 'Пальма гнутая',    'tree_palmBend.glb', 12);
add(5,  6, 'Камень-валун A',   'stone_largeC.glb', 9);
add(5,  7, 'Камень-валун D',   'stone_largeD.glb', 9);
add(5,  8, 'Камень-валун E',   'stone_largeE.glb', 9);
add(5,  9, 'Цветок жёлтый',    'flower_yellowC.glb', 10);
add(5, 10, 'Камень малый F',   'stone_smallF.glb', 5);

// ---------- Эпоха VI — Океан (10) ----------
add(6,  1, 'Камень морской A', 'stone_largeA.glb', 7);
add(6,  2, 'Камень морской B', 'stone_largeB.glb', 7);
add(6,  3, 'Камень морской C', 'stone_largeC.glb', 7);
add(6,  4, 'Камень флэт A',    'stone_smallFlatA.glb', 5);
add(6,  5, 'Гриб (коралл) A',  'mushroom_red.glb', 5);
add(6,  6, 'Гриб (коралл) B',  'mushroom_redTall.glb', 5);
add(6,  7, 'Гриб (коралл) C',  'mushroom_redGroup.glb', 5);
add(6,  8, 'Гриб тан',         'mushroom_tan.glb', 5);
add(6,  9, 'Цветок (анемона)', 'flower_redC.glb', 10);
add(6, 10, 'Трава (водорсль)', 'grass_leafs.glb', 8);

// ---------- Эпоха VII — Пещеры (10) ----------
add(7,  1, 'Камень высокий A', 'stone_tallA.glb', 10);
add(7,  2, 'Камень высокий B', 'stone_tallB.glb', 10);
add(7,  3, 'Камень высокий C', 'stone_tallC.glb', 10);
add(7,  4, 'Камень высокий D', 'stone_tallD.glb', 10);
add(7,  5, 'Камень высокий E', 'stone_tallE.glb', 10);
add(7,  6, 'Гриб красный',     'mushroom_red.glb', 5);
add(7,  7, 'Гриб красный t.',  'mushroom_redTall.glb', 5);
add(7,  8, 'Гриб тан',         'mushroom_tan.glb', 5);
add(7,  9, 'Гриб тан t.',      'mushroom_tanTall.glb', 5);
add(7, 10, 'Гриб тан группа',  'mushroom_tanGroup.glb', 5);

// ---------- Эпоха VIII — Вулкан (10) ----------
add(8,  1, 'Тёмная сосна',     'tree_cone_dark.glb', 11);
add(8,  2, 'Сухое дерево',     'tree_default_fall.glb', 10);
add(8,  3, 'Сухой дуб',        'tree_oak_fall.glb', 11);
add(8,  4, 'Сухой толстый',    'tree_fat_fall.glb', 10);
add(8,  5, 'Сухой детальный',  'tree_detailed_fall.glb', 11);
add(8,  6, 'Камень тёмный A',  'stone_smallA.glb', 5);
add(8,  7, 'Камень тёмный D',  'stone_smallD.glb', 5);
add(8,  8, 'Камень тёмный E',  'stone_smallE.glb', 5);
add(8,  9, 'Валун',            'stone_largeF.glb', 8);
add(8, 10, 'Камень flat C',    'stone_smallFlatC.glb', 5);

// ---------- Эпоха IX — Космос (5, без природы) ----------
add(9,  1, 'Астероид большой A','stone_largeA.glb', 6);
add(9,  2, 'Астероид большой B','stone_largeB.glb', 6);
add(9,  3, 'Астероид высокий', 'stone_tallG.glb', 7);
add(9,  4, 'Метеорит',         'stone_smallTopB.glb', 5);
add(9,  5, 'Лунный камень',    'stone_smallH.glb', 5);

// ---------- Эпоха X — Кибер (без природы) ----------
// Юзер сказал — деревья тут не нужны. Каталог пустой.

export const EPOCH_INFO = [
    { n: 1,  name: 'Лес',           emoji: '🌲', color: '#3a7a4a' },
    { n: 2,  name: 'Горы',          emoji: '🏔', color: '#aaccff' },
    { n: 3,  name: 'Город днём',    emoji: '🏙', color: '#7a8aaa' },
    { n: 4,  name: 'Город ночью',   emoji: '🌃', color: '#1a1a3a' },
    { n: 5,  name: 'Пустыня',       emoji: '🏜', color: '#c8a575' },
    { n: 6,  name: 'Океан',         emoji: '🌊', color: '#3a8aaa' },
    { n: 7,  name: 'Пещеры',        emoji: '🕳', color: '#3a3a3a' },
    { n: 8,  name: 'Вулкан',        emoji: '🌋', color: '#8a2a2a' },
    { n: 9,  name: 'Космос',        emoji: '🚀', color: '#3a1a5a' },
    { n: 10, name: 'Кибер',         emoji: '🤖', color: '#ff00ff' },
];

export function getDecoByEpoch(epoch) {
    return DECO_CATALOG.filter(d => d.epoch === epoch);
}
