/**
 * GdDecoPreview — превью декораций ландшафта (10 эпох × 10 = 100).
 * Маршрут: /admin-preview/gd-deco
 * Multi-select: до 5 моделей на эпоху. Выбор → kubikon3d_savegame
 * (project_id=295, namespace='gd_deco_choices'). data = { 1: ['d1_v1','d1_v3',...] }.
 */
import React, { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../auth/AuthContext.jsx';
import { jwtDecode } from 'jwt-decode';
import axios from 'axios';
import { STORYS_addres } from '../api/API';

import { Engine } from '@babylonjs/core/Engines/engine';
import { Scene } from '@babylonjs/core/scene';
import { ArcRotateCamera } from '@babylonjs/core/Cameras/arcRotateCamera';
import { HemisphericLight } from '@babylonjs/core/Lights/hemisphericLight';
import { DirectionalLight } from '@babylonjs/core/Lights/directionalLight';
import { Vector3, Color3, Color4 } from '@babylonjs/core/Maths/math';
import { MeshBuilder } from '@babylonjs/core/Meshes/meshBuilder';
import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';

import { DECO_CATALOG, EPOCH_INFO, getDecoByEpoch } from './gdDeco/decoFactories';

const CHOICES_PID = 295;
const CHOICES_NS = 'gd_deco_choices';
const MAX_PER_EPOCH = 5;

function getUserId() {
    try { const t = localStorage.getItem('Authorization'); if (!t) return 0; return Number(jwtDecode(t).id) || 0; } catch (e) { return 0; }
}
const api = axios.create({ baseURL: STORYS_addres, timeout: 15000 });
api.interceptors.request.use((cfg) => {
    try { const token = localStorage.getItem('Authorization'); if (token) cfg.headers.Authorization = token; } catch (e) {}
    return cfg;
});

function DecoCard({ deco, isChosen, onToggle, disabled }) {
    const wrapRef = useRef(null);
    const canvasRef = useRef(null);
    const [isVisible, setIsVisible] = useState(false);
    useEffect(() => {
        if (!wrapRef.current) return;
        const io = new IntersectionObserver((entries) => {
            for (const e of entries) setIsVisible(e.isIntersecting);
        }, { rootMargin: '200px', threshold: 0.01 });
        io.observe(wrapRef.current);
        return () => io.disconnect();
    }, []);
    useEffect(() => {
        if (!isVisible || !canvasRef.current) return;
        let engine = null, scene = null;
        try {
            engine = new Engine(canvasRef.current, true, { stencil: false, antialias: true });
            scene = new Scene(engine);
            scene.clearColor = new Color4(0.05, 0.07, 0.12, 1);
            const camera = new ArcRotateCamera('cam', -Math.PI / 2.5, Math.PI / 2.7, 5, new Vector3(0, 1.2, 0), scene);
            camera.attachControl(canvasRef.current, false);
            camera.minZ = 0.1; camera.maxZ = 50;
            new HemisphericLight('hemi', new Vector3(0, 1, 0), scene).intensity = 0.7;
            const sun = new DirectionalLight('sun', new Vector3(-0.5, -1, -0.3), scene);
            sun.intensity = 0.8;
            const floor = MeshBuilder.CreateGround('floor', { width: 4, height: 4 }, scene);
            const fmat = new StandardMaterial('fmat', scene);
            fmat.diffuseColor = new Color3(0.18, 0.22, 0.20);
            floor.material = fmat;
            const handle = deco.make(scene, `prev_${deco.id}`);
            if (handle && handle.root) handle.root.position.y = 0;
            scene.onBeforeRenderObservable.add(() => {
                if (handle && handle.root) handle.root.rotation.y += 0.008;
            });
            engine.runRenderLoop(() => scene.render());
            return () => {
                try { engine && engine.stopRenderLoop(); } catch (e) {}
                try { handle && handle.dispose && handle.dispose(); } catch (e) {}
                try { scene && scene.dispose(); } catch (e) {}
                try { engine && engine.dispose(); } catch (e) {}
            };
        } catch (e) { console.warn('[DecoCard]', e); return () => {}; }
    }, [isVisible, deco]);

    return (
        <div
            ref={wrapRef}
            onClick={() => { if (!disabled || isChosen) onToggle(); }}
            style={{
                ...cardStyle,
                border: isChosen ? '3px solid #22ff66' : '2px solid #2a3146',
                boxShadow: isChosen ? '0 0 16px rgba(34,255,102,0.4)' : 'none',
                cursor: disabled && !isChosen ? 'not-allowed' : 'pointer',
                opacity: disabled && !isChosen ? 0.45 : 1,
            }}
        >
            {isVisible
                ? <canvas ref={canvasRef} style={{ width: '100%', height: 200, display: 'block', background: '#0a1020' }} />
                : <div style={{ width: '100%', height: 200, background: '#0a1020', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#444' }}>•••</div>}
            <div style={{ padding: '8px 12px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <div>
                    <div style={{ fontSize: 13, fontWeight: 700, color: '#fff' }}>{deco.title}</div>
                    <div style={{ fontSize: 11, color: '#888' }}><code>{deco.id}</code></div>
                </div>
                {isChosen && <span style={{ color: '#22ff66', fontSize: 20 }}>✓</span>}
            </div>
        </div>
    );
}

export default function GdDecoPreview() {
    const { userRole, isLoading } = useAuth();
    const navigate = useNavigate();
    // choices: { '1': ['d1_v1','d1_v4',...], '2': [...], ... }
    const [choices, setChoices] = useState({});
    const [status, setStatus] = useState('idle');

    useEffect(() => {
        const uid = getUserId();
        if (!uid) return;
        api.get(`/kubikon3d/savegame/${CHOICES_PID}/${uid}/${CHOICES_NS}`)
            .then((r) => setChoices(r.data?.data || {}))
            .catch(() => {});
    }, []);

    const toggle = (epoch, decoId) => {
        setChoices(prev => {
            const arr = prev[epoch] || [];
            const has = arr.includes(decoId);
            let next;
            if (has) {
                next = arr.filter(x => x !== decoId);
            } else {
                if (arr.length >= MAX_PER_EPOCH) return prev;
                next = [...arr, decoId];
            }
            return { ...prev, [epoch]: next };
        });
        setStatus('idle');
    };

    const save = async () => {
        const uid = getUserId();
        if (!uid) { setStatus('error'); return; }
        setStatus('loading');
        try {
            await api.post(`/kubikon3d/savegame/${CHOICES_PID}/${uid}/${CHOICES_NS}`, { data: choices });
            setStatus('saved');
        } catch (e) { console.warn('[GdDecoPreview] save failed', e); setStatus('error'); }
    };

    if (isLoading) return <div style={{ padding: 24, color: '#fff' }}>Загрузка...</div>;
    if (userRole !== 'admin') {
        return (
            <div style={{ padding: 24, color: '#fff', background: '#070a14', minHeight: '100vh' }}>
                <h2>Доступ только для администратора</h2>
                <button onClick={() => navigate('/')} style={btnStyle}>На главную</button>
            </div>
        );
    }

    const totalChosen = Object.values(choices).reduce((s, arr) => s + (arr?.length || 0), 0);

    return (
        <div style={{ minHeight: '100vh', background: '#070a14', color: '#fff', padding: '20px 24px' }}>
            <div style={{
                position: 'sticky', top: 0, background: '#070a14', zIndex: 10,
                padding: '12px 0', marginBottom: 16, borderBottom: '1px solid #2a3146',
                display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap',
            }}>
                <button onClick={() => navigate('/')} style={btnStyle}>← Назад</button>
                <h1 style={{ margin: 0, fontSize: 22, color: '#22ff66' }}>GD — Декорации ландшафта ({DECO_CATALOG.length})</h1>
                <div style={{ flex: 1, fontSize: 14, color: '#888' }}>
                    Выбрано: <span style={{ color: '#fff', fontWeight: 700 }}>{totalChosen}</span> (до 5 на эпоху)
                </div>
                <button onClick={save} disabled={status === 'loading' || totalChosen === 0} style={{
                    ...btnPrimary, opacity: status === 'loading' || totalChosen === 0 ? 0.5 : 1,
                }}>
                    {status === 'loading' ? '⏳ Сохраняю...' : status === 'saved' ? '✓ Сохранено' : '💾 Сохранить выбор'}
                </button>
                {status === 'error' && <span style={{ color: '#ff5566' }}>Ошибка</span>}
            </div>
            {EPOCH_INFO.map(epoch => {
                const items = getDecoByEpoch(epoch.n);
                const arr = choices[epoch.n] || [];
                const fullyChosen = arr.length >= MAX_PER_EPOCH;
                return (
                    <div key={epoch.n} style={{ marginBottom: 32 }}>
                        <h2 style={{ fontSize: 22, color: epoch.color, marginBottom: 12, borderBottom: `2px solid ${epoch.color}33`, paddingBottom: 8 }}>
                            {epoch.emoji} Эпоха {epoch.n} — {epoch.name}
                            <span style={{ fontSize: 14, color: '#666', marginLeft: 12 }}>L{(epoch.n - 1) * 10 + 1} – L{epoch.n * 10}</span>
                            <span style={{ fontSize: 14, color: fullyChosen ? '#22ff66' : '#888', marginLeft: 12 }}>
                                выбрано {arr.length}/{MAX_PER_EPOCH}
                            </span>
                        </h2>
                        <div style={{
                            display: 'grid',
                            gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))',
                            gap: 16,
                        }}>
                            {items.map(deco => (
                                <DecoCard
                                    key={deco.id}
                                    deco={deco}
                                    isChosen={arr.includes(deco.id)}
                                    onToggle={() => toggle(epoch.n, deco.id)}
                                    disabled={fullyChosen}
                                />
                            ))}
                        </div>
                    </div>
                );
            })}
        </div>
    );
}

const cardStyle = { background: '#0e1525', borderRadius: 10, overflow: 'hidden', transition: 'all 0.15s' };
const btnStyle = { padding: '10px 18px', background: '#2a3146', color: '#cdd4e0', border: 'none', borderRadius: 8, cursor: 'pointer', fontWeight: 600, fontSize: 14 };
const btnPrimary = { padding: '10px 24px', background: 'linear-gradient(135deg, #22ff66, #44aaff)', color: '#000', border: 'none', borderRadius: 8, cursor: 'pointer', fontWeight: 700, fontSize: 15 };
