// ============================================
// AVATAR CATALOG — admin tool pra cadastrar/editar skins de avatar
// ============================================
// Edita em memória (window.MastershotData.AVATARS); botões "Exportar
// manifest.json" (cola em assets/avatars/manifest.json) e "Exportar SQL seed"
// (cola na migration do shop_catalog). O BINÁRIO (model.glb/.fbx + thumb.png)
// entra por commit em assets/avatars/<id>/ — assets/ é estático em produção.
// Reusa o componente global <Field> definido em cueCatalog.jsx.

function AvatarCatalogScreen({ navigate }) {
    const [list, setList] = React.useState(() => [...(window.MastershotData?.AVATARS || [])]);
    const [editing, setEditing] = React.useState(null);   // null | "new" | {avatar}
    React.useEffect(() => {
        const h = () => setList([...(window.MastershotData?.AVATARS || [])]);
        window.addEventListener("mastershot:avatars-ready", h);
        return () => window.removeEventListener("mastershot:avatars-ready", h);
    }, []);

    function commitList(next) {
        setList(next);
        if (window.MastershotData) window.MastershotData.AVATARS = next;
    }
    function saveAvatar(av) {
        const isNew = editing === "new";
        if (isNew && list.some(a => a.id === av.id)) { window.MastershotAlert(window.t('Já existe avatar com id "{id}".', { id: av.id })); return; }
        commitList(isNew ? [...list, av] : list.map(a => a.id === editing.id ? av : a));
        setEditing(null);
    }
    async function removeAvatar(id) {
        if (!(await window.MastershotConfirm({ title: window.t('Excluir avatar'), message: window.t('Excluir avatar "{id}"? (não apaga os arquivos em assets/)', { id }), confirmLabel: window.t('Excluir'), danger: true }))) return;
        commitList(list.filter(a => a.id !== id));
    }

    // Reconstrói a forma do MANIFESTO a partir do item normalizado.
    function toManifestEntry(a) {
        return {
            id: a.id, name: a.name, tier: a.tier || "Padrão", gender: a.gender || "u",
            unlock: a.unlock || { type: "level", value: 1 },
            price: a.price || 0, chips: a.chips || 0,
            starter: !!a.starter, owned: !!a.owned || !!a.starter,
            model: a.model, thumb: a.thumb || a.skin,
            targetHeight: a.targetHeight || 1.62, useGLB: a.useGLB !== false,
            cueGripSide: a.cueGripSide ?? -1, bridgeHand: a.bridgeHand || "left",
            ...(a.hairColor ? { hairColor: a.hairColor } : {}),
            ...(a.colors ? { colors: a.colors } : {}),
            customizable: a.customizable || {},
        };
    }
    function exportManifest() {
        const json = JSON.stringify({ version: 1, skins: list.map(toManifestEntry) }, null, 2);
        try { navigator.clipboard.writeText(json); window.MastershotAlert(window.t("manifest.json ({n} skins) copiado.\nCole em assets/avatars/manifest.json.", { n: list.length })); }
        catch { window.prompt(window.t("Copie manualmente:"), json); }
    }
    function exportSql() {
        const rows = list.map(a => {
            const lvl = a.unlock?.type === "level" ? (a.unlock.value || 1) : 1;
            const coins = a.unlock?.type === "coins" ? (a.unlock.value || a.price || 0) : 0;
            const chips = a.unlock?.type === "chips" ? (a.unlock.value || a.chips || 0) : 0;
            return `  ('avatar','${a.id}',${coins},${chips},${lvl},${a.starter ? "true" : "false"},true)`;
        }).join(",\n");
        const sql = `INSERT INTO shop_catalog (item_type,item_id,price_coins,price_chips,min_level,starter,active) VALUES\n${rows}\nON CONFLICT (item_type,item_id) DO UPDATE SET\n  price_coins=EXCLUDED.price_coins, price_chips=EXCLUDED.price_chips,\n  min_level=EXCLUDED.min_level, starter=EXCLUDED.starter, active=EXCLUDED.active;`;
        try { navigator.clipboard.writeText(sql); window.MastershotAlert(window.t("SQL seed copiado.\nCole numa migration do shop_catalog.")); }
        catch { window.prompt(window.t("Copie manualmente:"), sql); }
    }

    if (editing) {
        return <AvatarEditor initial={editing === "new" ? null : editing} onSave={saveAvatar} onCancel={() => setEditing(null)}/>;
    }

    return (
        <div className="screen active" style={{ opacity: 1 }}>
            <AmbientBackdrop/><TopBar navigate={navigate}/>
            <div style={{ position: "absolute", top: 88, left: 48, zIndex: 20 }}>
                <button className="back-btn" onClick={() => navigate("admin")}>
                    <span dangerouslySetInnerHTML={{ __html: window.Icon.back(14) }}/><span>{window.t("Admin")}</span>
                </button>
            </div>
            <div style={{ position: "relative", zIndex: 5, paddingTop: 110, paddingBottom: 32, paddingLeft: 48, paddingRight: 48, maxWidth: 1400, margin: "0 auto", height: "100%", display: "flex", flexDirection: "column", gap: 16 }}>
                <div className="panel cc-header" style={{ padding: 24, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                    <div>
                        <div style={{ fontFamily: "var(--font-display)", fontSize: 26, color: "var(--gold-300)", fontWeight: 700 }}>{window.t("Catálogo de Avatares")}</div>
                        <div style={{ fontSize: 12, color: "var(--ink-300)", marginTop: 4, maxWidth: 760 }}>
                            {window.t("Cadastra/edita skins. Os arquivos (model.glb/.fbx + thumb.png) ficam em assets/avatars/<id>/ e entram por commit. Aqui você edita os metadados e exporta o manifest.json (e o SQL do shop).")}
                        </div>
                    </div>
                    <div className="cc-actions" style={{ display: "flex", gap: 10 }}>
                        <button className="btn-secondary" onClick={exportSql}>{window.t("Exportar SQL")}</button>
                        <button className="btn-secondary" onClick={exportManifest}>{window.t("Exportar manifest.json")}</button>
                        <button className="btn-primary" onClick={() => setEditing("new")}>{window.t("+ Adicionar Avatar")}</button>
                    </div>
                </div>
                <div className="cc-table-wrap" style={{ flex: 1, minHeight: 0, overflowY: "auto", paddingRight: 8 }}>
                    <div className="cc-table-head" style={{ display: "grid", gridTemplateColumns: "80px 1fr 100px 80px 140px 100px", gap: 10, padding: "8px 14px", fontSize: 10, fontWeight: 600, letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--ink-400)" }}>
                        <div>{window.t("Preview")}</div><div>{window.t("Nome / ID")}</div><div>{window.t("Tier")}</div><div>{window.t("Gênero")}</div><div>{window.t("Unlock")}</div><div>{window.t("Ações")}</div>
                    </div>
                    {list.map(a => <AvatarRow key={a.id} avatar={a} onEdit={() => setEditing(a)} onDelete={() => removeAvatar(a.id)}/>)}
                    {list.length === 0 && (
                        <div className="panel" style={{ padding: 24, textAlign: "center", color: "var(--ink-400)" }}>
                            {window.t("Nenhuma skin no manifesto ainda.")}
                        </div>
                    )}
                </div>
            </div>
            <style>{`
                @media (max-width: 768px) {
                    .cc-header { flex-wrap: wrap !important; gap: 14px !important; padding: 16px !important; }
                    .cc-actions { flex-wrap: wrap !important; }
                    .cc-table-wrap { overflow-x: auto !important; padding-right: 0 !important; }
                    .cc-table-head, .cc-row { min-width: 600px; }
                }
            `}</style>
        </div>
    );
}

function AvatarRow({ avatar, onEdit, onDelete }) {
    return (
        <div className="panel cc-row" style={{ display: "grid", gridTemplateColumns: "80px 1fr 100px 80px 140px 100px", gap: 10, padding: "10px 14px", alignItems: "center", marginBottom: 6 }}>
            <div style={{ height: 64, background: "var(--ink-900)", border: "1px solid var(--ink-700)", borderRadius: 4, padding: 2, display: "flex", alignItems: "center", justifyContent: "center", overflow: "hidden" }}>
                {avatar.thumb
                    ? <img src={avatar.thumb} alt={avatar.name} style={{ maxWidth: "100%", maxHeight: "100%", objectFit: "contain" }}/>
                    : <span style={{ fontSize: 9, color: "var(--ink-500)" }}>{window.t("sem thumb")}</span>}
            </div>
            <div>
                <div style={{ fontSize: 13, color: "var(--ink-100)", fontWeight: 600 }}>{avatar.name}</div>
                <div style={{ fontSize: 10, color: "var(--ink-400)", fontFamily: "var(--font-mono)" }}>{avatar.id}</div>
            </div>
            <div style={{ fontSize: 11, color: "var(--gold-400)" }}>{avatar.tier || "—"}</div>
            <div style={{ fontSize: 11, color: "var(--ink-200)" }}>{avatar.gender === "m" ? "M" : avatar.gender === "f" ? "F" : "U"}</div>
            <div style={{ fontSize: 11, color: "var(--ink-200)" }}>
                {avatar.unlock?.type === "level" && window.t("Nv. {n}", { n: avatar.unlock.value })}
                {avatar.unlock?.type === "coins" && `$ ${avatar.unlock.value?.toLocaleString?.() || avatar.price}`}
                {avatar.unlock?.type === "chips" && `💎 ${avatar.unlock.value}`}
            </div>
            <div style={{ display: "flex", gap: 6 }}>
                <button className="btn-secondary" style={{ fontSize: 10, padding: "4px 8px" }} onClick={onEdit}>{window.t("Editar")}</button>
                <button className="btn-secondary" style={{ fontSize: 10, padding: "4px 8px", color: "var(--loss-bright)" }} onClick={onDelete}>×</button>
            </div>
        </div>
    );
}

function AvatarEditor({ initial, onSave, onCancel }) {
    const [form, setForm] = React.useState(() => {
        const base = initial ? { ...initial } : {
            id: "", name: "", gender: "m", tier: "Padrão",
            model: "", thumb: "", unlock: { type: "level", value: 1 },
            price: 0, chips: 0, starter: false, targetHeight: 1.62, useGLB: true,
            cueGripSide: -1, bridgeHand: "left", hairColor: "",
        };
        base.colorShirt = base.colors?.shirt || "";   // recolor de peças (roupas)
        base.colorPants = base.colors?.pants || "";
        base.colorShoes = base.colors?.shoes || "";
        return base;
    });
    function set(patch) { setForm(f => ({ ...f, ...patch })); }
    function setUnlock(patch) { setForm(f => ({ ...f, unlock: { ...f.unlock, ...patch } })); }

    // Auto-deriva os paths a partir do id (convenção assets/avatars/<id>/).
    React.useEffect(() => {
        if (form.id && !form.model) set({ model: `assets/avatars/${form.id}/model.glb` });
        if (form.id && !form.thumb) set({ thumb: `assets/avatars/${form.id}/thumb.png` });
    }, [form.id]);

    function submit(e) {
        e.preventDefault();
        if (!form.id.trim()) { window.MastershotAlert(window.t("ID obrigatório.")); return; }
        if (!form.name.trim()) { window.MastershotAlert(window.t("Nome obrigatório.")); return; }
        if (/[+\s]/.test(form.id)) { window.MastershotAlert(window.t("ID não pode ter '+' nem espaço (a URL decodifica).")); return; }
        const colors = {};
        if (form.colorShirt) colors.shirt = form.colorShirt;
        if (form.colorPants) colors.pants = form.colorPants;
        if (form.colorShoes) colors.shoes = form.colorShoes;
        const out = {
            ...form, id: form.id.trim(), name: form.name.trim(),
            skin: form.thumb, owned: !!form.starter,
            price: form.unlock?.type === "coins" ? (form.unlock.value || form.price || 0) : (form.price || 0),
            chips: form.unlock?.type === "chips" ? (form.unlock.value || form.chips || 0) : (form.chips || 0),
            hairColor: form.hairColor ? form.hairColor : null,
            colors: Object.keys(colors).length ? colors : null,
        };
        onSave(out);
    }

    return (
        <div className="screen active" style={{ opacity: 1 }}>
            <AmbientBackdrop/><TopBar navigate={() => {}}/>
            <div className="cc-editor-wrap" style={{ position: "relative", zIndex: 5, paddingTop: 110, paddingLeft: 48, paddingRight: 48, maxWidth: 920, margin: "0 auto", display: "flex", flexDirection: "column", gap: 16 }}>
                <div className="panel cc-editor-panel" style={{ padding: 24 }}>
                    <div style={{ fontFamily: "var(--font-display)", fontSize: 22, color: "var(--gold-300)", fontWeight: 700, marginBottom: 4 }}>
                        {initial ? window.t("Editar — {name}", { name: initial.name }) : window.t("Nova Skin")}
                    </div>
                    <div style={{ fontSize: 12, color: "var(--ink-400)" }}>
                        {window.t("Coloque os arquivos em assets/avatars/{id}/ (model.glb + thumb.png). Skin que é só variação de cor pode reusar um modelo existente + hairColor.", { id: form.id || "<id>" })}
                    </div>
                    <form className="cc-form" onSubmit={submit} style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14, marginTop: 20 }}>
                        <Field label={window.t("ID (slug, sem '+'/espaço)")} hint={window.t("Ex: f02_ruiva")}><input value={form.id} onChange={e => set({ id: e.target.value })} placeholder="f02_ruiva"/></Field>
                        <Field label={window.t("Nome (display)")}><input value={form.name} onChange={e => set({ name: e.target.value })} placeholder={window.t("Ruiva")}/></Field>
                        <Field label={window.t("Modelo (path)")} hint={window.t("Auto-derivado do id")}><input value={form.model} onChange={e => set({ model: e.target.value })} placeholder="assets/avatars/.../model.glb"/></Field>
                        <Field label={window.t("Thumb (path)")} hint={window.t("Auto-derivado do id")}><input value={form.thumb} onChange={e => set({ thumb: e.target.value })} placeholder="assets/avatars/.../thumb.png"/></Field>
                        <Field label={window.t("Gênero")}>
                            <select value={form.gender} onChange={e => set({ gender: e.target.value })}>
                                <option value="m">{window.t("Masculino")}</option><option value="f">{window.t("Feminino")}</option><option value="u">{window.t("Unissex")}</option>
                            </select>
                        </Field>
                        <Field label={window.t("Tier")}><input value={form.tier} onChange={e => set({ tier: e.target.value })} placeholder={window.t("Premium")}/></Field>
                        <Field label={window.t("Tipo de Unlock")}>
                            <select value={form.unlock?.type || "level"} onChange={e => setUnlock({ type: e.target.value })}>
                                <option value="level">{window.t("Por nível (patente)")}</option><option value="coins">{window.t("Por moedas")}</option><option value="chips">{window.t("Por chips")}</option>
                            </select>
                        </Field>
                        <Field label={form.unlock?.type === "level" ? window.t("Nível mínimo") : window.t("Custo")}>
                            <input type="number" min="0" value={form.unlock?.value ?? 0} onChange={e => setUnlock({ value: parseInt(e.target.value, 10) || 0 })}/>
                        </Field>
                        <Field label={window.t("Mão da tacada (grip)")}>
                            <select value={form.cueGripSide} onChange={e => set({ cueGripSide: parseInt(e.target.value, 10) })}>
                                <option value={-1}>{window.t("Esquerda (-1)")}</option><option value={1}>{window.t("Direita (+1)")}</option>
                            </select>
                        </Field>
                        <Field label={window.t("Mão da ponte")}>
                            <select value={form.bridgeHand} onChange={e => set({ bridgeHand: e.target.value })}>
                                <option value="left">{window.t("Esquerda")}</option><option value="right">{window.t("Direita")}</option>
                            </select>
                        </Field>
                        <Field label={window.t("Altura (m)")}><input type="number" step="0.01" value={form.targetHeight} onChange={e => set({ targetHeight: parseFloat(e.target.value) || 1.62 })}/></Field>
                        <Field label={window.t("Cor do cabelo (hex, opcional)")} hint={window.t("Variação sem arte nova")}><input value={form.hairColor || ""} onChange={e => set({ hairColor: e.target.value })} placeholder="#7a2f12"/></Field>
                        <Field label={window.t("Cor da camisa/casaco (hex)")} hint={window.t("Recolore só a peça")}><input value={form.colorShirt || ""} onChange={e => set({ colorShirt: e.target.value })} placeholder="#5a2a8a"/></Field>
                        <Field label={window.t("Cor da calça (hex)")} hint={window.t("Recolore só a peça")}><input value={form.colorPants || ""} onChange={e => set({ colorPants: e.target.value })} placeholder="#c9a24a"/></Field>
                        <Field label={window.t("Cor do sapato (hex)")} hint={window.t("Recolore só a peça")}><input value={form.colorShoes || ""} onChange={e => set({ colorShoes: e.target.value })} placeholder="#222222"/></Field>
                        <Field label={window.t("Starter (todos têm)")}>
                            <select value={form.starter ? "1" : "0"} onChange={e => set({ starter: e.target.value === "1" })}>
                                <option value="0">{window.t("Não")}</option><option value="1">{window.t("Sim")}</option>
                            </select>
                        </Field>
                        {form.thumb && (
                            <div style={{ gridColumn: "1 / -1" }}>
                                <div style={{ fontSize: 10, fontWeight: 600, color: "var(--ink-400)", letterSpacing: "0.14em", textTransform: "uppercase", marginBottom: 6 }}>{window.t("Preview")}</div>
                                <div style={{ background: "var(--ink-900)", border: "1px solid var(--ink-700)", borderRadius: 4, padding: 4, display: "flex", justifyContent: "center" }}>
                                    <img src={form.thumb} alt="preview" style={{ maxHeight: 180, objectFit: "contain", display: "block" }} onError={(e) => { e.target.style.opacity = 0.3; }}/>
                                </div>
                            </div>
                        )}
                        <div className="cc-form-actions" style={{ gridColumn: "1 / -1", display: "flex", gap: 10, justifyContent: "flex-end", marginTop: 8 }}>
                            <button type="button" className="btn-secondary" onClick={onCancel}>{window.t("Cancelar")}</button>
                            <button type="submit" className="btn-primary">{window.t("Salvar")}</button>
                        </div>
                    </form>
                </div>
            </div>
            <style>{`
                @media (max-width: 480px) {
                    .cc-form { grid-template-columns: 1fr !important; gap: 12px !important; }
                    .cc-form-actions { flex-wrap: wrap !important; }
                    .cc-form-actions button { flex: 1 1 auto; }
                }
            `}</style>
        </div>
    );
}

Object.assign(window, { AvatarCatalogScreen });
