/**
 * archFactories — реестр стартовых арок GD по эпохам.
 *
 * 10 эпох × 5 вариантов = 50 арок. Каждая фабрика строит арку:
 *   - две вертикальные «колонны» (cylinder/box) высотой ~4м.
 *   - горизонтальная «балка» сверху.
 *   - надпись «СТАРТ» (DynamicTexture на plane) посередине балки.
 *   - подсветка/glow в стиле эпохи.
 *
 * Возвращает (scene, id) => { root: TransformNode, dispose() }.
 * Габариты: ширина ~3.5м, высота ~4м, центр в (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 = 3.5, diameter = 0.5,
        shape = 'cylinder',   // 'cylinder' | 'box'
        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 на plane). */
function makeSignText(scene, name, text, opts = {}) {
    const {
        width = 2.4, height = 0.7,
        bgColor = '#0a1428', textColor = '#22ff66',
        fontSize = 96, fontFamily = 'sans-serif',
        emissive = [0.2, 1.0, 0.4],
    } = 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.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(...emissive);
    mat.disableLighting = true;
    mat.backFaceCulling = false;
    plane.material = mat;
    return plane;
}

/** Сферическая «лампочка»-glow (для гирлянд/неона). */
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);
    const mat = makeMat(scene, `${name}_mat`, { diffuse: color, emissive: color, disableLighting: true });
    bulb.material = mat;
    return bulb;
}

// =========================================================================
// ФАБРИКИ АРОК ПО ЭПОХАМ (по 5 на эпоху)
// =========================================================================

// ----------------------------------------- Эпоха I — Лес -----
function archForestWood(scene, id) {
    const root = new TransformNode(`arch_${id}`, scene);
    const COL_H = 3.6, 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;
    // листва — зелёная сферка над балкой
    for (let i = 0; i < 5; i++) {
        const leaf = MeshBuilder.CreateSphere(`${id}_leaf_${i}`, { diameter: 0.7 }, scene);
        leaf.position.set(-1.4 + i * 0.7, COL_H + 0.7, 0);
        const mat = makeMat(scene, `${id}_leaf_mat_${i}`, {
            diffuse: [0.2, 0.55, 0.25], emissive: [0.06, 0.18, 0.08],
        });
        leaf.material = mat;
        leaf.parent = root;
    }
    const sign = makeSignText(scene, `${id}_sign`, 'СТАРТ', {
        width: 2.4, height: 0.7, textColor: '#22ff66',
    });
    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 archForestStone(scene, id) {
    const root = new TransformNode(`arch_${id}`, scene);
    const COL_H = 3.4, GAP = 3.0;
    const stoneDif = [0.55, 0.55, 0.50];
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.7, shape: 'box',
        diffuse: stoneDif, emissive: [0.10, 0.10, 0.09] });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.7, shape: 'box',
        diffuse: stoneDif, emissive: [0.10, 0.10, 0.09] });
    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.9, height: 0.55, depth: 0.55,
        diffuse: stoneDif, emissive: [0.10, 0.10, 0.09],
    });
    beam.position.y = COL_H + 0.275;
    beam.parent = root;
    // мох сверху
    for (let i = 0; i < 7; i++) {
        const moss = MeshBuilder.CreateSphere(`${id}_moss_${i}`, { diameter: 0.35 }, scene);
        moss.position.set(-1.7 + i * 0.55, COL_H + 0.55, 0);
        moss.material = makeMat(scene, `${id}_moss_mat_${i}`,
            { diffuse: [0.25, 0.5, 0.20], emissive: [0.07, 0.15, 0.05] });
        moss.parent = root;
    }
    const sign = makeSignText(scene, `${id}_sign`, 'СТАРТ', { textColor: '#88dd55' });
    sign.position.set(0, COL_H - 0.3, 0.31);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

function archForestVine(scene, id) {
    const root = new TransformNode(`arch_${id}`, scene);
    const COL_H = 3.6, GAP = 3.0;
    // тонкие колонны-ветки
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.35,
        diffuse: [0.32, 0.22, 0.12], emissive: [0.08, 0.05, 0.03] });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.35,
        diffuse: [0.32, 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.4, height: 0.25, depth: 0.25,
        diffuse: [0.32, 0.22, 0.12], emissive: [0.08, 0.05, 0.03],
    });
    beam.position.y = COL_H + 0.125;
    beam.parent = root;
    // лианы — много зелёных мелких сфер
    for (let i = 0; i < 12; i++) {
        const x = -1.8 + i * 0.32;
        const dropY = 0.5 + Math.abs(Math.sin(i * 1.3)) * 0.8;
        for (let j = 0; j < 4; j++) {
            const leaf = MeshBuilder.CreateSphere(`${id}_v_${i}_${j}`, { diameter: 0.25 }, scene);
            leaf.position.set(x, COL_H + 0.2 - j * 0.25, 0);
            leaf.material = makeMat(scene, `${id}_vm_${i}_${j}`,
                { diffuse: [0.15 + (j % 2) * 0.1, 0.55 - j * 0.05, 0.15], emissive: [0.05, 0.18, 0.05] });
            leaf.parent = root;
        }
    }
    const sign = makeSignText(scene, `${id}_sign`, 'СТАРТ', { textColor: '#aaff66' });
    sign.position.set(0, COL_H - 0.5, 0.16);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

