/**
 * GdShop — магазин скинов / цветов / трейлов для GD 2.0.
 *
 * Маршрут: /gd/shop
 * Использует:
 *   - CUBE_SKINS, CUBE_TRAILS, SKIN_COLORS из cubeSkinFactories.js
 *   - savegame API: GET/POST /kubikon3d/savegame/<project_id>/<user_id>/gd_progress
 *     (project_id=296 — канонический "L1" для GD-saveдата)
 *
 * Стейт игрока в gd_progress:
 *   - total_stars: сколько звёзд накопил
 *   - owned_skins: [id]  (например ['cube_default','cube_smile'])
 *   - owned_colors: [id]
 *   - owned_trails: [id]
 *   - equipped_skin: id   ('cube_default' по умолчанию)
 *   - equipped_color: hex (#66ff66 по умолчанию)
 *   - equipped_trail: id  ('trail_white' по умолчанию)
 */
import React, { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { jwtDecode } from 'jwt-decode';
import axios from 'axios';
import {
    CUBE_SKINS, CUBE_TRAILS, SKIN_COLORS,
} from '../admin-preview/gdSkins/cubeSkinFactories';
import { STORYS_addres } from '../api/API';
import { availableStars } from './gdStars';

function getUserId() {
    try {
        const t = localStorage.getItem('Authorization');
        if (!t) return 0;
        return Number(jwtDecode(t).id) || 0;
    } catch (e) { return 0; }
}

// Свой axios с JWT-токеном для savegame API
const api = axios.create({ baseURL: STORYS_addres, timeout: 30000 });
api.interceptors.request.use((cfg) => {
    try {
        const token = localStorage.getItem('Authorization');
        if (token) cfg.headers.Authorization = token;
    } catch (e) {}
    return cfg;
});

const GD_PROJECT_IDS = [
    296, 297, 298, 299, 300, 301, 302, 303, 304, 305,    // Эпоха I — L1-L10
    306, 350, 351, 352, 353, 354, 355, 356, 357, 358,    // Эпоха II — L11-L20
];

export default function GdShop() {
    const navigate = useNavigate();
    // progress содержит merged-данные из ВСЕХ 10 проектов:
    // level_N_passed / level_N_coin_X (read-only, нужны для подсчёта earned ⭐),
    // spent_stars, owned_*, equipped_* (изменяемые магазином).
    const [progress, setProgress] = useState(null);
    const [error, setError] = useState(null);

    useEffect(() => {
        const userId = getUserId();
        if (!userId) {
            setError('Войдите чтобы открыть магазин');
            return;
        }
        // Читаем из ВСЕХ 10 (как меню) — иначе магазин не увидит прохождений
        Promise.allSettled(GD_PROJECT_IDS.map((pid) =>
            api.get(`/kubikon3d/savegame/${pid}/${userId}/gd_progress`)
                .then((res) => res.data?.data || {})
                .catch(() => ({}))
        )).then((results) => {
            const merged = {};
            for (const r of results) {
                if (r.status === 'fulfilled' && r.value) Object.assign(merged, r.value);
            }
            // Гарантируем дефолты для shop-полей
            setProgress({
                ...merged,
                spent_stars: Number(merged.spent_stars) || 0,
                owned_skins: merged.owned_skins || ['cube_default'],
                owned_colors: merged.owned_colors || ['green'],
                owned_trails: merged.owned_trails || ['trail_white'],
                equipped_skin: merged.equipped_skin || 'cube_default',
                equipped_color: merged.equipped_color || '#66ff66',
                equipped_trail: merged.equipped_trail || 'trail_white',
            });
        });
    }, []);

    /** Сохранить ТОЛЬКО shop-поля во все 10 pid через merge с patch
     *  (НЕ перезаписываем весь объект — иначе level_N_passed специфичные для pid сотрутся). */
    const saveShopFields = (next) => {
        const userId = getUserId();
        if (!userId) return;
        setProgress(next);
        const shopPatch = {
            spent_stars: next.spent_stars,
            owned_skins: next.owned_skins,
            owned_colors: next.owned_colors,
            owned_trails: next.owned_trails,
            equipped_skin: next.equipped_skin,
            equipped_color: next.equipped_color,
            equipped_trail: next.equipped_trail,
        };
        for (const pid of GD_PROJECT_IDS) {
            // /merge эндпоинт: { patch: {...} } — точечно обновит ключи, не затрёт level_N_*
            api.post(`/kubikon3d/savegame/${pid}/${userId}/gd_progress/merge`, {
                patch: shopPatch,
            }).catch((e) => console.warn('[GdShop] save failed pid=' + pid, e));
        }
    };

    const buy = (kind, item, price) => {
        if (!progress) return;
        const avail = availableStars(progress);
        if (avail < price) {
            alert(`Не хватает звёзд (нужно ${price}, есть ${avail})`);
            return;
        }
        const ownedField = `owned_${kind}s`;   // skins / colors / trails
        if (progress[ownedField].includes(item.id)) return;   // уже куплено
        saveShopFields({
            ...progress,
            spent_stars: (progress.spent_stars || 0) + price,
            [ownedField]: [...progress[ownedField], item.id],
        });
    };

    const equip = (kind, item) => {
        if (!progress) return;
        const field = kind === 'color' ? 'equipped_color' : `equipped_${kind}`;
        const value = kind === 'color' ? item.hex : item.id;
        saveShopFields({ ...progress, [field]: value });
    };

    if (error) return <CenteredCard text={error} onBack={() => navigate('/gd')} />;
    if (!progress) return <CenteredCard text="Загрузка..." />;

    return (
        <div style={{
            minHeight: '100vh', background: '#070a14', color: '#fff',
            padding: '20px 24px', fontFamily: 'system-ui, -apple-system, sans-serif',
        }}>
            <Header
                stars={availableStars(progress)}
                onBack={() => navigate('/gd')}
            />

            <Section title="🎨 Скины куба (10)">
                <Grid>
                    {CUBE_SKINS.map((s) => (
                        <SkinCard
                            key={s.id}
                            item={s}
                            owned={progress.owned_skins.includes(s.id)}
                            equipped={progress.equipped_skin === s.id}
                            primaryHex={progress.equipped_color}
                            stars={availableStars(progress)}
                            onBuy={() => buy('skin', s, s.priceStars)}
                            onEquip={() => equip('skin', s)}
                        />
                    ))}
                </Grid>
            </Section>

            <Section title="🎨 Цвета (13)">
                <Grid>
                    {SKIN_COLORS.map((c) => (
                        <ColorCard
                            key={c.id}
                            item={c}
                            owned={progress.owned_colors.includes(c.id)}
                            equipped={progress.equipped_color === c.hex}
                            stars={availableStars(progress)}
                            onBuy={() => buy('color', c, c.priceStars)}
                            onEquip={() => equip('color', c)}
                        />
                    ))}
                </Grid>
            </Section>

            <Section title="✨ Trail-эффекты (3)">
                <Grid>
                    {CUBE_TRAILS.map((t) => (
                        <TrailCard
                            key={t.id}
                            item={t}
                            owned={progress.owned_trails.includes(t.id)}
                            equipped={progress.equipped_trail === t.id}
                            stars={availableStars(progress)}
                            onBuy={() => buy('trail', t, t.priceStars)}
                            onEquip={() => equip('trail', t)}
                        />
                    ))}
                </Grid>
            </Section>
        </div>
    );
}

function Header({ stars, onBack }) {
    return (
        <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 24 }}>
            <button onClick={onBack} style={btnSecondary}>← Назад в меню GD</button>
            <h1 style={{ margin: 0, fontSize: 28, color: '#22ff66', flex: 1 }}>🛒 Магазин GD 2.0</h1>
            <div style={{ fontSize: 22, color: '#ffe44a', fontWeight: 700 }}>
                ⭐ {stars}
            </div>
        </div>
    );
}

