/**
 * finishFactories — реестр финишных ворот GD по эпохам.
 *
 * 10 эпох × 5 вариантов = 50 ворот. Каждая фабрика строит:
 *   - две высокие колонны (4м).
 *   - шахматный флаг между колоннами (DynamicTexture).
 *   - надпись «ФИНИШ».
 *   - подсветка стилистики эпохи (золото / неон / лава / лёд / ...).
 *
 * Возвращает (scene, id) => { root: TransformNode, dispose() }.
 * Габариты: ширина ~3.5м, высота ~4.5м, центр в (0, 0, 0).
 */
import {
    MeshBuilder, StandardMaterial, Color3, Vector3, TransformNode,
    DynamicTexture,
} from '@babylonjs/core';

function makeMat(scene, name, opts = {}) {
    const m = new StandardMaterial(name, scene);
    m.diffuseColor = new Color3(...(opts.diffuse || [1, 1, 1]));
    m.emissiveColor = new Color3(...(opts.emissive || [0, 0, 0]));
    m.specularColor = new Color3(...(opts.specular || [0.2, 0.2, 0.2]));
    if (opts.specPower != null) m.specularPower = opts.specPower;
    if (opts.alpha != null) m.alpha = opts.alpha;
    if (opts.disableLighting) m.disableLighting = true;
    return m;
}

function makeColumn(scene, name, opts = {}) {
    const {
        height = 4, diameter = 0.55,
        shape = 'cylinder',
        diffuse = [0.4, 0.3, 0.2], emissive = [0.05, 0.04, 0.03],
        specular, specPower,
    } = opts;
    let mesh;
    if (shape === 'box') {
        mesh = MeshBuilder.CreateBox(name, { width: diameter, height, depth: diameter }, scene);
    } else {
        mesh = MeshBuilder.CreateCylinder(name, { diameter, height, tessellation: 12 }, scene);
    }
    mesh.position.y = height / 2;
    mesh.material = makeMat(scene, `${name}_mat`, { diffuse, emissive, specular, specPower });
    return mesh;
}

function makeBeam(scene, name, opts = {}) {
    const {
        width = 3.5, height = 0.5, depth = 0.5,
        diffuse = [0.4, 0.3, 0.2], emissive = [0.05, 0.04, 0.03],
        specular, specPower,
    } = opts;
    const beam = MeshBuilder.CreateBox(name, { width, height, depth }, scene);
    beam.material = makeMat(scene, `${name}_mat`, { diffuse, emissive, specular, specPower });
    return beam;
}

/** Шахматный флаг — DynamicTexture с квадратиками. */
function makeChecker(scene, name, opts = {}) {
    const {
        width = 2.6, height = 1.6,
        cols = 8, rows = 5,
        c1 = '#ffffff', c2 = '#0a0a14',
    } = opts;
    const TW = 256, TH = 160;
    const dt = new DynamicTexture(`${name}_tex`, { width: TW, height: TH }, scene, true);
    const ctx = dt.getContext();
    const cw = TW / cols, ch = TH / rows;
    for (let r = 0; r < rows; r++) {
        for (let c = 0; c < cols; c++) {
            ctx.fillStyle = ((r + c) % 2 === 0) ? c1 : c2;
            ctx.fillRect(c * cw, r * ch, cw, ch);
        }
    }
    dt.hasAlpha = false;
    dt.update();

    const plane = MeshBuilder.CreatePlane(name, { width, height }, scene);
    const mat = new StandardMaterial(`${name}_mat`, scene);
    mat.diffuseTexture = dt;
    mat.emissiveTexture = dt;
    mat.emissiveColor = new Color3(0.5, 0.5, 0.5);
    mat.backFaceCulling = false;
    plane.material = mat;
    return plane;
}