function archForestLanterns(scene, id) {
    const root = new TransformNode(`arch_${id}`, scene);
    const COL_H = 3.6, GAP = 3.0;
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.50,
        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.50,
        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.6, height: 0.35, depth: 0.35,
        diffuse: [0.30, 0.18, 0.08], emissive: [0.06, 0.04, 0.02],
    });
    beam.position.y = COL_H + 0.175;
    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.18 - Math.abs(Math.sin(i * 1.7)) * 0.3,
            0,
            colors[i % colors.length],
            0.9
        );
        bulb.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.21);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

function archForestRustic(scene, id) {
    const root = new TransformNode(`arch_${id}`, scene);
    const COL_H = 3.5, GAP = 2.8;
    // кривые колонны (две box со слегка разным масштабом)
    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;
    // X-перекрестье из досок
    const dr1 = makeBeam(scene, `${id}_dr1`, {
        width: 2.6, height: 0.18, depth: 0.18,
        diffuse: [0.40, 0.25, 0.13], emissive: [0.08, 0.05, 0.03],
    });
    dr1.position.y = COL_H * 0.5;
    dr1.rotation.z = Math.PI / 5;
    dr1.parent = root;
    const dr2 = dr1.clone(`${id}_dr2`);
    dr2.rotation.z = -Math.PI / 5;
    dr2.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'СТАРТ', { textColor: '#ffe44a' });
    sign.position.set(0, COL_H + 0.5, 0.26);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

// ----------------------------------------- Эпоха II — Горы -----
function archMountainStone(scene, id) {
    const root = new TransformNode(`arch_${id}`, scene);
    const COL_H = 3.4, GAP = 3.0;
    const colDif = [0.50, 0.50, 0.55];
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.75, shape: 'box', diffuse: colDif, emissive: [0.10, 0.10, 0.11] });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.75, shape: 'box', diffuse: colDif, 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.0, height: 0.55, depth: 0.55, diffuse: colDif, emissive: [0.10, 0.10, 0.11] });
    beam.position.y = COL_H + 0.275; beam.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'СТАРТ', { textColor: '#aaccff' });
    sign.position.set(0, COL_H - 0.3, 0.31);
    sign.parent = root;
    return { root, dispose: () => { for (const ch of root.getChildMeshes()) ch.dispose(); root.dispose(); } };
}

function archMountainCrystal(scene, id) {
    const root = new TransformNode(`arch_${id}`, scene);
    const COL_H = 3.6, GAP = 3.0;
    const xtaldif = [0.5, 0.7, 0.95], xtalem = [0.20, 0.35, 0.55];
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.55, diffuse: xtaldif, emissive: xtalem, specPower: 96 });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.55, diffuse: xtaldif, emissive: xtalem, 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: xtaldif, emissive: xtalem });
    beam.position.y = COL_H + 0.175; beam.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'СТАРТ', { textColor: '#aaeeff' });
    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(); } };
}

function archMountainIce(scene, id) {
    const root = new TransformNode(`arch_${id}`, scene);
    const COL_H = 3.5, GAP = 3.0;
    const icedif = [0.80, 0.92, 1.0], iceem = [0.25, 0.35, 0.50];
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.55, diffuse: icedif, emissive: iceem, specPower: 128 });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.55, diffuse: icedif, emissive: iceem, 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: icedif, emissive: iceem });
    beam.position.y = COL_H + 0.175; beam.parent = root;
    const sign = makeSignText(scene, `${id}_sign`, 'СТАРТ', { textColor: '#ddffff' });
    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(); } };
}