function Section({ title, children }) {
    return (
        <div style={{ marginBottom: 32 }}>
            <h2 style={{ fontSize: 20, color: '#cdd4e0', borderBottom: '2px solid #2a3146', paddingBottom: 8, marginBottom: 16 }}>
                {title}
            </h2>
            {children}
        </div>
    );
}

function Grid({ children }) {
    return (
        <div style={{
            display: 'grid',
            gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))',
            gap: 16,
        }}>
            {children}
        </div>
    );
}

function SkinPreview({ skin, primary, size = 128 }) {
    const ref = useRef(null);
    useEffect(() => {
        const canvas = ref.current;
        if (!canvas || !skin?.draw) return;
        const ctx = canvas.getContext('2d');
        // Рисуем на 256 как фабрика, потом scale в canvas
        const tempCanvas = document.createElement('canvas');
        tempCanvas.width = 256; tempCanvas.height = 256;
        const tempCtx = tempCanvas.getContext('2d');
        try {
            skin.draw(tempCtx, primary || '#66ff66', '#222', 0);
        } catch (e) {}
        ctx.imageSmoothingEnabled = false;
        ctx.clearRect(0, 0, size, size);
        ctx.drawImage(tempCanvas, 0, 0, size, size);
    }, [skin, primary, size]);
    return <canvas ref={ref} width={size} height={size} style={{ width: size, height: size, imageRendering: 'pixelated', borderRadius: 8 }} />;
}

