// ============================================
// LIGA E TORNEIO do Carom3D (carom3d-re/notes/social.md §2.14; servidor: 20261101000001_competitivo.sql)
// ============================================
// Copa = mata-mata (bye quando falta gente); Liga = todos contra todos até a data final (vitória = 3 pontos).
// "Jogar" abre a sala fechada da partida para os dois; quem não aparece no prazo perde por W.O.
// Sem empate e sem sair (a partida do torneio não aceita empate). Prêmios: copa 70/30; liga 50/30/20.

const TN_STATUS = { registering: "Inscrições abertas", running: "Em andamento", finished: "Encerrado", cancelled: "Cancelado" };
const TN_MATCH = { pending: "Aguardando", playing: "Jogando", done: "Jogada", walkover: "W.O.", bye: "Bye", expired: "Não jogada" };
const tnApi = () => window.MastershotSocialApi;
const tnModeName = (id) => (window.MastershotData?.GAME_MODES || []).find((m) => m.id === id)?.name || id;
const tnDate = (d) => d ? new Date(d).toLocaleString([], { day: "2-digit", month: "2-digit", hour: "2-digit", minute: "2-digit" }) : "—";
const tnErr = (e) => ({ balance: "Saldo insuficiente para a inscrição.", full: "As vagas acabaram.", closed: "As inscrições estão fechadas.",
    not_player: "Essa partida não é sua.", not_found: "Torneio não encontrado." }[e] || "Não foi possível agora.");

function TnCountdown({ until }) {
    const [, tick] = React.useState(0);
    React.useEffect(() => { const t = setInterval(() => tick((n) => n + 1), 1000); return () => clearInterval(t); }, []);
    const s = Math.max(0, Math.floor((new Date(until) - Date.now()) / 1000));
    if (!until || !s) return null;
    const h = Math.floor(s / 3600), m = Math.floor((s % 3600) / 60), ss = s % 60;
    return <span className="tn-count">{h ? `${h}h ` : ""}{String(m).padStart(2, "0")}:{String(ss).padStart(2, "0")}</span>;
}

function TnPlayer({ p, winner }) {
    if (!p) return <span className="tn-p tn-empty">—</span>;
    return (
        <span className={"tn-p" + (winner === p.id ? " win" : "")} onClick={() => window.MastershotSocial?.openCard(p.id)}>
            <CountryFlag code={p.country} size={13}/> {p.guild?.tag ? <b style={{ color: p.guild.color }}>[{p.guild.tag}]</b> : null} {p.nick}
            {p.online && <i className="tn-on" title={window.t("Online")}/>}
        </span>
    );
}

function TournamentAdminForm({ onDone }) {
    const [f, setF] = React.useState({ name: "", kind: "cup", mode: "3ball", maxPlayers: 16, entryFee: 500, prizeBonus: 0,
        startsAt: new Date(Date.now() + 3600e3).toISOString().slice(0, 16), endsAt: "", roundMinutes: 20 });
    const [msg, setMsg] = React.useState(null);
    const set = (k) => (e) => setF({ ...f, [k]: e.target.type === "number" ? Number(e.target.value) : e.target.value });
    async function save() {
        setMsg(null);
        try {
            const r = await tnApi().adminTournamentSave({ ...f, startsAt: new Date(f.startsAt).toISOString(), endsAt: f.endsAt ? new Date(f.endsAt).toISOString() : null });
            if (r?.ok === false) { setMsg(r.error); return; }
            onDone?.(r.id);
        } catch (e) { setMsg(e.message); }
    }
    return (
        <div className="ms-card tn-form">
            <div className="tn-h3">{window.t("Novo torneio")}</div>
            <div className="tn-grid">
                <label>{window.t("Nome")}<input className="input" value={f.name} maxLength={60} onChange={set("name")}/></label>
                <label>{window.t("Tipo")}<select className="input" value={f.kind} onChange={set("kind")}><option value="cup">{window.t("Copa (mata-mata)")}</option><option value="league">{window.t("Liga (todos contra todos)")}</option></select></label>
                <label>{window.t("Modo")}<select className="input" value={f.mode} onChange={set("mode")}>{["3ball", "carom", "8ball", "9ball", "straight"].map((m) => <option key={m} value={m}>{tnModeName(m)}</option>)}</select></label>
                <label>{window.t("Vagas")}<input className="input" type="number" min={2} max={64} value={f.maxPlayers} onChange={set("maxPlayers")}/></label>
                <label>{window.t("Inscrição (moedas)")}<input className="input" type="number" min={0} value={f.entryFee} onChange={set("entryFee")}/></label>
                <label>{window.t("Bônus do prêmio")}<input className="input" type="number" min={0} value={f.prizeBonus} onChange={set("prizeBonus")}/></label>
                <label>{window.t("Começa")}<input className="input" type="datetime-local" value={f.startsAt} onChange={set("startsAt")}/></label>
                {f.kind === "league"
                    ? <label>{window.t("Termina")}<input className="input" type="datetime-local" value={f.endsAt} onChange={set("endsAt")}/></label>
                    : <label>{window.t("Prazo por rodada (min)")}<input className="input" type="number" min={5} max={1440} value={f.roundMinutes} onChange={set("roundMinutes")}/></label>}
            </div>
            <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                <button className="btn" disabled={!f.name.trim()} onClick={save}>{window.t("Criar torneio")}</button>
                {msg && <span style={{ color: "var(--loss-bright, #ff8a80)", fontSize: 12 }}>{msg}</span>}
            </div>
        </div>
    );
}