function archMountainPeak(scene, id) {
    const root = new TransformNode(`arch_${id}`, scene);
    const COL_H = 3.8, GAP = 3.0;
    const colDif = [0.40, 0.45, 0.50];
    const colL = makeColumn(scene, `${id}_colL`, { height: COL_H, diameter: 0.6, shape: 'box', diffuse: colDif, emissive: [0.05, 0.06, 0.07] });
    const colR = makeColumn(scene, `${id}_colR`, { height: COL_H, diameter: 0.6, shape: 'box', diffuse: colDif, emissive: [0.05, 0.06, 0.07] });
    colL.position.x = -GAP / 2; colR.position.x = GAP / 2;
    colL.parent = root; colR.parent = root;
    // вместо балки — пирамидальная крыша из 2-х наклонённых box
    const sideA = makeBeam(scene, `${id}_a`, { width: GAP * 0.7, height: 0.4, depth: 0.4, diffuse: colDif, 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 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 archMountainBronze(scene, id) {
    const root = new TransformNode(`arch_${id}`, scene);
    const COL_H = 3.6, 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 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(); } };
}

// ----------------------------------------- Эпохи III-X — упрощённые шаблоны -----
function archGeneric(scene, id, palette) {
    const root = new TransformNode(`arch_${id}`, scene);
    const COL_H = palette.colH || 3.5, GAP = palette.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: palette.beamH || 0.35, depth: 0.35,
        diffuse: palette.beamDif || palette.colDif, emissive: palette.beamEm || palette.colEm,
    });
    beam.position.y = COL_H + (palette.beamH || 0.35) / 2;
    beam.parent = root;
    // бонус — например лампочки или сферки
    if (palette.bulbs) {
        for (let i = 0; i < palette.bulbs.count; i++) {
            const b = makeBulb(scene, `${id}_bulb_${i}`,
                -GAP / 2 + (i + 0.5) * (GAP / palette.bulbs.count),
                COL_H + 0.5,
                0,
                palette.bulbs.color
            );
            b.parent = root;
        }
    }
    const sign = makeSignText(scene, `${id}_sign`, palette.signText || 'СТАРТ', {
        textColor: palette.signColor || '#ffffff',
        bgColor: palette.signBg || '#0a1428',
        emissive: palette.signEm || [0.5, 0.5, 0.5],
    });
    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 },
        { name: 'Город неон', colDif:[0.10,0.10,0.20], colEm:[0.10,0.30,0.60], signColor:'#22ddff', signEm:[0.1,0.6,1.0] },
        { 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] },
        { 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] },
    ],
    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] },
        { name: 'Ночной циан', colDif:[0.10,0.40,0.50], colEm:[0.10,0.50,0.65], signColor:'#88eeff', signEm:[0.3,0.8,1.0] },
        { name: 'Ночной розовый', colDif:[0.80,0.20,0.45], colEm:[0.55,0.15,0.30], signColor:'#ff88aa', signEm:[1.0,0.4,0.7] },
        { name: 'Ночной жёлтый', colDif:[0.85,0.65,0.10], colEm:[0.55,0.40,0.05], signColor:'#ffee88', signEm:[1,0.85,0.2] },
        { name: 'Голограмма', colDif:[0.30,0.50,1.0], colEm:[0.40,0.70,1.0], signColor:'#ffffff', signEm:[0.6,0.8,1.0] },
    ],
    5: [
        { name: 'Пустыня песчаник', colDif:[0.75,0.62,0.38], colEm:[0.18,0.13,0.07], signColor:'#5a3a18' },
        { name: 'Пустыня терракота', colDif:[0.65,0.30,0.15], colEm:[0.20,0.07,0.03], signColor:'#ffd76b' },
        { name: 'Пустыня кость', colDif:[0.85,0.80,0.65], colEm:[0.25,0.20,0.12], signColor:'#3a2a1a' },
        { name: 'Пустыня кактус', colDif:[0.30,0.50,0.25], colEm:[0.07,0.15,0.07], signColor:'#ffffff' },
        { name: 'Пустыня закат', colDif:[0.85,0.40,0.20], colEm:[0.45,0.15,0.05], signColor:'#ffe44a', signEm:[1,0.5,0.1] },
    ],
    6: [
        { name: 'Океан коралл', colDif:[0.90,0.40,0.50], colEm:[0.30,0.10,0.15], signColor:'#ffffff' },
        { name: 'Океан синий', colDif:[0.10,0.40,0.65], colEm:[0.05,0.20,0.35], signColor:'#aaeeff' },
        { name: 'Океан жемчуг', colDif:[0.85,0.85,0.95], colEm:[0.20,0.20,0.30], signColor:'#3a5a7a', specPower:128 },
        { name: 'Океан водоросль', colDif:[0.20,0.50,0.30], colEm:[0.07,0.20,0.10], signColor:'#aaffaa' },
        { name: 'Океан бирюза', colDif:[0.10,0.65,0.65], colEm:[0.10,0.40,0.40], signColor:'#ffffff' },
    ],
    7: [
        { name: 'Пещеры камень', colDif:[0.35,0.30,0.25], colEm:[0.07,0.05,0.04], signColor:'#aa8855' },
        { name: 'Пещеры кварц', colDif:[0.55,0.45,0.75], colEm:[0.20,0.15,0.40], signColor:'#ddccff' },
        { name: 'Пещеры гриб', colDif:[0.55,0.20,0.20], colEm:[0.25,0.08,0.08], signColor:'#ffffff' },
        { name: 'Пещеры мох', colDif:[0.20,0.50,0.30], colEm:[0.20,0.55,0.30], signColor:'#aaff88', signEm:[0.3,0.8,0.4] },
        { name: 'Пещеры алмаз', colDif:[0.75,0.85,0.95], colEm:[0.35,0.40,0.45], signColor:'#ffffff', specPower:128 },
    ],
    8: [
        { name: 'Вулкан лава', colDif:[0.30,0.10,0.05], colEm:[0.50,0.15,0.02], signColor:'#ffaa00', signEm:[1,0.5,0.05] },
        { name: 'Вулкан обсидиан', colDif:[0.10,0.05,0.10], colEm:[0.05,0.02,0.05], signColor:'#aa44aa', specPower:128 },
        { name: 'Вулкан магма', colDif:[0.55,0.25,0.05], colEm:[0.85,0.40,0.08], signColor:'#ffff55', signEm:[1,1,0.3] },
        { name: 'Вулкан пепел', colDif:[0.25,0.22,0.22], colEm:[0.05,0.04,0.04], signColor:'#ff5555' },
        { name: 'Вулкан огонь', colDif:[0.45,0.15,0.05], colEm:[0.85,0.30,0.05], signColor:'#ffee00', signEm:[1,0.9,0.1] },
    ],
    9: [
        { name: 'Космос звезда', colDif:[0.45,0.40,0.10], colEm:[0.65,0.55,0.15], signColor:'#ffffaa' },
        { name: 'Космос плазма', colDif:[0.30,0.55,0.95], colEm:[0.40,0.80,1.00], signColor:'#aaffff' },
        { name: 'Космос лазер', colDif:[0.80,0.10,0.50], colEm:[0.95,0.20,0.80], signColor:'#ffaaff', signEm:[1,0.4,1] },
        { name: 'Космос туманность', colDif:[0.55,0.25,0.85], colEm:[0.50,0.20,0.85], signColor:'#ffccff' },
        { name: 'Космос луна', colDif:[0.65,0.65,0.65], colEm:[0.35,0.35,0.35], signColor:'#bbbbbb' },
    ],
    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] },
        { name: 'Кибер фиолет', colDif:[0.55,0.15,0.85], colEm:[0.70,0.25,1.00], signColor:'#ffaaff' },
        { name: 'Кибер красный', colDif:[0.85,0.10,0.30], colEm:[0.90,0.20,0.40], signColor:'#ffaaaa' },
        { name: 'Кибер голограмма', colDif:[0.30,0.50,1.0], colEm:[0.50,0.85,1.0], signColor:'#ffffff' },
        { name: 'Кибер жёлтый', colDif:[0.85,0.85,0.10], colEm:[0.85,0.85,0.15], signColor:'#000', signBg:'#ffff44', signEm:[1,1,0.3] },
    ],
};

