/**
 * GdArchesPreview — превью стартовых арок (10 эпох × 5).
 *
 * Маршрут: /admin-preview/gd-arches
 *
 * Юзер выбирает по одной арке на эпоху → POST в kubikon3d_savegame
 * (project_id=295, namespace='gd_arch_choices').
 *
 * Carousel-canvas с lazy IntersectionObserver — иначе WebGL-контексты упрутся в лимит.
 */
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 { ARCH_CATALOG, EPOCH_INFO, getArchesByEpoch } from './gdArches/archFactories';

const CHOICES_PID = 295;
const CHOICES_NS = 'gd_arch_choices';

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 ArchCard({ arch, isChosen, onChoose }) {
    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.6, 8, new Vector3(0, 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: 7, height: 4 }, scene);
            const fmat = new StandardMaterial('fmat', scene);
            fmat.diffuseColor = new Color3(0.15, 0.20, 0.18);
            floor.material = fmat;

            const handle = arch.make(scene, `prev_${arch.id}`);
            if (handle && handle.root) handle.root.position.y = 0;

            scene.onBeforeRenderObservable.add(() => {
                if (handle && handle.root) handle.root.rotation.y += 0.005;
            });
            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('[ArchCard] init failed', e); return () => {}; }
    }, [isVisible, arch]);

    return (
        <div
            ref={wrapRef}
            onClick={onChoose}
            style={{
                ...cardStyle,
                border: isChosen ? '3px solid #22ff66' : '2px solid #2a3146',
                boxShadow: isChosen ? '0 0 16px rgba(34,255,102,0.4)' : 'none',
                cursor: 'pointer',
            }}
        >
            {isVisible
                ? <canvas ref={canvasRef} style={{ width: '100%', height: 240, display: 'block', background: '#0a1020' }} />
                : <div style={{ width: '100%', height: 240, background: '#0a1020', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#444' }}>•••</div>}
            <div style={{ padding: '10px 12px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <div>
                    <div style={{ fontSize: 14, fontWeight: 700, color: '#fff', marginBottom: 2 }}>{arch.title}</div>
                    <div style={{ fontSize: 11, color: '#888' }}><code>{arch.id}</code></div>
                </div>
                {isChosen && <span style={{ color: '#22ff66', fontSize: 20 }}>✓</span>}
            </div>
        </div>
    );
}

export default function GdArchesPreview() {
    const { userRole, isLoading } = useAuth();
    const navigate = useNavigate();
    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 choose = (epoch, archId) => {
        setChoices(prev => ({ ...prev, [epoch]: archId }));
        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('[GdArchesPreview] 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 chosenCount = Object.keys(choices).length;
    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: 24, color: '#22ff66' }}>GD — Стартовые арки по эпохам ({ARCH_CATALOG.length})</h1>
                <div style={{ flex: 1, fontSize: 14, color: '#888' }}>
                    Выбрано: <span style={{ color: '#fff', fontWeight: 700 }}>{chosenCount}/10</span> эпох
                </div>
                <button onClick={save} disabled={status === 'loading' || chosenCount === 0} style={{
                    ...btnPrimary, opacity: status === 'loading' || chosenCount === 0 ? 0.5 : 1,
                }}>
                    {status === 'loading' ? '⏳ Сохраняю...' : status === 'saved' ? '✓ Сохранено' : '💾 Сохранить выбор'}
                </button>
                {status === 'error' && <span style={{ color: '#ff5566' }}>Ошибка</span>}
            </div>
            {EPOCH_INFO.map(epoch => {
                const arches = getArchesByEpoch(epoch.n);
                const chosenId = choices[epoch.n];
                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>
                            {chosenId && (
                                <span style={{ fontSize: 14, color: '#22ff66', marginLeft: 12 }}>
                                    ✓ выбран: <code>{chosenId}</code>
                                </span>
                            )}
                        </h2>
                        <div style={{
                            display: 'grid',
                            gridTemplateColumns: 'repeat(auto-fill, minmax(260px, 1fr))',
                            gap: 16,
                        }}>
                            {arches.map(arch => (
                                <ArchCard key={arch.id}
                                          arch={arch}
                                          isChosen={chosenId === arch.id}
                                          onChoose={() => choose(epoch.n, arch.id)} />
                            ))}
                        </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 };