function TournamentDetail({ id, navigate, onBack }) {
    const [d, setD] = React.useState(null);
    const [msg, setMsg] = React.useState(null);
    const [busy, setBusy] = React.useState(false);
    const load = React.useCallback(async () => {
        try { const r = await tnApi().tournament(id); setD(r?.ok ? r : { error: tnErr(r?.error) }); } catch (e) { setD({ error: tnErr("x") }); }
    }, [id]);
    React.useEffect(() => { load(); const t = setInterval(load, 15000); return () => clearInterval(t); }, [load]);
    if (!d) return <div className="tn-empty">{window.t("Carregando…")}</div>;
    if (d.error) return <div className="tn-empty">{window.t(d.error)}</div>;
    const t = d.tournament;
    const me = window.MastershotAuth?.getUser?.()?.id;
    const isAdmin = !!window.MastershotAuth?.getPlayer?.()?.isAdmin;
    async function register(on) {
        setBusy(true); setMsg(null);
        try { const r = await tnApi().tournamentRegister(id, on); if (r?.ok === false) setMsg(window.t(tnErr(r.error))); await load(); window.MastershotAuth?.loadMe?.(); }
        catch { setMsg(window.t(tnErr("x"))); } finally { setBusy(false); }
    }
    async function play(m) {
        setBusy(true); setMsg(null);
        try {
            const r = await tnApi().tournamentPlay(m.id);
            if (r?.ok === false) { setMsg(window.t(tnErr(r.error))); return; }
            const room = await window.MastershotLobby.getRoom(r.roomId);
            await window.MastershotEnterRoom(room, navigate, { spectate: false });
        } catch (e) { setMsg(e.message); } finally { setBusy(false); }
    }
    const rounds = {};
    for (const m of d.matches) (rounds[m.round] = rounds[m.round] || []).push(m);
    const pool = Number(t.pot) + Number(t.prizeBonus);
    const shares = t.kind === "cup" ? [0.7, 0.3] : [0.5, 0.3, 0.2];
    const myNext = d.matches.find((m) => m.mine && (m.status === "pending" || m.status === "playing"));
    return (
        <div className="tn-detail">
            <button className="soc-link ms-crumb" onClick={onBack}>‹ {window.t("Torneios")}</button>
            <div className="tn-head">
                <div>
                    <div className="tn-kicker">{t.kind === "cup" ? window.t("Copa") : window.t("Liga")} · {tnModeName(t.mode)} · {window.t(TN_STATUS[t.status])}</div>
                    <div className="tn-title">{t.name}</div>
                    <div className="tn-sub">
                        {window.t("{n}/{max} jogadores", { n: t.players, max: t.maxPlayers })} · {window.t("Inscrição {v}", { v: t.entryFee ? `🪙 ${t.entryFee.toLocaleString()}` : window.t("grátis") })}
                        {" · "}{window.t("Prêmio {v}", { v: `🪙 ${pool.toLocaleString()}` })} ({shares.map((s) => Math.round(s * 100) + "%").join("/")})
                    </div>
                    <div className="tn-sub">
                        {t.status === "registering" && <>{window.t("Começa em {d}", { d: tnDate(t.startsAt) })} <TnCountdown until={t.startsAt}/></>}
                        {t.status === "running" && t.kind === "league" && <>{window.t("Termina em {d}", { d: tnDate(t.endsAt) })} <TnCountdown until={t.endsAt}/></>}
                        {t.status === "running" && t.kind === "cup" && window.t("Rodada {n} · prazo de {m} min por partida", { n: t.round, m: t.roundMinutes })}
                    </div>
                </div>
                <div className="tn-actions">
                    {t.status === "registering" && (t.registered
                        ? <button className="btn-ghost" disabled={busy} onClick={() => register(false)}>{window.t("Cancelar inscrição")}</button>
                        : <button className="btn" disabled={busy || t.players >= t.maxPlayers} onClick={() => register(true)}>{window.t("Inscrever-se")}</button>)}
                    {myNext && <button className="btn" disabled={busy} onClick={() => play(myNext)}>▶ {window.t("Jogar minha partida")}</button>}
                    {isAdmin && (t.status === "registering" || t.status === "running") && (
                        <button className="btn-ghost" style={{ color: "var(--loss-bright, #ff8a80)" }} onClick={async () => {
                            if (await window.MastershotConfirm({ title: window.t("Cancelar torneio"), message: window.t("As inscrições são devolvidas."), danger: true })) { await tnApi().adminTournamentCancel(id); load(); }
                        }}>{window.t("Cancelar torneio")}</button>
                    )}
                </div>
            </div>
            {msg && <div className="tn-msg">{msg}</div>}
            {t.results?.length > 0 && (
                <div className="tn-podium">
                    {t.results.map((r) => <div key={r.place}><b>{["🥇", "🥈", "🥉"][r.place - 1]} {r.nick}</b><span>🪙 {Number(r.prize).toLocaleString()}</span></div>)}
                </div>
            )}
            {t.kind === "league" || t.status === "registering" ? (
                <table className="tn-table">
                    <thead><tr><th>#</th><th>{window.t("Jogador")}</th>{t.status !== "registering" && <><th>{window.t("Pts")}</th><th>{window.t("V")}</th><th>{window.t("D")}</th></>}</tr></thead>
                    <tbody>{d.entries.map((e, i) => (
                        <tr key={e.id} className={e.id === me ? "me" : ""}><td>{i + 1}</td><td><TnPlayer p={e}/></td>
                            {t.status !== "registering" && <><td>{e.points}</td><td>{e.wins}</td><td>{e.losses}</td></>}</tr>
                    ))}</tbody>
                </table>
            ) : null}
            {t.kind === "cup" && Object.keys(rounds).length > 0 && (
                <div className="tn-bracket">
                    {Object.entries(rounds).map(([r, list]) => (
                        <div key={r} className="tn-round">
                            <div className="tn-round-h">{list.length === 1 && t.status !== "running" || (Number(r) === Math.max(...Object.keys(rounds).map(Number)) && list.length === 1) ? window.t("Final") : window.t("Rodada {n}", { n: r })}</div>
                            {list.map((m) => (
                                <div key={m.id} className={"tn-match" + (m.mine ? " mine" : "")}>
                                    <TnPlayer p={m.p1} winner={m.winner}/>
                                    <TnPlayer p={m.p2} winner={m.winner}/>
                                    <div className="tn-mstatus">{window.t(TN_MATCH[m.status] || m.status)}{m.status === "pending" && m.deadline ? <> · <TnCountdown until={m.deadline}/></> : null}</div>
                                </div>
                            ))}
                        </div>
                    ))}
                </div>
            )}
            {t.kind === "league" && d.matches.length > 0 && (
                <div className="tn-lmatches">
                    {d.matches.filter((m) => m.mine || m.status !== "pending").map((m) => (
                        <div key={m.id} className={"tn-match row" + (m.mine ? " mine" : "")}>
                            <TnPlayer p={m.p1} winner={m.winner}/><span className="tn-vs">×</span><TnPlayer p={m.p2} winner={m.winner}/>
                            <span className="tn-mstatus">{window.t(TN_MATCH[m.status] || m.status)}</span>
                            {m.mine && (m.status === "pending" || m.status === "playing") && <button className="btn" style={{ padding: "6px 12px", fontSize: 11 }} disabled={busy} onClick={() => play(m)}>▶ {window.t("Jogar")}</button>}
                        </div>
                    ))}
                </div>
            )}
        </div>
    );
}