export const ARCH_CATALOG = [];
const epoch1 = [
    { id: 'a1_v1', title: 'Деревянная', make: archForestWood },
    { id: 'a1_v2', title: 'Каменная', make: archForestStone },
    { id: 'a1_v3', title: 'С лианами', make: archForestVine },
    { id: 'a1_v4', title: 'С фонариками', make: archForestLanterns },
    { id: 'a1_v5', title: 'Рустик', make: archForestRustic },
];
for (const a of epoch1) ARCH_CATALOG.push({ ...a, epoch: 1 });

const epoch2 = [
    { id: 'a2_v1', title: 'Каменная', make: archMountainStone },
    { id: 'a2_v2', title: 'Кристалл', make: archMountainCrystal },
    { id: 'a2_v3', title: 'Ледяная', make: archMountainIce },
    { id: 'a2_v4', title: 'Пиковая', make: archMountainPeak },
    { id: 'a2_v5', title: 'Бронзовая', make: archMountainBronze },
];
for (const a of epoch2) ARCH_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];
        ARCH_CATALOG.push({
            id: `a${epoch}_v${i + 1}`,
            epoch,
            title: palette.name,
            make: (scene, id) => archGeneric(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 getArchesByEpoch(epoch) {
    return ARCH_CATALOG.filter(a => a.epoch === epoch);
}