function makeSignText(scene, name, text, opts = {}) {
    const {
        width = 2.6, height = 0.7,
        bgColor = '#0a1428', textColor = '#ffe44a',
        fontSize = 96, fontFamily = 'sans-serif',
        emissive = [0.8, 0.7, 0.2],
    } = opts;
    const TW = 512, TH = 128;
    const dt = new DynamicTexture(`${name}_tex`, { width: TW, height: TH }, scene, true);
    const ctx = dt.getContext();
    ctx.fillStyle = bgColor;
    ctx.fillRect(0, 0, TW, TH);
    ctx.fillStyle = textColor;
    ctx.font = `bold ${fontSize}px ${fontFamily}`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(text, TW / 2, TH / 2);
    dt.update();
    const plane = MeshBuilder.CreatePlane(name, { width, height }, scene);
    const mat = new StandardMaterial(`${name}_mat`, scene);
    mat.diffuseTexture = dt;
    mat.emissiveTexture = dt;
    mat.emissiveColor = new Color3(...emissive);
    mat.disableLighting = true;
    mat.backFaceCulling = false;
    plane.material = mat;
    return plane;
}

function makeBulb(scene, name, x, y, z, color, scale = 1) {
    const bulb = MeshBuilder.CreateSphere(name, { diameter: 0.18, segments: 8 }, scene);
    bulb.position.set(x, y, z);
    bulb.scaling.set(scale, scale, scale);
    bulb.material = makeMat(scene, `${name}_mat`, { diffuse: color, emissive: color, disableLighting: true });
    return bulb;
}

// =========================================================================
// ДЕТАЛЬНЫЕ ФАБРИКИ — ЭПОХА I (Лес) и II (Горы)
// =========================================================================

// ----- Эпоха I — Лес -----
function finishForestWoodFlag(scene, id) {
    const root = new TransformNode(`fin_${id}`, scene);
    const COL_H = 4.2, GAP = 3.0;
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.55,
        diffuse: [0.40, 0.25, 0.13], emissive: [0.10, 0.07, 0.04] });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.55,
        diffuse: [0.40, 0.25, 0.13], emissive: [0.10, 0.07, 0.04] });
    colL.position.x = -GAP / 2; colR.position.x = GAP / 2;
    colL.parent = root; colR.parent = root;
    const beam = makeBeam(scene, `${id}_beam`, {
        width: GAP + 0.7, height: 0.45, depth: 0.45,
        diffuse: [0.45, 0.28, 0.15], emissive: [0.10, 0.07, 0.04],
    });
    beam.position.y = COL_H + 0.225;
    beam.parent = root;
    const flag = makeChecker(scene, `${id}_flag`, { width: GAP - 0.2, height: 1.8 });
    flag.position.y = COL_H - 1.4;
    flag.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'ФИНИШ', { textColor: '#ffe44a' });
    sign.position.set(0, COL_H + 0.55, 0.26);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

function finishForestGold(scene, id) {
    const root = new TransformNode(`fin_${id}`, scene);
    const COL_H = 4.0, GAP = 3.0;
    const gold = [0.85, 0.65, 0.10];
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.5,
        diffuse: gold, emissive: [0.30, 0.20, 0.05], specPower: 96 });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.5,
        diffuse: gold, emissive: [0.30, 0.20, 0.05], specPower: 96 });
    colL.position.x = -GAP / 2; colR.position.x = GAP / 2;
    colL.parent = root; colR.parent = root;
    const beam = makeBeam(scene, `${id}_beam`, {
        width: GAP + 0.7, height: 0.4, depth: 0.4,
        diffuse: gold, emissive: [0.30, 0.20, 0.05],
    });
    beam.position.y = COL_H + 0.2;
    beam.parent = root;
    const flag = makeChecker(scene, `${id}_flag`, { width: GAP - 0.2, height: 1.6,
        c1: '#ffe44a', c2: '#3a2a1a' });
    flag.position.y = COL_H - 1.2;
    flag.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'ФИНИШ', { textColor: '#ffffff', bgColor: '#2a1a0a' });
    sign.position.set(0, COL_H + 0.55, 0.21);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

