/**
 * TerrainGenPanel — процедурный генератор ландшафта с live-превью.
 *
 * Левая боковая панель в KubikonEditor (открывается через кнопку
 * «Генератор» в TerrainPanel или отдельно). Позволяет:
 *
 *   - Настроить параметры noise: scale/octaves/amplitude/exponent
 *   - Видеть live-превью карты на canvas (2D top-down) — обновляется
 *     при изменении любого параметра с debounce 150мс
 *   - Применить готовый пресет (Горы/Лес/Острова/Пустыня)
 *   - Сгенерировать мир: создаёт voxel-террейн через WorldGenerator,
 *     заменяет существующий
 *
 * Без сетевого I/O — всё происходит локально в браузере, BabylonScene
 * получает результат через переданный prop onApply(params).
 *
 * Архитектура live-превью:
 *   - Превью использует ТУ ЖЕ WorldGenerator что и реальная генерация
 *   - sampleHeight() + sampleBiome() для каждого пикселя 256×256 canvas
 *   - Цвет = биом × яркость от высоты
 *   - 256×256 = 65 536 noise-вызовов = ~5мс при 0.1мкс/вызов
 *
 * Параметры хранятся в локальном state. При нажатии «Сгенерировать»
 * вызывается onApply(params) — BabylonScene применяет.
 */

import React, { useState, useRef, useEffect, useCallback } from 'react';
import { WorldGenerator, DEFAULT_GENERATOR_PARAMS } from './engine/voxel/WorldGenerator';
import Icon from './Icon';
import cl from './TerrainGenPanel.module.css';

// ============================================================================
// Inline-стили для карточек выбора режима генерации.
// Кнопка-карточка с иконкой слева и текстом справа. Hover-эффект через onMouseEnter
// не делаем — используем CSS box-shadow через inline для простоты.
// ============================================================================
const modeCardStyle = {
    display: 'flex',
    alignItems: 'flex-start',
    gap: 14,
    padding: '14px 14px',
    // Тёмный фон под тёмную тему редактора
    background: '#2e2e2e',
    border: '1px solid #3a3a3a',
    borderRadius: 10,
    cursor: 'pointer',
    color: '#e8e8ea',
    textAlign: 'left',
    fontFamily: 'inherit',
    transition: 'all 0.15s ease-out',
    boxShadow: '0 1px 3px rgba(0, 0, 0, 0.3)',
};
const modeIconStyle = {
    fontSize: 36,
    lineHeight: 1,
    filter: 'drop-shadow(0 1px 2px rgba(0,0,0,0.10))',
    flexShrink: 0,
};
const modeTitleStyle = {
    fontSize: 14,
    fontWeight: 800,
    letterSpacing: 0.2,
    color: '#e8e8ea',
    marginBottom: 6,
};
const modeDescStyle = {
    fontSize: 12,
    lineHeight: 1.5,
    color: '#9a9a9e',
    marginBottom: 10,
};
const modeBadgesStyle = {
    display: 'flex',
    flexWrap: 'wrap',
    gap: 4,
};
const badgeStyle = (color) => ({
    fontSize: 10,
    fontWeight: 700,
    padding: '3px 7px',
    borderRadius: 4,
    background: `${color}1a`,
    color: color,
    border: `1px solid ${color}55`,
});

// ============================================================================
// Готовые пресеты — каждый со своим РАЗНЫМ распределением биомов.
// Это даёт визуально различимые карты: пустыня — сплошной песок,
// горы — серый камень со снегом, и т.п.
// ============================================================================

// Стандартные биомы (для большинства пресетов)
const BIOME_PLAIN = {
    id: 'plain', topMaterial: 'grass', softMaterial: 'dirt', hardMaterial: 'rock',
    features: { trees: 0.3, treeTypes: ['oak'], grass: 0.2 },
};
const BIOME_FOREST = {
    id: 'forest', topMaterial: 'grass', softMaterial: 'dirt', hardMaterial: 'rock',
    features: { trees: 0.8, treeTypes: ['oak', 'autumn'], grass: 0.4 },
};
const BIOME_DESERT = {
    id: 'desert', topMaterial: 'sand', softMaterial: 'sand', hardMaterial: 'sand',
    features: { trees: 0, treeTypes: [], grass: 0 },
};
const BIOME_MOUNTAIN = {
    id: 'mountain', topMaterial: 'rock', softMaterial: 'rock', hardMaterial: 'rock',
    heightBonus: 1.3,    // меньше резкости на границе с травой
    features: { trees: 0.05, treeTypes: ['autumn'] },
};
const BIOME_SNOW = {
    id: 'snow', topMaterial: 'snow', softMaterial: 'rock', hardMaterial: 'rock',
    heightBonus: 1.5,
    features: { trees: 0.02, treeTypes: ['birch'] },
};