function TournamentsScreen({ navigate, params = {} }) {
    const [list, setList] = React.useState(null);
    const [open, setOpen] = React.useState(params.id || null);
    const [creating, setCreating] = React.useState(false);
    const isAdmin = !!window.MastershotAuth?.getPlayer?.()?.isAdmin;
    const load = React.useCallback(() => { tnApi()?.tournaments().then(setList).catch(() => setList([])); }, []);
    React.useEffect(() => {
        if (window.MastershotSocialApi) load(); else window.addEventListener("mastershot:lobby-ready", load, { once: true });
    }, [load]);
    return (
        <div className="ms-screen">
            <TopBar navigate={navigate} active="tournaments"/>
            <main className="ms-page tn-shell">
                {!open && <button className="ms-crumb" onClick={() => navigate("online")}>‹ {window.t("Salões Ativos")}</button>}
                {open ? <TournamentDetail id={open} navigate={navigate} onBack={() => { setOpen(null); load(); }}/> : (<>
                    <div className="ms-page-head ms-head-keep tn-head">
                        <div>
                            <div className="ms-eyebrow">{window.t("Liga e torneio")}</div>
                            <h1 className="ms-h1">{window.t("Torneios")}</h1>
                            <div className="tn-sub">{window.t("Copa: mata-mata. Liga: todos contra todos até a data final. Quem não aparece no prazo perde por W.O.; não há empate.")}</div>
                        </div>
                        {isAdmin && <div className="ms-head-acts"><button className="btn" onClick={() => setCreating((v) => !v)}>{creating ? window.t("Fechar") : "＋ " + window.t("Novo torneio")}</button></div>}
                    </div>
                    {creating && <TournamentAdminForm onDone={(id) => { setCreating(false); load(); setOpen(id); }}/>}
                    {list === null && <div className="tn-empty">{window.t("Carregando…")}</div>}
                    {list && list.length === 0 && <div className="tn-empty">{window.t("Nenhum torneio por enquanto.")}</div>}
                    <div className="tn-list">
                        {(list || []).map((t) => (
                            <button key={t.id} className={"tn-card st-" + t.status} onClick={() => setOpen(t.id)}>
                                <div className="tn-kicker">{t.kind === "cup" ? window.t("Copa") : window.t("Liga")} · {tnModeName(t.mode)}</div>
                                <div className="tn-card-name">{t.name}</div>
                                <div className="tn-sub">{window.t(TN_STATUS[t.status])}{t.registered ? " · " + window.t("inscrito") : ""}</div>
                                <div className="tn-sub">{window.t("{n}/{max} jogadores", { n: t.players, max: t.maxPlayers })} · 🪙 {(Number(t.pot) + Number(t.prizeBonus)).toLocaleString()}</div>
                                <div className="tn-sub">{t.status === "registering" ? window.t("Começa em {d}", { d: tnDate(t.startsAt) }) : t.status === "running" && t.kind === "league" ? window.t("Termina em {d}", { d: tnDate(t.endsAt) }) : t.results?.[0] ? "🥇 " + t.results[0].nick : ""}</div>
                            </button>
                        ))}
                    </div>
                </>)}
            </main>
        </div>
    );
}

Object.assign(window, { TournamentsScreen });