function finishForestLeafy(scene, id) {
    const root = new TransformNode(`fin_${id}`, scene);
    const COL_H = 4.2, GAP = 3.0;
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.55,
        diffuse: [0.35, 0.22, 0.12], emissive: [0.08, 0.05, 0.03] });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.55,
        diffuse: [0.35, 0.22, 0.12], emissive: [0.08, 0.05, 0.03] });
    colL.position.x = -GAP / 2; colR.position.x = GAP / 2;
    colL.parent = root; colR.parent = root;
    const beam = makeBeam(scene, `${id}_beam`, { width: GAP + 0.5, height: 0.35, depth: 0.35,
        diffuse: [0.35, 0.22, 0.12], emissive: [0.08, 0.05, 0.03] });
    beam.position.y = COL_H + 0.175;
    beam.parent = root;
    // Листва (зелёные шарики) поверх балки
    for (let i = 0; i < 8; i++) {
        const leaf = MeshBuilder.CreateSphere(`${id}_leaf_${i}`, { diameter: 0.6 }, scene);
        leaf.position.set(-1.6 + i * 0.45, COL_H + 0.55, (i % 2) * 0.15 - 0.075);
        leaf.material = makeMat(scene, `${id}_lm_${i}`,
            { diffuse: [0.2, 0.55 + (i % 2) * 0.1, 0.25], emissive: [0.06, 0.18, 0.08] });
        leaf.parent = root;
    }
    const flag = makeChecker(scene, `${id}_flag`, { width: GAP - 0.2, height: 1.6 });
    flag.position.y = COL_H - 1.2;
    flag.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'ФИНИШ', { textColor: '#aaff66' });
    sign.position.set(0, COL_H - 0.3, 0.26);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

function finishForestRustic(scene, id) {
    const root = new TransformNode(`fin_${id}`, scene);
    const COL_H = 4.0, GAP = 2.8;
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.6, shape: 'box',
        diffuse: [0.42, 0.28, 0.16], emissive: [0.10, 0.07, 0.04] });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.6, shape: 'box',
        diffuse: [0.42, 0.28, 0.16], emissive: [0.10, 0.07, 0.04] });
    colL.position.x = -GAP / 2; colL.rotation.z = -0.05;
    colR.position.x = GAP / 2; colR.rotation.z = 0.05;
    colL.parent = root; colR.parent = root;
    const beam1 = makeBeam(scene, `${id}_beam1`, { width: GAP + 0.5, height: 0.35, depth: 0.35,
        diffuse: [0.45, 0.30, 0.18], emissive: [0.10, 0.07, 0.04] });
    beam1.position.y = COL_H + 0.175;
    beam1.parent = root;
    const beam2 = makeBeam(scene, `${id}_beam2`, { width: GAP, height: 0.25, depth: 0.25,
        diffuse: [0.45, 0.30, 0.18], emissive: [0.10, 0.07, 0.04] });
    beam2.position.y = COL_H - 0.5;
    beam2.parent = root;
    const flag = makeChecker(scene, `${id}_flag`, { width: GAP - 0.4, height: 1.3 });
    flag.position.y = COL_H * 0.55;
    flag.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'ФИНИШ', { textColor: '#ffe44a' });
    sign.position.set(0, COL_H + 0.55, 0.21);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

function finishForestLanterns(scene, id) {
    const root = new TransformNode(`fin_${id}`, scene);
    const COL_H = 4.2, GAP = 3.0;
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.5,
        diffuse: [0.30, 0.18, 0.08], emissive: [0.06, 0.04, 0.02] });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.5,
        diffuse: [0.30, 0.18, 0.08], emissive: [0.06, 0.04, 0.02] });
    colL.position.x = -GAP / 2; colR.position.x = GAP / 2;
    colL.parent = root; colR.parent = root;
    const beam = makeBeam(scene, `${id}_beam`, { width: GAP + 0.5, height: 0.3, depth: 0.3,
        diffuse: [0.30, 0.18, 0.08], emissive: [0.06, 0.04, 0.02] });
    beam.position.y = COL_H + 0.15;
    beam.parent = root;
    // тёплые лампочки
    const colors = [[1.0, 0.85, 0.30], [1.0, 0.55, 0.20], [1.0, 0.95, 0.65]];
    for (let i = 0; i < 9; i++) {
        const bulb = makeBulb(scene, `${id}_b_${i}`,
            -1.6 + i * 0.4,
            COL_H + 0.15 - Math.abs(Math.sin(i * 1.7)) * 0.3,
            0, colors[i % colors.length], 0.9);
        bulb.parent = root;
    }
    const flag = makeChecker(scene, `${id}_flag`, { width: GAP - 0.2, height: 1.6 });
    flag.position.y = COL_H - 1.2;
    flag.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'ФИНИШ', {
        textColor: '#ffd76b', bgColor: '#1f1408', emissive: [0.7, 0.55, 0.15],
    });
    sign.position.set(0, COL_H - 0.4, 0.26);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

