/**
 * SkinManagerModal — модал управления скинами проекта (задача 07).
 *
 * Здесь автор игры настраивает, какие скины доступны игрокам:
 *   - выбирает СТАРТОВЫЙ скин (default) — с него игрок начинает;
 *   - отмечает, какие скины разблокированы по умолчанию (unlocked) —
 *     их игрок носит бесплатно без покупки в магазине;
 *   - включает/выключает встроенный магазин скинов (клавиша B в Play);
 *   - задаёт стартовый баланс рубликов игрока (coins);
 *   - добавляет СВОИ скины из .glb-файлов (customGlbs) — каждый со своим
 *     масштабом (scale) и высотой бёдер (hipHeight) для правильной посадки.
 *
 * Итог сохраняется в конфиг проекта:
 *   { default, unlocked:[slug], shopVisible, coins, customGlbs:[{...}] }
 *
 * Стиль повторяет SkinShopOverlay/GameSettingsModal (тёмная тема, акцент
 * #3b6cff, шрифт Roboto Condensed). Иконки — самописные inline-SVG
 * (правило проекта: НИКОГДА не эмодзи в UI).
 *
 * Props:
 *   open          — bool, показывать ли модал (false → null);
 *   onClose()     — закрыть без сохранения;
 *   onSave(cfg)   — сохранить собранный конфиг;
 *   allSkins      — [{ id, slug, name, kind, category, price }] — полный манифест;
 *   skinsConfig   — текущая конфигурация проекта (может быть null).
 */

import React, { useState, useEffect, useMemo, useRef } from 'react';

// ---- Палитра по категориям (дубль из SkinShopOverlay, чтобы не связывать модули) ----
const CAT_THEME = {
    human:   { from: '#3b6cff', to: '#1e2da5', label: 'Люди' },
    animal:  { from: '#46b34a', to: '#1f6b2a', label: 'Животные' },
    food:    { from: '#ff8a3d', to: '#c2410c', label: 'Еда' },
    vehicle: { from: '#9b59ff', to: '#5b21b6', label: 'Транспорт' },
    robot:   { from: '#22c6d6', to: '#0e7490', label: 'Роботы' },
    custom:  { from: '#fbbf24', to: '#b45309', label: 'Свои' },
};
const CAT_ORDER = ['all', 'human', 'animal', 'food', 'vehicle', 'robot', 'custom'];

const MAX_GLB_BYTES = 4 * 1024 * 1024; // 4 МБ — потолок на кастомный .glb

// ---- Самописные SVG-иконки категорий (дубль из SkinShopOverlay) ----
function CatGlyph({ cat, size = 46 }) {
    const st = { fill: 'none', stroke: 'currentColor', strokeWidth: 1.6, strokeLinecap: 'round', strokeLinejoin: 'round' };
    let body;
    switch (cat) {
        case 'human':
            body = (<><circle cx="12" cy="7" r="3.2" {...st} /><path d="M5 21c0-4 3.2-7 7-7s7 3 7 7" {...st} /></>);
            break;
        case 'animal':
            body = (<><path d="M5 6l2.5 3M19 6l-2.5 3" {...st} /><circle cx="12" cy="13" r="7" {...st} /><circle cx="9.5" cy="12" r="0.9" fill="currentColor" stroke="none" /><circle cx="14.5" cy="12" r="0.9" fill="currentColor" stroke="none" /><path d="M10.5 16c1 0.8 2 0.8 3 0" {...st} /></>);
            break;
        case 'food':
            body = (<><circle cx="12" cy="12" r="8" {...st} /><circle cx="12" cy="12" r="2.6" {...st} /><path d="M7 8.5l0.5 1M16.5 9l-0.7 0.9M9 16l0.6-1M15.5 15.5l-0.7-0.9" {...st} /></>);
            break;
        case 'vehicle':
            body = (<><path d="M3 14l1.5-4.5A2 2 0 0 1 6.4 8h11.2a2 2 0 0 1 1.9 1.5L21 14v3h-2" {...st} /><path d="M3 14v3h2" {...st} /><circle cx="7.5" cy="17" r="1.8" {...st} /><circle cx="16.5" cy="17" r="1.8" {...st} /></>);
            break;
        case 'robot':
            body = (<><rect x="6" y="8" width="12" height="10" rx="2" {...st} /><path d="M12 8V5M9 5h6" {...st} /><circle cx="9.5" cy="13" r="1" fill="currentColor" stroke="none" /><circle cx="14.5" cy="13" r="1" fill="currentColor" stroke="none" /></>);
            break;
        default: // custom — звезда
            body = (<path d="M12 4l2.2 4.8L19 9.4l-3.6 3.3 1 5-4.4-2.5L7.6 17.7l1-5L5 9.4l4.8-0.6z" {...st} />);
    }
    return (<svg width={size} height={size} viewBox="0 0 24 24" style={{ display: 'block' }}>{body}</svg>);
}