function SkinCard({ item, owned, equipped, primaryHex, stars, onBuy, onEquip }) {
    return (
        <div style={cardStyle(equipped)}>
            <SkinPreview skin={item} primary={primaryHex} size={120} />
            <div style={{ fontWeight: 600, marginTop: 8, fontSize: 14 }}>{item.title}</div>
            <div style={{ fontSize: 11, color: '#888' }}>{item.category}</div>
            <ActionButton owned={owned} equipped={equipped} price={item.priceStars} canAfford={stars >= item.priceStars} onBuy={onBuy} onEquip={onEquip} />
        </div>
    );
}

function ColorCard({ item, owned, equipped, stars, onBuy, onEquip }) {
    return (
        <div style={cardStyle(equipped)}>
            <div style={{
                width: 120, height: 120, background: item.hex,
                borderRadius: 8, border: equipped ? '4px solid #22ff66' : '2px solid #444',
            }} />
            <div style={{ fontWeight: 600, marginTop: 8, fontSize: 14 }}>{item.title}</div>
            <div style={{ fontSize: 11, color: '#888' }}>{item.hex}</div>
            <ActionButton owned={owned} equipped={equipped} price={item.priceStars} canAfford={stars >= item.priceStars} onBuy={onBuy} onEquip={onEquip} />
        </div>
    );
}

function TrailCard({ item, owned, equipped, stars, onBuy, onEquip }) {
    const p = item.params;
    return (
        <div style={cardStyle(equipped)}>
            <div style={{
                width: 120, height: 120, borderRadius: 8,
                background: `linear-gradient(135deg, ${p.colorStart || '#fff'} 0%, ${p.colorEnd || '#888'} 100%)`,
                display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 40,
                border: equipped ? '4px solid #22ff66' : '2px solid #444',
            }}>✨</div>
            <div style={{ fontWeight: 600, marginTop: 8, fontSize: 14 }}>{item.title}</div>
            <ActionButton owned={owned} equipped={equipped} price={item.priceStars} canAfford={stars >= item.priceStars} onBuy={onBuy} onEquip={onEquip} />
        </div>
    );
}

function ActionButton({ owned, equipped, price, canAfford, onBuy, onEquip }) {
    if (equipped) {
        return <div style={{ ...btn, background: '#22ff66', color: '#000', cursor: 'default' }}>✓ Активен</div>;
    }
    if (owned) {
        return <button onClick={onEquip} style={{ ...btn, background: '#3a4156', color: '#fff' }}>Применить</button>;
    }
    if (price === 0) {
        return <button onClick={onBuy} style={{ ...btn, background: '#22aa66', color: '#fff' }}>Бесплатно</button>;
    }
    return (
        <button onClick={onBuy} disabled={!canAfford} style={{
            ...btn,
            background: canAfford ? '#ffe44a' : '#444',
            color: canAfford ? '#000' : '#888',
            cursor: canAfford ? 'pointer' : 'not-allowed',
        }}>
            ⭐ {price}
        </button>
    );
}

function CenteredCard({ text, onBack }) {
    return (
        <div style={{ minHeight: '100vh', background: '#070a14', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', gap: 16 }}>
            <div style={{ fontSize: 22 }}>{text}</div>
            {onBack && <button onClick={onBack} style={btnSecondary}>← Назад</button>}
        </div>
    );
}

// ===== Стили =====
const btn = {
    marginTop: 8, padding: '8px 12px', border: 'none', borderRadius: 6,
    fontWeight: 700, fontSize: 14, width: '100%', textAlign: 'center',
};
const btnSecondary = {
    padding: '8px 16px', background: '#2a3146', color: '#cdd4e0',
    border: 'none', borderRadius: 6, cursor: 'pointer', fontWeight: 600, fontSize: 14,
};
const cardStyle = (equipped) => ({
    padding: 12, background: '#0e1525', borderRadius: 10,
    border: equipped ? '2px solid #22ff66' : '2px solid #1a2238',
    display: 'flex', flexDirection: 'column', alignItems: 'center',
});