// ----- Эпоха II — Горы -----
function finishMountainStone(scene, id) {
    const root = new TransformNode(`fin_${id}`, scene);
    const COL_H = 4.0, GAP = 3.0;
    const dif = [0.50, 0.50, 0.55];
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.7, shape: 'box', diffuse: dif, emissive: [0.10, 0.10, 0.11] });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.7, shape: 'box', diffuse: dif, emissive: [0.10, 0.10, 0.11] });
    colL.position.x = -GAP / 2; colR.position.x = GAP / 2;
    colL.parent = root; colR.parent = root;
    const beam = makeBeam(scene, `${id}_beam`, { width: GAP + 1, height: 0.55, depth: 0.55, diffuse: dif, emissive: [0.10, 0.10, 0.11] });
    beam.position.y = COL_H + 0.275;
    beam.parent = root;
    const flag = makeChecker(scene, `${id}_flag`, { width: GAP - 0.2, height: 1.6, c1: '#cccccc', c2: '#1a1a20' });
    flag.position.y = COL_H - 1.2;
    flag.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'ФИНИШ', { textColor: '#aaccff' });
    sign.position.set(0, COL_H + 0.55, 0.31);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

function finishMountainCrystal(scene, id) {
    const root = new TransformNode(`fin_${id}`, scene);
    const COL_H = 4.2, GAP = 3.0;
    const dif = [0.5, 0.7, 0.95], em = [0.20, 0.35, 0.55];
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.55, diffuse: dif, emissive: em, specPower: 96 });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.55, diffuse: dif, emissive: em, specPower: 96 });
    colL.position.x = -GAP / 2; colR.position.x = GAP / 2;
    colL.parent = root; colR.parent = root;
    const beam = makeBeam(scene, `${id}_beam`, { width: GAP + 0.6, height: 0.35, depth: 0.35, diffuse: dif, emissive: em });
    beam.position.y = COL_H + 0.175; beam.parent = root;
    const flag = makeChecker(scene, `${id}_flag`, { width: GAP - 0.2, height: 1.6, c1: '#ddeeff', c2: '#1a2a4a' });
    flag.position.y = COL_H - 1.2; flag.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'ФИНИШ', { textColor: '#aaeeff' });
    sign.position.set(0, COL_H - 0.3, 0.21);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

function finishMountainIce(scene, id) {
    const root = new TransformNode(`fin_${id}`, scene);
    const COL_H = 4.0, GAP = 3.0;
    const dif = [0.80, 0.92, 1.0], em = [0.25, 0.35, 0.50];
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.55, diffuse: dif, emissive: em, specPower: 128 });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.55, diffuse: dif, emissive: em, specPower: 128 });
    colL.position.x = -GAP / 2; colR.position.x = GAP / 2;
    colL.parent = root; colR.parent = root;
    const beam = makeBeam(scene, `${id}_beam`, { width: GAP + 0.6, height: 0.35, depth: 0.35, diffuse: dif, emissive: em });
    beam.position.y = COL_H + 0.175; beam.parent = root;
    const flag = makeChecker(scene, `${id}_flag`, { width: GAP - 0.2, height: 1.6, c1: '#ffffff', c2: '#4488aa' });
    flag.position.y = COL_H - 1.2; flag.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'ФИНИШ', { textColor: '#ddffff' });
    sign.position.set(0, COL_H - 0.3, 0.21);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