// ---- Монета-рублик (дубль из SkinShopOverlay) ----
function CoinIcon({ size = 16 }) {
    return (
        <svg width={size} height={size} viewBox="0 0 24 24" style={{ display: 'inline-block', verticalAlign: 'middle' }}>
            <circle cx="12" cy="12" r="9" fill="#ffd24a" stroke="#a86b00" strokeWidth="1.6" />
            <text x="12" y="16" textAnchor="middle" fontSize="11" fontWeight="900" fill="#7a4d00">₽</text>
        </svg>
    );
}

// ---- Мелкие самописные иконки управления ----
function XIcon({ size = 14 }) {
    return (
        <svg width={size} height={size} viewBox="0 0 24 24" style={{ display: 'block' }}>
            <path d="M6 6l12 12M18 6L6 18" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
        </svg>
    );
}
function CheckIcon({ size = 12 }) {
    return (
        <svg width={size} height={size} viewBox="0 0 24 24" style={{ display: 'block' }}>
            <path d="M5 12.5l4.5 4.5L19 6.5" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
    );
}
function PlusIcon({ size = 14 }) {
    return (
        <svg width={size} height={size} viewBox="0 0 24 24" style={{ display: 'block' }}>
            <path d="M12 5v14M5 12h14" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" />
        </svg>
    );
}

const DEFAULT_FALLBACK = 'skin_bacon-hair';