const PRESETS = {
    default: {
        label: 'Земля',
        params: {
            ...DEFAULT_GENERATOR_PARAMS,
            biomes: [
                { ...BIOME_DESERT,   threshold: [0.0, 0.15] },
                { ...BIOME_PLAIN,    threshold: [0.15, 0.5] },
                { ...BIOME_FOREST,   threshold: [0.5, 0.75] },
                { ...BIOME_MOUNTAIN, threshold: [0.75, 0.9] },
                { ...BIOME_SNOW,     threshold: [0.9, 1.0] },
            ],
        },
    },
    meadow: {
        label: 'Луг',
        params: {
            ...DEFAULT_GENERATOR_PARAMS,
            heightmap: { ...DEFAULT_GENERATOR_PARAMS.heightmap, amplitude: 4, exponent: 1.2 },
            biomes: [
                { ...BIOME_PLAIN,  threshold: [0, 0.5], features: { ...BIOME_PLAIN.features, trees: 0.2 } },
                { ...BIOME_FOREST, threshold: [0.5, 1.0], features: { ...BIOME_FOREST.features, trees: 0.5 } },
            ],
        },
    },
    mountains: {
        label: 'Горы',
        params: {
            ...DEFAULT_GENERATOR_PARAMS,
            heightmap: { ...DEFAULT_GENERATOR_PARAMS.heightmap, amplitude: 30, exponent: 2.0, scale: 0.012 },
            biomes: [
                { ...BIOME_PLAIN,    threshold: [0.0, 0.25] },
                { ...BIOME_FOREST,   threshold: [0.25, 0.45] },
                { ...BIOME_MOUNTAIN, threshold: [0.45, 0.75], heightBonus: 1.5 },
                { ...BIOME_SNOW,     threshold: [0.75, 1.0], heightBonus: 1.8 },
            ],
        },
    },
    flat: {
        label: 'Равнина',
        params: {
            ...DEFAULT_GENERATOR_PARAMS,
            heightmap: { ...DEFAULT_GENERATOR_PARAMS.heightmap, amplitude: 3, exponent: 1.0 },
            biomes: [
                { ...BIOME_PLAIN,  threshold: [0, 0.4], features: { ...BIOME_PLAIN.features, trees: 0.1 } },
                { ...BIOME_FOREST, threshold: [0.4, 0.85], features: { ...BIOME_FOREST.features, trees: 0.4 } },
                { ...BIOME_DESERT, threshold: [0.85, 1.0] },
            ],
        },
    },
    islands: {
        label: 'Острова',
        params: {
            ...DEFAULT_GENERATOR_PARAMS,
            heightmap: { ...DEFAULT_GENERATOR_PARAMS.heightmap, amplitude: 18, exponent: 2.8, baseHeight: -2 },
            biomes: [
                { ...BIOME_DESERT, threshold: [0.0, 0.4] },        // песчаные пляжи большой части
                { ...BIOME_PLAIN,  threshold: [0.4, 0.75] },
                { ...BIOME_FOREST, threshold: [0.75, 1.0], features: { ...BIOME_FOREST.features, trees: 0.6 } },
            ],
        },
    },
    forest: {
        label: 'Лес',
        params: {
            ...DEFAULT_GENERATOR_PARAMS,
            structures: { ...DEFAULT_GENERATOR_PARAMS.structures, trees: { enabled: true, density: 0.7, minDistance: 6 } },
            biomes: [
                { ...BIOME_FOREST, threshold: [0.0, 0.7],
                  features: { trees: 1.0, treeTypes: ['oak', 'autumn'], grass: 0.5 } },
                { ...BIOME_FOREST, threshold: [0.7, 1.0], id: 'forest_dense',
                  features: { trees: 1.4, treeTypes: ['oak', 'autumn'], grass: 0.6 } },
            ],
        },
    },
    desert: {
        label: 'Пустыня',
        params: {
            ...DEFAULT_GENERATOR_PARAMS,
            biomeMap: { ...DEFAULT_GENERATOR_PARAMS.biomeMap, scale: 0.005 },
            heightmap: { ...DEFAULT_GENERATOR_PARAMS.heightmap, amplitude: 6, exponent: 1.2 },
            biomes: [
                { ...BIOME_DESERT, threshold: [0.0, 0.8] },
                { ...BIOME_DESERT, threshold: [0.8, 1.0], id: 'oasis',
                  topMaterial: 'grass', softMaterial: 'dirt', hardMaterial: 'sand',
                  features: { trees: 0.3, treeTypes: ['oak'], grass: 0.2 } },
            ],
        },
    },
};

// ============================================================================
// Цвета биомов для preview canvas (top-down view)
// ============================================================================
const BIOME_COLOR = {
    desert: [220, 200, 120],
    plain: [110, 175, 90],
    forest: [70, 140, 60],
    mountain: [140, 140, 140],
    snow: [240, 245, 250],
    // Fallback по topMaterial если биом не известен
    grass: [110, 175, 90],
    sand: [220, 200, 120],
    rock: [140, 140, 140],
};
// Цвет биома: сначала по id, потом по topMaterial.
function biomeColor(biome) {
    return BIOME_COLOR[biome.id] ?? BIOME_COLOR[biome.topMaterial] ?? [128, 128, 128];
}