function finishMountainPeak(scene, id) {
    const root = new TransformNode(`fin_${id}`, scene);
    const COL_H = 4.4, GAP = 3.0;
    const dif = [0.40, 0.45, 0.50];
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.6, shape: 'box', diffuse: dif, emissive: [0.05, 0.06, 0.07] });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.6, shape: 'box', diffuse: dif, emissive: [0.05, 0.06, 0.07] });
    colL.position.x = -GAP / 2; colR.position.x = GAP / 2;
    colL.parent = root; colR.parent = root;
    const sideA = makeBeam(scene, `${id}_a`, { width: GAP * 0.7, height: 0.4, depth: 0.4, diffuse: dif, emissive: [0.05, 0.06, 0.07] });
    sideA.position.set(-GAP * 0.27, COL_H + GAP * 0.27, 0);
    sideA.rotation.z = -Math.PI / 4;
    sideA.parent = root;
    const sideB = sideA.clone(`${id}_b`);
    sideB.position.set(GAP * 0.27, COL_H + GAP * 0.27, 0);
    sideB.rotation.z = Math.PI / 4;
    sideB.parent = root;
    const flag = makeChecker(scene, `${id}_flag`, { width: GAP - 0.2, height: 1.6, c1: '#aabbcc', c2: '#1a2030' });
    flag.position.y = COL_H - 1.2; flag.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'ФИНИШ', { textColor: '#88aacc' });
    sign.position.set(0, COL_H - 0.6, 0.31);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

function finishMountainBronze(scene, id) {
    const root = new TransformNode(`fin_${id}`, scene);
    const COL_H = 4.2, GAP = 3.0;
    const brz = [0.55, 0.38, 0.18];
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.5, diffuse: brz, emissive: [0.15, 0.08, 0.03], specPower: 96 });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.5, diffuse: brz, emissive: [0.15, 0.08, 0.03], specPower: 96 });
    colL.position.x = -GAP / 2; colR.position.x = GAP / 2;
    colL.parent = root; colR.parent = root;
    const beam = makeBeam(scene, `${id}_beam`, { width: GAP + 0.8, height: 0.45, depth: 0.45, diffuse: brz, emissive: [0.15, 0.08, 0.03] });
    beam.position.y = COL_H + 0.225; beam.parent = root;
    const flag = makeChecker(scene, `${id}_flag`, { width: GAP - 0.2, height: 1.6, c1: '#ffd76b', c2: '#3a2a1a' });
    flag.position.y = COL_H - 1.2; flag.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'ФИНИШ', { textColor: '#ffd76b' });
    sign.position.set(0, COL_H - 0.3, 0.26);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

// =========================================================================
// УПРОЩЁННЫЕ ЭПОХИ (3-10) через palette-обёртку
// =========================================================================

function finishGeneric(scene, id, palette) {
    const root = new TransformNode(`fin_${id}`, scene);
    const COL_H = 4.2, GAP = 3.0;
    const colL = makeColumn(scene, `${id}_colL`, {
        height: COL_H, diameter: palette.colDia || 0.55,
        shape: palette.shape || 'cylinder',
        diffuse: palette.colDif, emissive: palette.colEm,
        specPower: palette.specPower,
    });
    const colR = makeColumn(scene, `${id}_colR`, {
        height: COL_H, diameter: palette.colDia || 0.55,
        shape: palette.shape || 'cylinder',
        diffuse: palette.colDif, emissive: palette.colEm,
        specPower: palette.specPower,
    });
    colL.position.x = -GAP / 2; colR.position.x = GAP / 2;
    colL.parent = root; colR.parent = root;
    const beam = makeBeam(scene, `${id}_beam`, {
        width: GAP + 0.6, height: 0.35, depth: 0.35,
        diffuse: palette.beamDif || palette.colDif, emissive: palette.beamEm || palette.colEm,
    });
    beam.position.y = COL_H + 0.175;
    beam.parent = root;
    const flag = makeChecker(scene, `${id}_flag`, {
        width: GAP - 0.2, height: 1.6,
        c1: palette.flagC1 || '#ffffff', c2: palette.flagC2 || '#0a0a14',
    });
    flag.position.y = COL_H - 1.2;
    flag.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'ФИНИШ', {
        textColor: palette.signColor || '#ffe44a',
        bgColor: palette.signBg || '#0a1428',
        emissive: palette.signEm || [0.8, 0.7, 0.2],
    });
    sign.position.set(0, COL_H - 0.4, 0.21);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