export default function SkinManagerModal({ open, onClose, onSave, allSkins, skinsConfig }) {
    const manifest = useMemo(() => Array.isArray(allSkins) ? allSkins : [], [allSkins]);

    // ----- Локальный state конфигурации (заполняется при открытии) -----
    const [defaultSlug, setDefaultSlug] = useState(DEFAULT_FALLBACK);
    const [unlocked, setUnlocked] = useState([]);           // массив slug
    const [shopVisible, setShopVisible] = useState(true);
    const [coins, setCoins] = useState(0);
    const [customGlbs, setCustomGlbs] = useState([]);       // [{slug,name,kind,category,scale,hipHeight,dataUrl,price}]

    // ----- UI-state -----
    const [cat, setCat] = useState('all');
    const [error, setError] = useState('');

    // ----- Форма добавления кастомного скина -----
    const [draftName, setDraftName] = useState('');
    const [draftScale, setDraftScale] = useState(1.5);
    const [draftHip, setDraftHip] = useState(0.4);
    const [draftDataUrl, setDraftDataUrl] = useState('');   // dataURL выбранного .glb (ещё не добавлен)
    const [draftFileName, setDraftFileName] = useState(''); // имя файла для подсказки
    const fileInputRef = useRef(null);

    // Заполняем поля ОДИН РАЗ при открытии (паттерн как в GameSettingsModal:
    // зависимость только от [open], чтобы новый литерал-объект родителя
    // не сбрасывал состояние при каждом ре-рендере).
    useEffect(() => {
        if (!open) return;
        const cfg = skinsConfig || {};
        // дефолтный скин: из конфига → иначе первый человекоподобный → иначе фолбэк-slug
        let def = cfg.default;
        if (!def) {
            const firstHuman = manifest.find(s => (s.category || 'human') === 'human');
            def = firstHuman ? firstHuman.slug : DEFAULT_FALLBACK;
        }
        setDefaultSlug(def);
        setUnlocked(Array.isArray(cfg.unlocked) ? [...cfg.unlocked] : []);
        setShopVisible(cfg.shopVisible !== undefined ? !!cfg.shopVisible : true);
        setCoins(typeof cfg.coins === 'number' ? cfg.coins : 0);
        setCustomGlbs(Array.isArray(cfg.customGlbs) ? cfg.customGlbs.map(g => ({ ...g })) : []);
        // сброс UI/формы
        setCat('all');
        setError('');
        setDraftName('');
        setDraftScale(1.5);
        setDraftHip(0.4);
        setDraftDataUrl('');
        setDraftFileName('');
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [open]);

    // Объединённый список скинов: манифест + кастомные (custom-категория).
    const combined = useMemo(() => {
        const customCards = customGlbs.map(g => ({
            id: 'skin_' + g.slug,
            slug: g.slug,
            name: g.name,
            kind: g.kind || 'non-humanoid-mesh',
            category: 'custom',
            price: g.price || 0,
            __custom: true,
        }));
        return [...manifest, ...customCards];
    }, [manifest, customGlbs]);

    // Видимые категории (только присутствующие) для табов-фильтра.
    const cats = useMemo(() => {
        const present = new Set(combined.map(s => s.category || 'human'));
        return CAT_ORDER.filter(c => c === 'all' || present.has(c));
    }, [combined]);

    // Фильтрованная сетка.
    const visible = useMemo(() => {
        if (cat === 'all') return combined;
        return combined.filter(s => (s.category || 'human') === cat);
    }, [combined, cat]);

    if (!open) return null;

    const unlockedSet = new Set(unlocked);

    // Выбрать карточку как стартовый скин.
    const pickDefault = (slug) => {
        setDefaultSlug(slug);
    };

    // Переключить «разблокирован по умолчанию» (стартовый — всегда включён).
    const toggleUnlock = (slug) => {
        if (slug === defaultSlug) return; // стартовый нельзя снять — он всегда unlocked
        setUnlocked(prev => prev.includes(slug)
            ? prev.filter(x => x !== slug)
            : [...prev, slug]);
    };

    // Выбор .glb → читаем как dataURL, проверяем размер.
    const handleFile = (e) => {
        const file = e.target.files && e.target.files[0];
        if (!file) return;
        if (!/\.glb$/i.test(file.name)) {
            setError('Нужен файл с расширением .glb');
            return;
        }
        if (file.size > MAX_GLB_BYTES) {
            setError('Файл слишком большой (макс. 4 МБ)');
            return;
        }
        const reader = new FileReader();
        reader.onload = (ev) => {
            setDraftDataUrl(ev.target.result);
            setDraftFileName(file.name);
            // предзаполним имя из имени файла, если поле пустое
            setDraftName(prev => prev || file.name.replace(/\.glb$/i, ''));
            setError('');
        };
        reader.onerror = () => setError('Не удалось прочитать файл');
        reader.readAsDataURL(file);
    };

    // Подтвердить добавление кастомного скина в список.
    const addCustom = () => {
        if (!draftDataUrl) {
            setError('Сначала выбери .glb-файл');
            return;
        }
        const name = draftName.trim();
        if (!name) {
            setError('Введи имя скина');
            return;
        }
        const entry = {
            slug: 'custom-' + Date.now(),
            name,
            kind: 'non-humanoid-mesh',
            category: 'custom',
            scale: Math.max(0.5, Math.min(3, Number(draftScale) || 1.5)),
            hipHeight: Math.max(0, Math.min(1, Number(draftHip) || 0.4)),
            dataUrl: draftDataUrl,
            price: 0,
        };
        setCustomGlbs(prev => [...prev, entry]);
        // кастомные по умолчанию разблокированы (иначе игрок не сможет их надеть бесплатно)
        setUnlocked(prev => prev.includes(entry.slug) ? prev : [...prev, entry.slug]);
        // сброс формы
        setDraftName('');
        setDraftScale(1.5);
        setDraftHip(0.4);
        setDraftDataUrl('');
        setDraftFileName('');
        setError('');
        if (fileInputRef.current) fileInputRef.current.value = '';
    };

    // Удалить кастомный скин.
    const removeCustom = (slug) => {
        setCustomGlbs(prev => prev.filter(g => g.slug !== slug));
        setUnlocked(prev => prev.filter(x => x !== slug));
        if (defaultSlug === slug) {
            // если удалили стартовый — откатываемся на первый человекоподобный/фолбэк
            const firstHuman = manifest.find(s => (s.category || 'human') === 'human');
            setDefaultSlug(firstHuman ? firstHuman.slug : DEFAULT_FALLBACK);
        }
    };

    // Собрать и сохранить.
    const handleSave = () => {
        // гарантируем, что стартовый скин всегда в unlocked
        const finalUnlocked = unlocked.includes(defaultSlug)
            ? [...unlocked]
            : [...unlocked, defaultSlug];
        const config = {
            default: defaultSlug,
            unlocked: finalUnlocked,
            shopVisible: !!shopVisible,
            coins: Math.max(0, Math.min(100000, Number(coins) || 0)),
            customGlbs: customGlbs.map(g => ({ ...g })),
        };
        onSave && onSave(config);
        onClose && onClose();
    };

    // ====================== РЕНДЕР ======================
    return (
        <div
            style={{
                position: 'fixed', inset: 0, zIndex: 10000,
                background: 'rgba(6, 9, 20, 0.78)',
                backdropFilter: 'blur(8px)', WebkitBackdropFilter: 'blur(8px)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                padding: 20,
                fontFamily: '"Roboto Condensed", system-ui, -apple-system, sans-serif',
            }}
            onClick={(e) => { if (e.target === e.currentTarget) onClose && onClose(); }}
        >
            <div
                style={{
                    width: 'min(960px, 94vw)', maxHeight: '92vh',
                    background: 'linear-gradient(160deg, #161b2e 0%, #0c1020 100%)',
                    border: '2px solid #2b3a66', borderRadius: 20,
                    boxShadow: '0 28px 70px rgba(0,0,0,0.6)',
                    display: 'flex', flexDirection: 'column', overflow: 'hidden',
                    color: '#e8ecf8',
                }}
            >
                {/* ---------- Шапка ---------- */}
                <div style={{
                    display: 'flex', alignItems: 'center', gap: 12,
                    padding: '16px 20px',
                    borderBottom: '1px solid rgba(255,255,255,0.08)',
                    background: 'linear-gradient(90deg, rgba(59,108,255,0.20), transparent)',
                }}>
                    <div style={{ fontSize: 22, fontWeight: 900, color: '#fff', letterSpacing: 0.3 }}>
                        Скины игрока
                    </div>
                    <div style={{ flex: 1 }} />
                    <button
                        onClick={onClose}
                        title="Закрыть"
                        style={{
                            width: 34, height: 34, borderRadius: 10, cursor: 'pointer',
                            background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.16)',
                            color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center',
                        }}
                    ><XIcon size={16} /></button>
                </div>

                {/* ---------- Тело (скролл) ---------- */}
                <div style={{ display: 'flex', flexDirection: 'column', overflowY: 'auto', flex: 1, minHeight: 0 }}>

                    {/* Подсказка */}
                    <div style={{
                        padding: '12px 20px 0', color: '#8a93b4', fontSize: 13, lineHeight: 1.45,
                    }}>
                        Кликни по карточке, чтобы выбрать <b style={{ color: '#22ff88' }}>стартовый скин</b>.
                        Галочкой отметь скины, которые игрок носит бесплатно с самого начала.
                        Остальные он покупает в магазине за рублики.
                    </div>

                    {/* Табы категорий */}
                    <div style={{ display: 'flex', gap: 8, padding: '12px 20px 4px', flexWrap: 'wrap' }}>
                        {cats.map(c => {
                            const active = c === cat;
                            const label = c === 'all' ? 'Все' : (CAT_THEME[c]?.label || c);
                            return (
                                <button
                                    key={c}
                                    onClick={() => setCat(c)}
                                    style={{
                                        padding: '6px 14px', borderRadius: 999, cursor: 'pointer',
                                        fontSize: 13, fontWeight: 800,
                                        background: active ? 'linear-gradient(135deg, #3b6cff, #1e2da5)' : 'rgba(255,255,255,0.06)',
                                        border: active ? '1px solid #6b8cff' : '1px solid rgba(255,255,255,0.12)',
                                        color: active ? '#fff' : '#aab4d4',
                                        fontFamily: 'inherit',
                                    }}
                                >{label}</button>
                            );
                        })}
                    </div>

                    {/* Сетка карточек */}
                    <div style={{
                        display: 'grid',
                        gridTemplateColumns: 'repeat(auto-fill, minmax(120px, 1fr))',
                        gap: 12, padding: 20,
                    }}>
                        {visible.map(s => {
                            const theme = CAT_THEME[s.category] || CAT_THEME.human;
                            const isDefault = defaultSlug === s.slug;
                            const isUnlocked = isDefault || unlockedSet.has(s.slug);
                            const price = s.price || 0;
                            const isHuman = (s.kind || 'r15') === 'r15';
                            return (
                                <div
                                    key={s.slug}
                                    onClick={() => pickDefault(s.slug)}
                                    style={{
                                        borderRadius: 14, overflow: 'hidden', cursor: 'pointer',
                                        border: isDefault ? '3px solid #22ff88' : '2px solid rgba(255,255,255,0.10)',
                                        background: 'rgba(255,255,255,0.04)',
                                        transition: 'transform 0.1s, border-color 0.15s',
                                        position: 'relative',
                                        display: 'flex', flexDirection: 'column',
                                    }}
                                    onMouseEnter={(e) => { if (!isDefault) e.currentTarget.style.transform = 'translateY(-3px)'; }}
                                    onMouseLeave={(e) => { e.currentTarget.style.transform = 'none'; }}
                                >
                                    {/* Превью-плашка */}
                                    <div style={{
                                        height: 84, display: 'flex', alignItems: 'center', justifyContent: 'center',
                                        background: `linear-gradient(150deg, ${theme.from}, ${theme.to})`,
                                        color: 'rgba(255,255,255,0.92)', position: 'relative',
                                    }}>
                                        <CatGlyph cat={s.category || 'human'} size={44} />
                                        {/* Бейдж «Старт» */}
                                        {isDefault && (
                                            <div style={{
                                                position: 'absolute', top: 6, right: 6,
                                                background: '#22ff88', color: '#04361b',
                                                fontSize: 10, fontWeight: 900, padding: '2px 7px', borderRadius: 999,
                                                boxShadow: '0 2px 6px rgba(0,0,0,0.4)',
                                            }}>Старт</div>
                                        )}
                                        {/* Бейдж категории для не-человекоподобных */}
                                        {!isHuman && !isDefault && (
                                            <div style={{
                                                position: 'absolute', top: 6, left: 6,
                                                background: 'rgba(0,0,0,0.35)', color: '#fff',
                                                fontSize: 10, fontWeight: 800, padding: '2px 7px', borderRadius: 999,
                                            }}>{CAT_THEME[s.category]?.label || s.category}</div>
                                        )}
                                    </div>

                                    {/* Низ карточки */}
                                    <div style={{ padding: '8px 10px', display: 'flex', flexDirection: 'column', gap: 6, flex: 1 }}>
                                        <div style={{
                                            color: '#fff', fontWeight: 800, fontSize: 13,
                                            whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                                        }}>{s.name || s.slug}</div>

                                        {/* Цена (если > 0) */}
                                        {price > 0 && (
                                            <div style={{
                                                display: 'inline-flex', alignItems: 'center', gap: 4,
                                                color: '#ffd24a', fontWeight: 900, fontSize: 13,
                                            }}>
                                                <CoinIcon size={14} /> {price}
                                            </div>
                                        )}

                                        {/* Тогл «разблокирован по умолчанию» */}
                                        <label
                                            onClick={(e) => { e.stopPropagation(); }}
                                            style={{
                                                display: 'flex', alignItems: 'center', gap: 6,
                                                cursor: isDefault ? 'default' : 'pointer',
                                                marginTop: 'auto',
                                            }}
                                        >
                                            <span
                                                onClick={() => { if (!isDefault) toggleUnlock(s.slug); }}
                                                style={{
                                                    width: 16, height: 16, borderRadius: 4, flexShrink: 0,
                                                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                                                    background: isUnlocked ? (isDefault ? '#1f6b2a' : '#3b6cff') : 'transparent',
                                                    border: isUnlocked ? '1px solid transparent' : '1.5px solid rgba(255,255,255,0.3)',
                                                    color: '#fff',
                                                    opacity: isDefault ? 0.7 : 1,
                                                }}
                                            >
                                                {isUnlocked && <CheckIcon size={11} />}
                                            </span>
                                            <span style={{
                                                fontSize: 11, fontWeight: 600,
                                                color: isDefault ? '#7fe0a0' : (isUnlocked ? '#aab4d4' : '#6b76a0'),
                                            }}>
                                                {isDefault ? 'всегда включён' : 'разблокирован'}
                                            </span>
                                        </label>
                                    </div>
                                </div>
                            );
                        })}
                        {visible.length === 0 && (
                            <div style={{ color: '#8a93b4', gridColumn: '1 / -1', textAlign: 'center', padding: 30 }}>
                                В этой категории пока нет скинов
                            </div>
                        )}
                    </div>

                    {/* ---------- Настройки магазина ---------- */}
                    <div style={{
                        margin: '0 20px 16px', padding: 16, borderRadius: 14,
                        background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.08)',
                        display: 'flex', flexDirection: 'column', gap: 14,
                    }}>
                        <div style={{ fontSize: 12, fontWeight: 900, color: '#9fb0d8', textTransform: 'uppercase', letterSpacing: 0.8 }}>
                            Магазин и экономика
                        </div>

                        {/* Чекбокс магазина */}
                        <label style={{ display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer' }}>
                            <span
                                onClick={() => setShopVisible(v => !v)}
                                style={{
                                    width: 18, height: 18, borderRadius: 5, flexShrink: 0,
                                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                                    background: shopVisible ? '#3b6cff' : 'transparent',
                                    border: shopVisible ? '1px solid transparent' : '1.5px solid rgba(255,255,255,0.3)',
                                    color: '#fff',
                                }}
                            >
                                {shopVisible && <CheckIcon size={12} />}
                            </span>
                            <span>
                                <span style={{ fontWeight: 800, color: '#fff', fontSize: 14 }}>Встроенный магазин скинов</span>
                                <span style={{ display: 'block', fontSize: 12, color: '#8a93b4', marginTop: 2 }}>
                                    Игрок открывает его клавишей <b style={{ color: '#aab4d4' }}>B</b> прямо в игре
                                </span>
                            </span>
                        </label>

                        {/* Стартовые рублики */}
                        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                            <div style={{ fontSize: 11, fontWeight: 800, color: '#9fb0d8', textTransform: 'uppercase', letterSpacing: 0.8 }}>
                                Стартовые рублики игрока
                            </div>
                            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                                <CoinIcon size={18} />
                                <input
                                    type="number"
                                    min={0}
                                    max={100000}
                                    step={1}
                                    value={coins}
                                    onChange={(e) => {
                                        const v = e.target.value === '' ? 0 : Number(e.target.value);
                                        setCoins(Math.max(0, Math.min(100000, isNaN(v) ? 0 : v)));
                                    }}
                                    style={{
                                        width: 160,
                                        background: '#0c1020', border: '1.5px solid #2b3a66', borderRadius: 10,
                                        padding: '8px 12px', color: '#fff', fontSize: 14, fontFamily: 'inherit', outline: 'none',
                                    }}
                                />
                                <span style={{ fontSize: 12, color: '#6b76a0' }}>от 0 до 100000</span>
                            </div>
                        </div>
                    </div>

                    {/* ---------- Свои скины (.glb) ---------- */}
                    <div style={{
                        margin: '0 20px 20px', padding: 16, borderRadius: 14,
                        background: 'rgba(251,191,36,0.06)', border: '1px solid rgba(251,191,36,0.22)',
                        display: 'flex', flexDirection: 'column', gap: 14,
                    }}>
                        <div style={{ fontSize: 12, fontWeight: 900, color: '#fbbf24', textTransform: 'uppercase', letterSpacing: 0.8 }}>
                            Свои скины
                        </div>

                        {/* Список уже добавленных */}
                        {customGlbs.length > 0 && (
                            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                                {customGlbs.map(g => (
                                    <div key={g.slug} style={{
                                        display: 'flex', alignItems: 'center', gap: 10,
                                        padding: '8px 12px', borderRadius: 10,
                                        background: 'rgba(0,0,0,0.25)', border: '1px solid rgba(255,255,255,0.08)',
                                    }}>
                                        <div style={{ color: '#fbbf24', display: 'flex' }}><CatGlyph cat="custom" size={22} /></div>
                                        <div style={{ flex: 1, minWidth: 0 }}>
                                            <div style={{
                                                color: '#fff', fontWeight: 800, fontSize: 13,
                                                whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                                            }}>{g.name}</div>
                                            <div style={{ fontSize: 11, color: '#8a93b4' }}>
                                                масштаб {g.scale}× · высота бёдер {g.hipHeight}
                                            </div>
                                        </div>
                                        <button
                                            onClick={() => removeCustom(g.slug)}
                                            title="Удалить"
                                            style={{
                                                width: 30, height: 30, borderRadius: 8, cursor: 'pointer',
                                                background: 'rgba(239,68,68,0.16)', border: '1px solid rgba(239,68,68,0.5)',
                                                color: '#ff7a7a', display: 'flex', alignItems: 'center', justifyContent: 'center',
                                            }}
                                        ><XIcon size={14} /></button>
                                    </div>
                                ))}
                            </div>
                        )}

                        {/* Форма добавления */}
                        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                            <input
                                ref={fileInputRef}
                                type="file"
                                accept=".glb"
                                style={{ display: 'none' }}
                                onChange={handleFile}
                            />
                            <button
                                onClick={() => fileInputRef.current && fileInputRef.current.click()}
                                style={{
                                    display: 'inline-flex', alignItems: 'center', gap: 8, alignSelf: 'flex-start',
                                    padding: '9px 16px', borderRadius: 10, cursor: 'pointer',
                                    background: draftDataUrl ? 'rgba(34,255,136,0.14)' : 'rgba(255,255,255,0.06)',
                                    border: draftDataUrl ? '1px solid rgba(34,255,136,0.5)' : '1px solid rgba(255,255,255,0.16)',
                                    color: draftDataUrl ? '#7fe0a0' : '#e8ecf8',
                                    fontSize: 13, fontWeight: 800, fontFamily: 'inherit',
                                }}
                            >
                                <PlusIcon size={14} />
                                {draftDataUrl ? `Файл выбран: ${draftFileName}` : 'Выбрать свой скин (.glb)'}
                            </button>

                            {/* Поля параметров появляются после выбора файла */}
                            {draftDataUrl && (
                                <div style={{
                                    display: 'flex', flexDirection: 'column', gap: 12,
                                    padding: 12, borderRadius: 10,
                                    background: 'rgba(0,0,0,0.25)', border: '1px solid rgba(255,255,255,0.08)',
                                }}>
                                    {/* Имя */}
                                    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                                        <div style={{ fontSize: 11, fontWeight: 800, color: '#9fb0d8', textTransform: 'uppercase', letterSpacing: 0.8 }}>
                                            Имя скина
                                        </div>
                                        <input
                                            type="text"
                                            value={draftName}
                                            onChange={(e) => setDraftName(e.target.value.slice(0, 60))}
                                            placeholder="Например, Мой дракон"
                                            style={{
                                                background: '#0c1020', border: '1.5px solid #2b3a66', borderRadius: 10,
                                                padding: '8px 12px', color: '#fff', fontSize: 14, fontFamily: 'inherit', outline: 'none',
                                            }}
                                        />
                                    </div>

                                    {/* Масштаб */}
                                    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                            <span style={{ fontSize: 11, fontWeight: 800, color: '#9fb0d8', textTransform: 'uppercase', letterSpacing: 0.8 }}>
                                                Масштаб модели
                                            </span>
                                            <span style={{ fontSize: 12, color: '#ffd24a', fontWeight: 800 }}>{Number(draftScale).toFixed(2)}×</span>
                                        </div>
                                        <input
                                            type="range" min={0.5} max={3} step={0.1}
                                            value={draftScale}
                                            onChange={(e) => setDraftScale(Number(e.target.value))}
                                            style={{ width: '100%', accentColor: '#3b6cff', cursor: 'pointer' }}
                                        />
                                    </div>

                                    {/* Высота бёдер */}
                                    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                            <span style={{ fontSize: 11, fontWeight: 800, color: '#9fb0d8', textTransform: 'uppercase', letterSpacing: 0.8 }}>
                                                Высота бёдер
                                            </span>
                                            <span style={{ fontSize: 12, color: '#ffd24a', fontWeight: 800 }}>{Number(draftHip).toFixed(2)}</span>
                                        </div>
                                        <input
                                            type="range" min={0} max={1} step={0.05}
                                            value={draftHip}
                                            onChange={(e) => setDraftHip(Number(e.target.value))}
                                            style={{ width: '100%', accentColor: '#3b6cff', cursor: 'pointer' }}
                                        />
                                        <div style={{ fontSize: 11, color: '#6b76a0' }}>
                                            Насколько приподнять модель над землёй, чтобы ноги не уходили в пол.
                                        </div>
                                    </div>

                                    <button
                                        onClick={addCustom}
                                        style={{
                                            alignSelf: 'flex-start',
                                            display: 'inline-flex', alignItems: 'center', gap: 8,
                                            padding: '9px 18px', borderRadius: 10, cursor: 'pointer',
                                            background: 'linear-gradient(135deg, #fbbf24, #b45309)',
                                            border: '1px solid transparent', color: '#1a1205',
                                            fontSize: 14, fontWeight: 900, fontFamily: 'inherit',
                                        }}
                                    >
                                        <PlusIcon size={14} /> Добавить скин
                                    </button>
                                </div>
                            )}
                        </div>
                    </div>

                    {/* Ошибка */}
                    {error && (
                        <div style={{
                            margin: '0 20px 16px', padding: '10px 14px', borderRadius: 10,
                            background: 'rgba(239,68,68,0.16)', border: '1px solid rgba(239,68,68,0.4)',
                            color: '#ff9d9d', fontSize: 13, fontWeight: 700,
                        }}>{error}</div>
                    )}
                </div>

                {/* ---------- Подвал ---------- */}
                <div style={{
                    display: 'flex', justifyContent: 'flex-end', gap: 10,
                    padding: '14px 20px', borderTop: '1px solid rgba(255,255,255,0.08)',
                    background: 'rgba(0,0,0,0.25)',
                }}>
                    <button
                        onClick={onClose}
                        style={{
                            background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.16)',
                            borderRadius: 10, color: '#e8ecf8', fontSize: 14, fontWeight: 700,
                            padding: '10px 20px', cursor: 'pointer', fontFamily: 'inherit',
                        }}
                    >Отмена</button>
                    <button
                        onClick={handleSave}
                        style={{
                            background: 'linear-gradient(135deg, #3b6cff, #1e2da5)', border: '1px solid transparent',
                            borderRadius: 10, color: '#fff', fontSize: 14, fontWeight: 800,
                            padding: '10px 24px', cursor: 'pointer', fontFamily: 'inherit',
                            boxShadow: '0 6px 16px rgba(59,108,255,0.32)',
                        }}
                    >Сохранить</button>
                </div>
            </div>
        </div>
    );
}