// ============================================================================
// Компоненты UI
// ============================================================================

function Slider({ label, value, min, max, step, onChange, format }) {
    const display = format ? format(value) : value.toFixed(2);
    return (
        <div className={cl.sliderRow}>
            <div className={cl.sliderHead}>
                <span className={cl.sliderLabel}>{label}</span>
                <span className={cl.sliderValue}>{display}</span>
            </div>
            <input
                type="range"
                min={min}
                max={max}
                step={step}
                value={value}
                onChange={(e) => onChange(parseFloat(e.target.value))}
                className={cl.slider}
            />
        </div>
    );
}

function Section({ title, children, defaultOpen = true }) {
    const [open, setOpen] = useState(defaultOpen);
    return (
        <div className={cl.section}>
            <button className={cl.sectionHeader} onClick={() => setOpen(!open)} type="button">
                <span className={cl.sectionArrow}>{open ? '▾' : '▸'}</span>
                {title}
            </button>
            {open && <div className={cl.sectionBody}>{children}</div>}
        </div>
    );
}

// ============================================================================
// Главный компонент
// ============================================================================
export default function TerrainGenPanel({ onApply, onApplyRoblox, onClearRoblox, onClose, hasRobloxTerrain }) {
    // === Режим генерации ===
    //   null — экран выбора между Voxel и Smooth
    //   'voxel' — параметры воксельного генератора
    //   'smooth' — параметры гладкого ландшафта (Roblox-style)
    const [genMode, setGenMode] = useState(null);

    // Авто-выбор 'smooth' при первом обнаружении ландшафта в сцене.
    // Если genMode уже выбран пользователем — не переопределяем.
    useEffect(() => {
        if (hasRobloxTerrain && genMode === null) {
            setGenMode('smooth');
        }
    }, [hasRobloxTerrain]);

    // === Roblox-style smooth terrain (новая параллельная подсистема) ===
    // Slider от 30 до 150 cells (= 120-600м карта при 4м/cell).
    const [robloxSize, setRobloxSize] = useState(50);
    const [isApplyingRoblox, setIsApplyingRoblox] = useState(false);

    // State параметров — деструктурируем DEFAULT_GENERATOR_PARAMS чтобы
    // компонент управлял всеми полями.
    const [seed, setSeed] = useState(DEFAULT_GENERATOR_PARAMS.seed);
    const [worldSize, setWorldSize] = useState(160);   // в voxel-units (160 = 80м)
    const [heightmap, setHeightmap] = useState(DEFAULT_GENERATOR_PARAMS.heightmap);
    const [biomes, setBiomes] = useState(PRESETS.default.params.biomes);
    const [treesEnabled, setTreesEnabled] = useState(DEFAULT_GENERATOR_PARAMS.structures.trees.enabled);
    const [treesDensity, setTreesDensity] = useState(DEFAULT_GENERATOR_PARAMS.structures.trees.density);
    // Размер деревьев — 1.0 базовые, 2.0 большие, 0.5 кусты
    const [treesSizeScale, setTreesSizeScale] = useState(DEFAULT_GENERATOR_PARAMS.structures.trees.sizeScale ?? 1.0);
    // Декорации: цветы и трава — раздельно
    const [flowersDensity, setFlowersDensity] = useState(DEFAULT_GENERATOR_PARAMS.structures.decorations?.flowersDensity ?? 0.015);
    const [grassDensity, setGrassDensity] = useState(DEFAULT_GENERATOR_PARAMS.structures.decorations?.grassDensity ?? 0.08);
    // Smooth-режим: плотность деревьев (отдельно от voxel-treesDensity).
    // 0..1: 0=нет деревьев, 1=густой лес (1 дерево на ~64м² базовый шаг).
    const [smoothTreesDensity, setSmoothTreesDensity] = useState(0.4);
    const [previewStats, setPreviewStats] = useState(null);
    /** Прогресс генерации: { pct: 0..100, phase: 'heightmap'|'surface'|'trees'|'render'|'done' } */
    const [progress, setProgress] = useState(null);
    const canvasRef = useRef(null);
    const debounceRef = useRef(null);

    // Глобальный callback который BabylonScene.__voxelGenerate дёргает с прогрессом.
    // Регистрируем на window чтобы движок видел.
    useEffect(() => {
        const handler = (pct, phase) => setProgress({ pct, phase });
        window.__voxelGenProgress = handler;
        return () => {
            if (window.__voxelGenProgress === handler) {
                delete window.__voxelGenProgress;
            }
        };
    }, []);

    // Собираем params из state. useCallback чтобы не пересоздавать на каждый render.
    const buildParams = useCallback(() => ({
        ...DEFAULT_GENERATOR_PARAMS,
        seed,
        heightmap,
        biomes,
        structures: {
            ...DEFAULT_GENERATOR_PARAMS.structures,
            trees: {
                ...DEFAULT_GENERATOR_PARAMS.structures.trees,
                enabled: treesEnabled,
                density: treesDensity,
                sizeScale: treesSizeScale,
            },
            decorations: {
                ...DEFAULT_GENERATOR_PARAMS.structures.decorations,
                enabled: true,
                flowersDensity,
                grassDensity,
            },
        },
    }), [seed, heightmap, biomes, treesEnabled, treesDensity, treesSizeScale, flowersDensity, grassDensity]);

    // Рендер preview canvas — top-down карта.
    // Каждый пиксель = (x_world, z_world) куда мы сэмплим biome и height.
    const renderPreview = useCallback(() => {
        const canvas = canvasRef.current;
        if (!canvas) return;
        const ctx = canvas.getContext('2d');
        const w = canvas.width;
        const h = canvas.height;

        const t0 = performance.now();
        const params = buildParams();
        const gen = new WorldGenerator(params);

        // Sample 1 пиксель на каждый x,z.
        // Voxel: 1 voxel = 0.25м, halfSize = worldSize voxel-units.
        // Smooth: 1 cell = 4м = 16 voxel-units, halfSize_voxels = robloxSize * 8.
        const halfSize = genMode === 'smooth'
            ? robloxSize * 16 / 2     // size cells × 16 voxel-units / 2
            : worldSize;
        const step = (halfSize * 2) / w;
        const img = ctx.createImageData(w, h);
        const data = img.data;

        let minH = Infinity, maxH = -Infinity;
        const heights = new Float32Array(w * h);
        // Первый проход — high-min для нормализации.
        for (let py = 0; py < h; py++) {
            const wz = -halfSize + py * step;
            for (let px = 0; px < w; px++) {
                const wx = -halfSize + px * step;
                const h_ = gen.sampleHeight(wx, wz);
                heights[py * w + px] = h_;
                if (h_ < minH) minH = h_;
                if (h_ > maxH) maxH = h_;
            }
        }
        const hRange = Math.max(1, maxH - minH);

        // Второй проход — биом + тень от высоты
        for (let py = 0; py < h; py++) {
            const wz = -halfSize + py * step;
            for (let px = 0; px < w; px++) {
                const wx = -halfSize + px * step;
                const biome = gen.sampleBiome(wx, wz);
                const h_ = heights[py * w + px];
                let r, g, b;
                if (h_ <= 0) {
                    // Вода
                    r = 60; g = 130; b = 200;
                } else {
                    const base = biomeColor(biome);
                    // Тень от высоты: чем выше — тем светлее (имитация горы)
                    const tHi = (h_ - minH) / hRange;
                    const lighten = 0.7 + tHi * 0.6;
                    r = Math.min(255, Math.round(base[0] * lighten));
                    g = Math.min(255, Math.round(base[1] * lighten));
                    b = Math.min(255, Math.round(base[2] * lighten));
                }
                const idx = (py * w + px) * 4;
                data[idx]     = r;
                data[idx + 1] = g;
                data[idx + 2] = b;
                data[idx + 3] = 255;
            }
        }
        ctx.putImageData(img, 0, 0);

        // Иконки деревьев на preview — только в voxel-режиме.
        // В smooth ландшафте деревьев пока нет.
        let treeCount = 0;
        if (genMode === 'voxel') {
            ctx.fillStyle = 'rgba(20, 50, 20, 0.85)';
            for (let py = 0; py < h; py += 2) {
                const wz = -halfSize + py * step;
                for (let px = 0; px < w; px += 2) {
                    const wx = -halfSize + px * step;
                    const tree = gen.sampleTreeAt(Math.floor(wx), Math.floor(wz));
                    if (tree) {
                        ctx.fillRect(px - 1, py - 1, 2, 2);
                        treeCount++;
                    }
                }
            }
        }

        const dt = performance.now() - t0;
        setPreviewStats({
            time: Math.round(dt),
            minH: Math.round(minH),
            maxH: Math.round(maxH),
            estimatedTrees: treeCount * 4,   // компенсация sample step=2
        });
    }, [buildParams, worldSize, genMode, robloxSize]);

    // Debounced re-render preview когда меняются параметры
    useEffect(() => {
        if (debounceRef.current) clearTimeout(debounceRef.current);
        debounceRef.current = setTimeout(renderPreview, 150);
        return () => {
            if (debounceRef.current) clearTimeout(debounceRef.current);
        };
    }, [renderPreview]);

    // Применить пресет
    const applyPreset = (key) => {
        const p = PRESETS[key];
        if (!p) return;
        setSeed(p.params.seed);
        setHeightmap(p.params.heightmap);
        // Биомы — главное визуальное отличие пресетов!
        // Без передачи biomes все пресеты будут с одинаковым набором.
        setBiomes(p.params.biomes ?? DEFAULT_GENERATOR_PARAMS.biomes);
        setTreesEnabled(p.params.structures?.trees?.enabled ?? true);
        setTreesDensity(p.params.structures?.trees?.density ?? 0.3);
    };

    // Хард-блокировка от двойных кликов: ref устанавливается СРАЗУ
    // (в отличие от setState который batched/async).
    const generatingRef = useRef(false);
    // Сгенерировать мир — отдаём params наверх. onApply async.
    const handleApply = async () => {
        if (!onApply) return;
        if (generatingRef.current) {
            console.warn('[TerrainGen] already generating, ignoring click');
            return;
        }
        generatingRef.current = true;
        setProgress({ pct: 0, phase: 'starting' });
        try {
            await onApply({
                params: buildParams(),
                size: worldSize,
            });
        } catch (e) {
            console.error('voxelGenerate failed:', e);
        } finally {
            generatingRef.current = false;
        }
        // Авто-скрытие через 600мс чтобы пользователь увидел "100%"
        setTimeout(() => setProgress(null), 600);
    };
    const isGenerating = progress !== null && progress.pct < 100;

    // === Roblox smooth terrain handlers ===
    const robloxRef = useRef(false);
    const handleApplyRoblox = async () => {
        if (!onApplyRoblox) return;
        if (robloxRef.current) {
            console.warn('[RobloxTerrain] already applying');
            return;
        }
        robloxRef.current = true;
        setIsApplyingRoblox(true);
        try {
            // Передаём те же params что и для voxel-режима. Сервер
            // __robloxTest использует их для WorldGenerator (sampleHeight + sampleBiome).
            // Деревья пока отключены, voxel-декорации тоже (smooth-декорации
            // обрабатываются отдельно через smoothDeco поле).
            const p = buildParams();
            p.structures = {
                ...p.structures,
                trees: { ...p.structures.trees, enabled: false },
                decorations: { ...p.structures.decorations, enabled: false },
            };
            // smoothDeco — плотность для thin-instance декораций гладкого ландшафта.
            // 0 = выключено, 1 = максимум. Считается hash-функцией в SmoothDecoManager.
            p.smoothDeco = {
                flowersDensity,
                grassDensity,
                treesDensity: smoothTreesDensity,
            };
            await onApplyRoblox({ size: robloxSize, params: p });
        } catch (e) {
            console.error('robloxApply failed:', e);
        } finally {
            robloxRef.current = false;
            setIsApplyingRoblox(false);
        }
    };
    const handleClearRoblox = () => {
        console.log('[TerrainGenPanel] handleClearRoblox CLICK; onClearRoblox=', typeof onClearRoblox);
        if (onClearRoblox) onClearRoblox();
    };

    const randomSeed = () => setSeed(Math.floor(Math.random() * 1000000));

    // === Экран выбора режима ===
    // Показывается когда genMode === null. Две карточки, объясняющие что есть что.
    if (genMode === null) {
        return (
            <div className={cl.panel}>
                <div className={cl.stickyTop}>
                    <div className={cl.header}>
                        <div className={cl.headerTitle}>Процедурный ландшафт</div>
                        <div className={cl.headerHint}>
                            Выберите тип создаваемого мира
                            {hasRobloxTerrain ? ' · Сейчас в сцене: гладкий ландшафт' : ''}
                        </div>
                    </div>
                </div>
                <div className={cl.scrollArea} style={{ padding: 10, display: 'flex', flexDirection: 'column', gap: 10 }}>
                    {/* Карточка «Воксели» ВРЕМЕННО УБРАНА — генерация воксельного
                        ландшафта сломана (битый рендер деревьев + невидимые
                        правки кистью после генерации). Будет починена позже.
                        Воксельный ландшафт пока доступен только через ручной
                        инструмент «Ландшафт» — там всё работает. */}

                    {/* Карточка: Гладкий ландшафт */}
                    <button
                        type="button"
                        onClick={() => setGenMode('smooth')}
                        style={modeCardStyle}
                    >
                        <div style={modeIconStyle}><Icon emoji="🌄" size={26} /></div>
                        <div style={{ flex: 1, textAlign: 'left' }}>
                            <div style={modeTitleStyle}>Гладкий ландшафт</div>
                            <div style={modeDescStyle}>
                                Плавные холмы для open-world игр.
                            </div>
                            <div style={modeBadgesStyle}>
                                <span style={badgeStyle('#e6a23a')}>До 600м</span>
                                <span style={badgeStyle('#3357ff')}>FPS 60+</span>
                            </div>
                        </div>
                    </button>

                    {/* Пояснение про воксельный режим */}
                    <div style={{
                        padding: '10px 12px',
                        border: '1px solid #3a3a3a',
                        borderRadius: 8,
                        background: '#1b1b1b',
                        fontSize: 12,
                        color: '#9a9a9e',
                        lineHeight: 1.5,
                    }}>
                        <Icon emoji="🟩" size={13} /> Процедурная генерация воксельного ландшафта
                        временно недоступна — чиним. Воксельный мир пока можно создать
                        вручную через инструмент «Ландшафт».
                    </div>

                    {/* Если в сцене уже есть гладкий ландшафт — кнопка очистки */}
                    {hasRobloxTerrain && (
                        <button
                            type="button"
                            onClick={handleClearRoblox}
                            style={{
                                marginTop: 4,
                                padding: '10px 14px',
                                border: '1px solid rgba(239, 68, 68, 0.4)',
                                borderRadius: 8,
                                background: 'rgba(239, 68, 68, 0.16)',
                                color: '#ff6b6b',
                                fontSize: 13,
                                fontWeight: 600,
                                cursor: 'pointer',
                            }}
                        >
                            <Icon emoji="🗑" size={13} /> Очистить текущий гладкий ландшафт
                        </button>
                    )}
                </div>
                {/* Кнопка "Назад" */}
                {onClose && (
                    <div className={cl.actions}>
                        <button type="button" className={cl.closeBtn} onClick={onClose}>
                            Закрыть
                        </button>
                    </div>
                )}
            </div>
        );
    }

    // === Экран параметров (после выбора режима) ===
    return (
        <div className={cl.panel}>
            {/* Sticky top — шапка + превью. Не скроллится при крутке секций. */}
            <div className={cl.stickyTop}>
                <div className={cl.header}>
                    <button
                        type="button"
                        onClick={() => setGenMode(null)}
                        style={{
                            background: 'transparent',
                            border: 'none',
                            color: '#aac3ff',
                            cursor: 'pointer',
                            padding: '2px 0',
                            fontSize: 12,
                            display: 'flex',
                            alignItems: 'center',
                            gap: 4,
                        }}
                    >
                        <Icon name="arrow-left" size={13} /> Назад к выбору типа
                    </button>
                    <div className={cl.headerTitle} style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                        <Icon emoji={genMode === 'smooth' ? '🌄' : '🟩'} size={15} />
                        {genMode === 'smooth' ? 'Гладкий ландшафт' : 'Воксельный ландшафт'}
                    </div>
                    <div className={cl.headerHint}>
                        {genMode === 'smooth'
                            ? 'Плавные холмы, Surface Nets, до 600м'
                            : 'Подбери параметры и нажми «Сгенерировать»'}
                    </div>
                </div>

                {/* Превью для обоих режимов — топ-вью карта биомов и высоты.
                    Smooth-режим использует те же params, превью одинаково. */}
                <div className={cl.previewWrap}>
                    <canvas
                        ref={canvasRef}
                        width={256}
                        height={256}
                        className={cl.preview}
                    />
                    {previewStats && (
                        <div className={cl.previewStats}>
                            Превью: {previewStats.time} мс · Y {previewStats.minH}…{previewStats.maxH}
                            {genMode === 'voxel'
                                ? ` · ~${previewStats.estimatedTrees} деревьев`
                                : ''}
                        </div>
                    )}
                </div>
            </div>

            {/* Скроллящаяся зона со всеми секциями параметров */}
            <div className={cl.scrollArea}>

            {genMode === 'voxel' && (<>
            <Section title="Пресеты">
                <div className={cl.presetsGrid}>
                    {Object.entries(PRESETS).map(([key, p]) => (
                        <button
                            key={key}
                            type="button"
                            className={cl.presetBtn}
                            onClick={() => applyPreset(key)}
                        >
                            {p.label}
                        </button>
                    ))}
                </div>
            </Section>

            <Section title="Основные параметры">
                <div className={cl.seedRow}>
                    <span className={cl.sliderLabel}>Seed</span>
                    <input
                        type="number"
                        value={seed}
                        onChange={(e) => setSeed(parseInt(e.target.value, 10) || 0)}
                        className={cl.seedInput}
                    />
                    <button type="button" onClick={randomSeed} className={cl.diceBtn} title="Случайный"><Icon name="dice" size={15} /></button>
                </div>
                <Slider
                    label="Размер карты"
                    value={worldSize}
                    min={40} max={200} step={20}
                    onChange={setWorldSize}
                    format={(v) => `${(v * 0.25 * 2).toFixed(0)} м`}
                />
                <div style={{ fontSize: 10, color: '#7aa3ff', padding: '2px 0' }}>
                    Лимит 100м для воксельных карт. Для больших карт выберите «Гладкий ландшафт» в начале панели.
                </div>
            </Section>

            <Section title="Рельеф (heightmap)">
                <Slider
                    label="Масштаб"
                    value={heightmap.scale}
                    min={0.005} max={0.05} step={0.001}
                    onChange={(v) => setHeightmap({ ...heightmap, scale: v })}
                    format={(v) => v.toFixed(3)}
                />
                <Slider
                    label="Амплитуда (высота)"
                    value={heightmap.amplitude}
                    min={1} max={60} step={1}
                    onChange={(v) => setHeightmap({ ...heightmap, amplitude: v })}
                    format={(v) => `${v} вокс`}
                />
                <Slider
                    label="Октавы"
                    value={heightmap.octaves}
                    min={1} max={8} step={1}
                    onChange={(v) => setHeightmap({ ...heightmap, octaves: v })}
                    format={(v) => v.toString()}
                />
                <Slider
                    label="Экспонента"
                    value={heightmap.exponent}
                    min={0.5} max={3.5} step={0.1}
                    onChange={(v) => setHeightmap({ ...heightmap, exponent: v })}
                />
                <Slider
                    label="Базовая высота"
                    value={heightmap.baseHeight}
                    min={-10} max={20} step={1}
                    onChange={(v) => setHeightmap({ ...heightmap, baseHeight: v })}
                    format={(v) => v.toString()}
                />
            </Section>

            <Section title="Деревья">
                <label className={cl.checkRow}>
                    <input
                        type="checkbox"
                        checked={treesEnabled}
                        onChange={(e) => setTreesEnabled(e.target.checked)}
                    />
                    <span>Деревья включены</span>
                </label>
                {treesEnabled && (
                    <>
                        <Slider
                            label="Плотность"
                            value={treesDensity}
                            min={0.05} max={1.5} step={0.05}
                            onChange={setTreesDensity}
                        />
                        <Slider
                            label="Размер (×базы)"
                            value={treesSizeScale}
                            min={0.5} max={2.5} step={0.1}
                            onChange={setTreesSizeScale}
                            format={(v) => `×${v.toFixed(1)}`}
                        />
                        {treesSizeScale > 2.0 && (
                            <div style={{ fontSize: 10, color: '#e69b3a', padding: '2px 0' }}>
                                <Icon name="warning" size={11} /> Очень большие деревья дают много вокселей.
                            </div>
                        )}
                    </>
                )}
            </Section>

            <Section title="Декорации">
                <Slider
                    label="Частота цветов и грибов"
                    value={flowersDensity}
                    min={0} max={0.1} step={0.005}
                    onChange={setFlowersDensity}
                    format={(v) => `${(v * 100).toFixed(1)}%`}
                />
                <Slider
                    label="Частота травы"
                    value={grassDensity}
                    min={0} max={0.5} step={0.01}
                    onChange={setGrassDensity}
                    format={(v) => `${(v * 100).toFixed(0)}%`}
                />
            </Section>
            </>)}

            {genMode === 'smooth' && (<>
            <Section title="Пресеты">
                <div className={cl.presetsGrid}>
                    {Object.entries(PRESETS).map(([key, p]) => (
                        <button
                            key={key}
                            type="button"
                            className={cl.presetBtn}
                            onClick={() => applyPreset(key)}
                        >
                            {p.label}
                        </button>
                    ))}
                </div>
            </Section>

            <Section title="Основные параметры">
                <div className={cl.seedRow}>
                    <span className={cl.sliderLabel}>Seed</span>
                    <input
                        type="number"
                        value={seed}
                        onChange={(e) => setSeed(parseInt(e.target.value, 10) || 0)}
                        className={cl.seedInput}
                    />
                    <button type="button" onClick={randomSeed} className={cl.diceBtn} title="Случайный"><Icon name="dice" size={15} /></button>
                </div>
                <Slider
                    label="Размер карты"
                    value={robloxSize}
                    min={30} max={150} step={10}
                    onChange={setRobloxSize}
                    format={(v) => `${v * 4} м`}
                />
                <div style={{ fontSize: 10, color: '#7aa3ff', padding: '2px 0' }}>
                    1 ячейка = 4м. Гладкий ландшафт поддерживает большие карты до 600м.
                </div>
            </Section>

            <Section title="Рельеф (heightmap)">
                <Slider
                    label="Масштаб"
                    value={heightmap.scale}
                    min={0.001} max={0.02} step={0.0005}
                    onChange={(v) => setHeightmap({ ...heightmap, scale: v })}
                    format={(v) => v.toFixed(4)}
                />
                <Slider
                    label="Амплитуда (высота)"
                    value={heightmap.amplitude}
                    min={5} max={120} step={5}
                    onChange={(v) => setHeightmap({ ...heightmap, amplitude: v })}
                    format={(v) => `${(v * 0.25).toFixed(1)} м`}
                />
                <Slider
                    label="Октавы"
                    value={heightmap.octaves}
                    min={1} max={8} step={1}
                    onChange={(v) => setHeightmap({ ...heightmap, octaves: v })}
                    format={(v) => v.toString()}
                />
                <Slider
                    label="Экспонента"
                    value={heightmap.exponent}
                    min={0.5} max={3.5} step={0.1}
                    onChange={(v) => setHeightmap({ ...heightmap, exponent: v })}
                />
                <Slider
                    label="Базовая высота"
                    value={heightmap.baseHeight}
                    min={-10} max={20} step={1}
                    onChange={(v) => setHeightmap({ ...heightmap, baseHeight: v })}
                    format={(v) => v.toString()}
                />
            </Section>

            <Section title={<><Icon emoji="🌳" size={14} /> Деревья</>}>
                <div style={{ fontSize: 10, color: '#7aa3ff', padding: '0 0 6px', lineHeight: 1.4 }}>
                    Лиственные деревья в лесах/равнинах, хвойные в горах,
                    пальмы на пляжах, кактусы в пустыне.
                </div>
                <Slider
                    label="Плотность"
                    value={smoothTreesDensity}
                    min={0} max={1} step={0.05}
                    onChange={setSmoothTreesDensity}
                    format={(v) => v === 0 ? 'выкл' : `${(v * 100).toFixed(0)}%`}
                />
            </Section>

            <Section title={<><Icon emoji="🌼" size={14} /> Декорации</>}>
                <div style={{ fontSize: 10, color: '#7aa3ff', padding: '0 0 6px', lineHeight: 1.4 }}>
                    3D-модели цветов, травы и грибов на поверхности.
                    Размещаются автоматически в подходящих биомах.
                </div>
                <Slider
                    label="Цветы и грибы"
                    value={flowersDensity}
                    min={0} max={0.1} step={0.005}
                    onChange={setFlowersDensity}
                    format={(v) => v === 0 ? 'выкл' : `${(v * 100).toFixed(1)}%`}
                />
                <Slider
                    label="Трава"
                    value={grassDensity}
                    min={0} max={0.5} step={0.01}
                    onChange={setGrassDensity}
                    format={(v) => v === 0 ? 'выкл' : `${(v * 100).toFixed(0)}%`}
                />
            </Section>

            <Section title={<><Icon emoji="🌄" size={14} /> Применить</>}>
                <div style={{ display: 'flex', gap: 6 }}>
                    <button
                        type="button"
                        className={cl.applyBtn}
                        onClick={handleApplyRoblox}
                        disabled={isApplyingRoblox}
                        style={{
                            flex: 1,
                            ...(isApplyingRoblox ? { opacity: 0.5, cursor: 'wait' } : null),
                        }}
                    >
                        {isApplyingRoblox ? 'Создаю…' : <><Icon emoji="🌄" size={13} /> Создать гладкий ландшафт</>}
                    </button>
                    <button
                        type="button"
                        className={cl.closeBtn}
                        onClick={handleClearRoblox}
                        disabled={isApplyingRoblox}
                        title="Очистить гладкий ландшафт"
                        style={{ minWidth: 38 }}
                    >
                        <Icon name="close" size={14} />
                    </button>
                </div>
            </Section>
            </>)}

            </div>{/* /scrollArea */}

            {/* Нижняя панель действий: для voxel — большая кнопка
                «Сгенерировать», для smooth — отдельной кнопки нет (она
                уже внутри секции). Закрытие/Назад работает всегда. */}
            <div className={cl.actions}>
                {genMode === 'voxel' && (
                    <button
                        type="button"
                        className={cl.applyBtn}
                        onClick={handleApply}
                        disabled={isGenerating}
                        style={isGenerating ? { opacity: 0.5, cursor: 'wait' } : undefined}
                    >
                        {isGenerating ? `Генерация… ${progress.pct}%` : 'Сгенерировать'}
                    </button>
                )}
                {onClose && (
                    <button
                        type="button"
                        className={cl.closeBtn}
                        onClick={onClose}
                        disabled={isGenerating || isApplyingRoblox}
                    >
                        Закрыть
                    </button>
                )}
            </div>

            {/* Full-screen прогресс-оверлей пока идёт генерация.
                Перекрывает весь viewport чтобы пользователь не пытался кликать. */}
            {progress !== null && (
                <div style={{
                    position: 'fixed',
                    inset: 0,
                    background: 'rgba(0, 0, 0, 0.55)',
                    display: 'flex',
                    flexDirection: 'column',
                    alignItems: 'center',
                    justifyContent: 'center',
                    zIndex: 9999,
                    pointerEvents: 'all',
                }}>
                    <div style={{
                        background: 'rgba(30, 32, 40, 0.95)',
                        borderRadius: 12,
                        padding: '24px 32px',
                        minWidth: 320,
                        boxShadow: '0 8px 32px rgba(0, 0, 0, 0.5)',
                        textAlign: 'center',
                    }}>
                        <div style={{ fontSize: 16, fontWeight: 600, color: '#fff', marginBottom: 14 }}>
                            Генерация ландшафта…
                        </div>
                        <div style={{ fontSize: 12, color: 'rgba(255,255,255,0.65)', marginBottom: 16 }}>
                            {progress.phase === 'heightmap' && 'Расчёт рельефа'}
                            {progress.phase === 'surface' && 'Поверхность'}
                            {progress.phase === 'trees' && 'Расстановка деревьев'}
                            {progress.phase === 'render' && 'Сборка мешей'}
                            {progress.phase === 'done' && 'Готово!'}
                            {progress.phase === 'starting' && 'Старт…'}
                        </div>
                        {/* Progress bar */}
                        <div style={{
                            width: 280,
                            height: 8,
                            background: 'rgba(255,255,255,0.12)',
                            borderRadius: 4,
                            overflow: 'hidden',
                            margin: '0 auto',
                        }}>
                            <div style={{
                                width: `${progress.pct}%`,
                                height: '100%',
                                background: 'linear-gradient(90deg, #3357FF 0%, #4a7aff 100%)',
                                transition: 'width 0.15s ease-out',
                            }} />
                        </div>
                        <div style={{ fontSize: 14, color: '#fff', marginTop: 10, fontFamily: 'monospace' }}>
                            {progress.pct}%
                        </div>
                    </div>
                </div>
            )}
        </div>
    );
}