const GENERIC_EPOCHS = {
    3: [
        { name: 'Город хром', colDif:[0.65,0.65,0.7], colEm:[0.15,0.15,0.18], signColor:'#22ccff', specPower:128, flagC1:'#ffffff', flagC2:'#222222' },
        { name: 'Город неон', colDif:[0.10,0.10,0.20], colEm:[0.10,0.30,0.60], signColor:'#22ddff', signEm:[0.1,0.6,1.0], flagC1:'#22ddff', flagC2:'#0a0a30' },
        { name: 'Город бетон', colDif:[0.55,0.55,0.55], colEm:[0.10,0.10,0.10], signColor:'#cccccc' },
        { name: 'Граффити', colDif:[0.20,0.20,0.25], colEm:[0.05,0.05,0.07], signColor:'#ff44aa', signBg:'#2a0a1a', signEm:[0.8,0.2,0.5], flagC1:'#ff44aa', flagC2:'#222' },
        { name: 'Город жёлтый', colDif:[0.85,0.65,0.10], colEm:[0.30,0.20,0.05], signColor:'#000', signBg:'#ffe44a', signEm:[1,0.85,0.1], flagC1:'#ffe44a', flagC2:'#222' },
    ],
    4: [
        { name: 'Ночной фиолет', colDif:[0.35,0.10,0.50], colEm:[0.35,0.10,0.60], signColor:'#ff88ff', signEm:[0.7,0.3,0.9], flagC1:'#ff88ff', flagC2:'#22002a' },
        { name: 'Ночной циан', colDif:[0.10,0.40,0.50], colEm:[0.10,0.50,0.65], signColor:'#88eeff', signEm:[0.3,0.8,1.0], flagC1:'#88eeff', flagC2:'#001a2a' },
        { name: 'Ночной розовый', colDif:[0.80,0.20,0.45], colEm:[0.55,0.15,0.30], signColor:'#ff88aa', signEm:[1.0,0.4,0.7], flagC1:'#ff88aa', flagC2:'#2a0a1a' },
        { name: 'Ночной жёлтый', colDif:[0.85,0.65,0.10], colEm:[0.55,0.40,0.05], signColor:'#ffee88', signEm:[1,0.85,0.2], flagC1:'#ffee88', flagC2:'#2a2010' },
        { name: 'Голограмма', colDif:[0.30,0.50,1.0], colEm:[0.40,0.70,1.0], signColor:'#ffffff', signEm:[0.6,0.8,1.0], flagC1:'#88ccff', flagC2:'#0a1a3a' },
    ],
    5: [
        { name: 'Пустыня песчаник', colDif:[0.75,0.62,0.38], colEm:[0.18,0.13,0.07], signColor:'#5a3a18', flagC1:'#d4b878', flagC2:'#3a2a1a' },
        { name: 'Пустыня терракота', colDif:[0.65,0.30,0.15], colEm:[0.20,0.07,0.03], signColor:'#ffd76b', flagC1:'#ffaa66', flagC2:'#3a1a0a' },
        { name: 'Пустыня кость', colDif:[0.85,0.80,0.65], colEm:[0.25,0.20,0.12], signColor:'#3a2a1a', flagC1:'#fff5e0', flagC2:'#3a2a1a' },
        { name: 'Пустыня кактус', colDif:[0.30,0.50,0.25], colEm:[0.07,0.15,0.07], signColor:'#ffffff', flagC1:'#9ad889', flagC2:'#1a3a1a' },
        { name: 'Пустыня закат', colDif:[0.85,0.40,0.20], colEm:[0.45,0.15,0.05], signColor:'#ffe44a', signEm:[1,0.5,0.1], flagC1:'#ffaa44', flagC2:'#3a1a0a' },
    ],
    6: [
        { name: 'Океан коралл', colDif:[0.90,0.40,0.50], colEm:[0.30,0.10,0.15], signColor:'#ffffff', flagC1:'#ffaabb', flagC2:'#2a0a1a' },
        { name: 'Океан синий', colDif:[0.10,0.40,0.65], colEm:[0.05,0.20,0.35], signColor:'#aaeeff', flagC1:'#aaeeff', flagC2:'#0a1a3a' },
        { name: 'Океан жемчуг', colDif:[0.85,0.85,0.95], colEm:[0.20,0.20,0.30], signColor:'#3a5a7a', specPower:128, flagC1:'#ffffff', flagC2:'#3a5a7a' },
        { name: 'Океан водоросль', colDif:[0.20,0.50,0.30], colEm:[0.07,0.20,0.10], signColor:'#aaffaa', flagC1:'#7acc7a', flagC2:'#0a2a1a' },
        { name: 'Океан бирюза', colDif:[0.10,0.65,0.65], colEm:[0.10,0.40,0.40], signColor:'#ffffff', flagC1:'#aaffff', flagC2:'#0a2a2a' },
    ],
    7: [
        { name: 'Пещеры камень', colDif:[0.35,0.30,0.25], colEm:[0.07,0.05,0.04], signColor:'#aa8855', flagC1:'#aa9977', flagC2:'#1a1410' },
        { name: 'Пещеры кварц', colDif:[0.55,0.45,0.75], colEm:[0.20,0.15,0.40], signColor:'#ddccff', flagC1:'#ddccff', flagC2:'#2a1a3a' },
        { name: 'Пещеры гриб', colDif:[0.55,0.20,0.20], colEm:[0.25,0.08,0.08], signColor:'#ffffff', flagC1:'#ffaaaa', flagC2:'#2a0a0a' },
        { name: 'Пещеры мох', colDif:[0.20,0.50,0.30], colEm:[0.20,0.55,0.30], signColor:'#aaff88', signEm:[0.3,0.8,0.4], flagC1:'#aaff88', flagC2:'#0a2a1a' },
        { name: 'Пещеры алмаз', colDif:[0.75,0.85,0.95], colEm:[0.35,0.40,0.45], signColor:'#ffffff', specPower:128, flagC1:'#ffffff', flagC2:'#4477aa' },
    ],
    8: [
        { name: 'Вулкан лава', colDif:[0.30,0.10,0.05], colEm:[0.50,0.15,0.02], signColor:'#ffaa00', signEm:[1,0.5,0.05], flagC1:'#ff6600', flagC2:'#3a0a0a' },
        { name: 'Вулкан обсидиан', colDif:[0.10,0.05,0.10], colEm:[0.05,0.02,0.05], signColor:'#aa44aa', specPower:128, flagC1:'#aa44aa', flagC2:'#0a050a' },
        { name: 'Вулкан магма', colDif:[0.55,0.25,0.05], colEm:[0.85,0.40,0.08], signColor:'#ffff55', signEm:[1,1,0.3], flagC1:'#ffaa33', flagC2:'#3a1a05' },
        { name: 'Вулкан пепел', colDif:[0.25,0.22,0.22], colEm:[0.05,0.04,0.04], signColor:'#ff5555', flagC1:'#ff5555', flagC2:'#222' },
        { name: 'Вулкан огонь', colDif:[0.45,0.15,0.05], colEm:[0.85,0.30,0.05], signColor:'#ffee00', signEm:[1,0.9,0.1], flagC1:'#ffcc00', flagC2:'#3a1a05' },
    ],
    9: [
        { name: 'Космос звезда', colDif:[0.45,0.40,0.10], colEm:[0.65,0.55,0.15], signColor:'#ffffaa', flagC1:'#ffffaa', flagC2:'#1a1a05' },
        { name: 'Космос плазма', colDif:[0.30,0.55,0.95], colEm:[0.40,0.80,1.00], signColor:'#aaffff', flagC1:'#aaffff', flagC2:'#0a1a3a' },
        { name: 'Космос лазер', colDif:[0.80,0.10,0.50], colEm:[0.95,0.20,0.80], signColor:'#ffaaff', signEm:[1,0.4,1], flagC1:'#ffaaff', flagC2:'#2a0a2a' },
        { name: 'Космос туманность', colDif:[0.55,0.25,0.85], colEm:[0.50,0.20,0.85], signColor:'#ffccff', flagC1:'#ffccff', flagC2:'#1a0a3a' },
        { name: 'Космос луна', colDif:[0.65,0.65,0.65], colEm:[0.35,0.35,0.35], signColor:'#bbbbbb', flagC1:'#ffffff', flagC2:'#1a1a2a' },
    ],
    10: [
        { name: 'Кибер зелёный', colDif:[0.10,0.80,0.30], colEm:[0.20,1.00,0.40], signColor:'#aaffaa', signEm:[0.2,1.0,0.4], flagC1:'#aaffaa', flagC2:'#0a1a0a' },
        { name: 'Кибер фиолет', colDif:[0.55,0.15,0.85], colEm:[0.70,0.25,1.00], signColor:'#ffaaff', flagC1:'#ffaaff', flagC2:'#1a0a2a' },
        { name: 'Кибер красный', colDif:[0.85,0.10,0.30], colEm:[0.90,0.20,0.40], signColor:'#ffaaaa', flagC1:'#ffaaaa', flagC2:'#2a0a0a' },
        { name: 'Кибер голограмма', colDif:[0.30,0.50,1.0], colEm:[0.50,0.85,1.0], signColor:'#ffffff', flagC1:'#aaeeff', flagC2:'#0a2a4a' },
        { name: 'Кибер жёлтый', colDif:[0.85,0.85,0.10], colEm:[0.85,0.85,0.15], signColor:'#000', signBg:'#ffff44', signEm:[1,1,0.3], flagC1:'#ffee44', flagC2:'#222' },
    ],
};

export const FINISH_CATALOG = [];
const epoch1 = [
    { id: 'f1_v1', title: 'Деревянная с флагом', make: finishForestWoodFlag },
    { id: 'f1_v2', title: 'Золотая', make: finishForestGold },
    { id: 'f1_v3', title: 'С листвой', make: finishForestLeafy },
    { id: 'f1_v4', title: 'Рустик', make: finishForestRustic },
    { id: 'f1_v5', title: 'С фонариками', make: finishForestLanterns },
];
for (const a of epoch1) FINISH_CATALOG.push({ ...a, epoch: 1 });

const epoch2 = [
    { id: 'f2_v1', title: 'Каменная', make: finishMountainStone },
    { id: 'f2_v2', title: 'Кристалл', make: finishMountainCrystal },
    { id: 'f2_v3', title: 'Ледяная', make: finishMountainIce },
    { id: 'f2_v4', title: 'Пиковая', make: finishMountainPeak },
    { id: 'f2_v5', title: 'Бронзовая', make: finishMountainBronze },
];
for (const a of epoch2) FINISH_CATALOG.push({ ...a, epoch: 2 });

for (let epoch = 3; epoch <= 10; epoch++) {
    const palettes = GENERIC_EPOCHS[epoch] || [];
    for (let i = 0; i < palettes.length; i++) {
        const palette = palettes[i];
        FINISH_CATALOG.push({
            id: `f${epoch}_v${i + 1}`,
            epoch,
            title: palette.name,
            make: (scene, id) => finishGeneric(scene, id, palette),
        });
    }
}

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 getFinishesByEpoch(epoch) {
    return FINISH_CATALOG.filter(a => a.epoch === epoch);
}
