// ============================================
// SALA POR TIMES do Carom3D (2x2, 3x3) — tela "SELECT TEAM" (carom3d-re/notes/teams.md §5)
//   - 2 times (azul #498EA9, verde #4AAC86) com team_size vagas cada (room_slots, tempo real)
//   - clicar numa vaga livre muda de vaga; o mestre fecha/abre vagas, expulsa e dá o START
//   - START exige os dois times com o mesmo nº de jogadores (1x1, 2x2 ou 3x3) — 0x4bd106
//   - quando a partida começa (rooms.current_match_id), todos os que estão nas vagas entram juntos
// ============================================

const TEAM_COLORS = ["#498EA9", "#4AAC86"];

function TeamWaitingRoom({ navigate, params = {} }) {
    const { GAME_MODES } = window.MastershotData;
    const Lobby = window.MastershotLobby;
    const myId = Lobby?.getCurrentClientId?.()?.id;
    const roomId = React.useMemo(() => {
        if (params.roomId) {
            try { sessionStorage.setItem('mastershot.activeRoomId', params.roomId); sessionStorage.setItem('mastershot.activeRoomKind', 'team'); } catch {}
            return params.roomId;
        }
        try { return sessionStorage.getItem('mastershot.activeRoomId'); } catch { return null; }
    }, [params.roomId]);
    const [room, setRoom] = React.useState(null);
    const [slots, setSlots] = React.useState([]);
    const [msg, setMsg] = React.useState(null);
    const [busy, setBusy] = React.useState(false);
    const [chat, setChat] = React.useState([]);
    const [draft, setDraft] = React.useState("");
    const chatRef = React.useRef(null);
    const enteredRef = React.useRef(false);
    // social: "na sala X" para os amigos e o /where; os convites saem desta sala
    React.useEffect(() => { if (room?.id) window.MastershotSocial?.setRoom({ id: room.id, name: room.name }); }, [room?.id, room?.name]);
    React.useEffect(() => () => window.MastershotSocial?.setRoom(null), []);

    const [spectators, setSpectators] = React.useState([]);
    const refresh = React.useCallback(async () => {
        if (!Lobby || !roomId) return;
        setSlots(await Lobby.getTeamSlots(roomId));
        if (Lobby.getRoomSpectators) setSpectators(await Lobby.getRoomSpectators(roomId));
    }, [Lobby, roomId]);
    // espectadores não têm assinatura própria: confere de tempos em tempos
    React.useEffect(() => { const t = setInterval(refresh, 10000); return () => clearInterval(t); }, [refresh]);

    React.useEffect(() => {
        if (!Lobby || !roomId) return;
        let alive = true;
        (async () => {
            try { const r = await Lobby.getRoom(roomId); if (alive && r) setRoom(r); } catch {}
            await refresh();
        })();
        const unsub = Lobby.subscribeToTeamRoom(roomId, (ev) => {
            if (ev.type === 'room' && ev.room) setRoom((old) => ({ ...(old || {}), ...ev.room }));
            refresh();
        });
        chatRef.current = Lobby.openRoomChat?.(roomId, (m) => setChat((c) => [...c.slice(-40), m]));
        return () => { alive = false; unsub(); chatRef.current?.close(); };
    }, [Lobby, roomId, refresh]);

    // a partida começou: quem está numa vaga entra no jogo (com a vaga que recebeu na partida)
    React.useEffect(() => {
        const mid = room?.current_match_id;
        if (!mid || enteredRef.current) return;
        if (!slots.some((s) => s.client_id === myId)) return;
        enteredRef.current = true;
        (async () => {
            let players = [];
            try { players = await Lobby.getMatchPlayers(mid); } catch {}
            const me = players.find((p) => p.client_id === myId) || slots.find((s) => s.client_id === myId);
            const perTeam = players.filter((p) => p.team === 0).length || 1;
            Lobby.markStayingInRoom?.();
            navigate('game', {
                mode: room.mode || '8ball', table: room.table_id || 'classic', env: room.env_id || 'pool-hall',
                aim: room.aim_mode || 'com', opponent: 'remote', roomId, matchId: mid,
                seat: me.team, team: perTeam, slot: `${me.team}.${me.member}`,
            });
        })();
    }, [room?.current_match_id, slots, myId]);

    const size = room?.team_size || Math.max(1, ...slots.map((s) => s.member + 1));
    const isMaster = room?.master_client_id === myId;
    const imSpectator = !slots.some((s) => s.client_id === myId) && spectators.some((p) => p.client_id === myId);
    const roomPeople = [...slots.filter((s) => s.client_id).map((s) => ({ client_id: s.client_id, nick: s.nick })),
                        ...spectators.map((p) => ({ ...p, role: 'spectator' }))];
    const count = (t) => slots.filter((s) => s.team === t && s.client_id).length;
    const arrangementOk = count(0) > 0 && count(0) === count(1);
    const mode = GAME_MODES.find((m) => m.id === room?.mode);

    async function act(fn) {
        setBusy(true); setMsg(null);
        try {
            const r = await fn();
            if (r && r.ok === false) setMsg(reasonText(r));
        } catch (e) { setMsg(e.message); }
        setBusy(false);
        refresh();
    }
    function reasonText(r) {
        const map = {
            occupied: window.t("Essa vaga está ocupada."), closed: window.t("Essa vaga está fechada."),
            in_game: window.t("A partida já começou."), not_in_room: window.t("Você não está nesta sala."),
            not_master: window.t("Só o mestre da sala pode iniciar."),
            arrangement: window.t("A formação dos jogadores não está correta: os dois times precisam ter o mesmo número de jogadores."),
            balance: window.t("Saldo insuficiente: {nick}", { nick: r.nick || "" }),
            banned: window.t("Você foi expulso desta sala."), self: window.t("Você não pode expulsar a si mesmo."),
            not_found: window.t("Sala não encontrada."), invalid: window.t("Vaga inválida."),
        };
        return map[r.reason] || r.reason || window.t("Não foi possível.");
    }
    async function leave() {
        // o espectador sai pela saída comum (não tem vaga para liberar)
        try { if (imSpectator) await Lobby.leaveRoom(roomId); else await Lobby.leaveTeamRoom(roomId); } catch {}
        window.rxMarkSpectating?.(roomId, false);
        try { sessionStorage.removeItem('mastershot.activeRoomId'); sessionStorage.removeItem('mastershot.activeRoomKind'); } catch {}
        navigate("online");
    }

    const slotCard = (team, member) => {
        const s = slots.find((x) => x.team === team && x.member === member) || { team, member };
        const mine = s.client_id && s.client_id === myId;
        const master = s.client_id && s.client_id === room?.master_client_id;
        return (
            <div key={`${team}.${member}`} className={`tw-slot ${s.client_id ? "on" : ""} ${s.closed ? "closed" : ""} ${mine ? "mine" : ""}`}
                style={{ "--team": TEAM_COLORS[team] }}>
                {s.client_id ? (
                    <>
                        <Avatar initials={s.avatar || (s.nick || "?").slice(0, 2).toUpperCase()} size="md"/>
                        <div className="tw-who">
                            <div className="tw-nick" style={{ cursor: "pointer" }} onClick={() => window.MastershotSocial?.openCard(s.client_id)}>{s.nick || window.t("Jogador")}{mine ? ` (${window.t("você")})` : ""}</div>
                            {master && <div className="tw-badge">{window.t("Mestre")}</div>}
                        </div>
                        {isMaster && !mine && <button className="tw-mini" disabled={busy} onClick={() => act(() => Lobby.kickFromTeamRoom(roomId, s.client_id))}>{window.t("Expulsar")}</button>}
                    </>
                ) : s.closed ? (
                    <>
                        <div className="tw-empty">{window.t("Vaga fechada")}</div>
                        {isMaster && <button className="tw-mini" disabled={busy} onClick={() => act(() => Lobby.setTeamSlotClosed(roomId, team, member, false))}>{window.t("Abrir")}</button>}
                    </>
                ) : (
                    <>
                        <button className="tw-take" disabled={busy} onClick={() => act(() => Lobby.setTeamSlot(roomId, team, member))}>{window.t("Vaga livre — entrar")}</button>
                        {isMaster && <button className="tw-mini" disabled={busy} onClick={() => act(() => Lobby.setTeamSlotClosed(roomId, team, member, true))}>{window.t("Fechar")}</button>}
                    </>
                )}
            </div>
        );
    };

    return (
        <div className="ms-screen">
            <TopBar navigate={navigate} active="waiting"/>
            <main className="tw-shell">
                <div className="tw-head">
                    <div>
                        <div className="tw-kicker">{window.t("Selecione o time")}</div>
                        <div className="tw-title">{room?.name || window.t("Sala")}</div>
                        <div className="tw-sub">
                            {mode?.name || room?.mode} · {window.t("até {n}x{n}", { n: size })}
                            {room?.bet ? ` · ${window.t("aposta {v}", { v: Number(room.bet).toLocaleString() })}` : ""}
                            {room?.aim_mode === "sem" ? ` · ${window.t("Sem mira")}` : ""}
                        </div>
                    </div>
                    <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
                        {window.RoomMasterMenu && <window.RoomMasterMenu room={room} people={roomPeople} myId={myId} onChanged={refresh}/>}
                        {room?.current_match_id && room?.status === "playing" && !slots.some((s) => s.client_id === myId) && window.rxWatchGame && (
                            <button className="btn" onClick={() => window.rxWatchGame(navigate, room)}>👁 {window.t("Assistir partida")}</button>
                        )}
                        {window.MastershotSocial && <button className="btn-ghost" onClick={() => window.MastershotSocial.setOpen(true, "friends")}>＋ {window.t("Convidar")}</button>}
                        <button className="btn" onClick={leave}>{window.t("Sair da sala")}</button>
                    </div>
                </div>
                {/* espectadores e itens de partida (Carom3D) */}
                <div className="rx-bar">
                    {window.RoomSpectators && <window.RoomSpectators list={spectators}/>}
                    {imSpectator && room?.status !== "playing" && (
                        <button className="btn-ghost" onClick={() => act(async () => { const r = await Lobby.joinTeamRoom(roomId); if (r?.ok !== false) window.rxMarkSpectating?.(roomId, false); return r; })}>{window.t("Pegar uma vaga")}</button>
                    )}
                    <div style={{ flex: 1 }}/>
                    {window.RoomItemsBar && !imSpectator && <window.RoomItemsBar/>}
                </div>
                <div className="tw-teams">
                    {[0, 1].map((team) => (
                        <div key={team} className="tw-team" style={{ "--team": TEAM_COLORS[team] }}>
                            <div className="tw-team-head">
                                <span>{team === 0 ? window.t("Time azul") : window.t("Time verde")}</span>
                                <span className="tw-count">{count(team)}/{size}</span>
                            </div>
                            {Array.from({ length: size }, (_, m) => slotCard(team, m))}
                        </div>
                    ))}
                </div>
                <div className="tw-foot">
                    {msg && <div className="tw-msg">{msg}</div>}
                    {isMaster ? (
                        <button className="btn-cta" disabled={busy || !arrangementOk} style={{ opacity: arrangementOk ? 1 : 0.5 }}
                            onClick={async () => {
                                if (room?.bet > 0 && window.confirmBet) { const ok = await window.confirmBet({ bet: room.bet, currency: "coin" }); if (!ok) return; }
                                act(() => Lobby.startTeamMatch(roomId));
                            }}>
                            {arrangementOk ? window.t("Iniciar partida ({a}x{b})", { a: count(0), b: count(1) }) : window.t("Os times precisam ter o mesmo número de jogadores")}
                        </button>
                    ) : (
                        <div className="tw-wait">{window.t("Aguardando o mestre iniciar a partida…")}</div>
                    )}
                </div>
                <div className="tw-chat">
                    <div className="tw-chat-log">
                        {chat.map((m, i) => <div key={i}><b>{m.nick}:</b> {m.text}</div>)}
                    </div>
                    <form onSubmit={(e) => { e.preventDefault(); chatRef.current?.send(draft); setDraft(""); }}>
                        <input className="input" value={draft} onChange={(e) => setDraft(e.target.value)} placeholder={window.t("Mensagem para a sala")} maxLength={280}/>
                    </form>
                </div>
            </main>
            <style>{`
                .tw-shell { width: 100%; max-width: 1040px; margin: 0 auto; padding: 32px 48px 40px; display: grid; gap: 18px; }
                .tw-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 16px; flex-wrap: wrap; }
                .tw-kicker { font-size: 11px; font-weight: 600; color: var(--ms-eyebrow); letter-spacing: .4em; text-transform: uppercase; }
                .tw-title { font-family: var(--font-display); font-weight: 600; font-size: 36px; line-height: 1.05; color: var(--ms-title); margin-top: 8px; }
                .tw-sub { font-size: 12.5px; color: var(--ms-muted); margin-top: 6px; }
                .tw-teams { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
                @media (max-width: 720px) { .tw-teams { grid-template-columns: 1fr; } }
                .tw-team { border: 1px solid color-mix(in srgb, var(--team) 50%, transparent); border-radius: 16px; padding: 14px;
                    background: linear-gradient(180deg, color-mix(in srgb, var(--team) 12%, rgba(0,0,0,.2)), rgba(255,255,255,.02)); display: grid; gap: 10px; }
                .tw-team-head { display: flex; justify-content: space-between; color: #e7eef2; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; font-size: 12px; }
                .tw-count { color: var(--ms-muted); }
                .tw-slot { display: flex; align-items: center; gap: 12px; min-height: 58px; padding: 8px 12px; border-radius: 12px;
                    border: 1px dashed rgba(255,255,255,.14); background: rgba(0,0,0,.2); }
                .tw-slot.on { border-style: solid; border-color: color-mix(in srgb, var(--team) 70%, transparent); }
                .tw-slot.mine { box-shadow: 0 0 0 1px var(--gold-500) inset; }
                .tw-slot.closed { opacity: .55; }
                .tw-who { flex: 1; min-width: 0; }
                .tw-nick { color: var(--ink-100); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
                .tw-badge { display: inline-block; margin-top: 3px; font-size: 10px; color: #1b1406; background: var(--gold-500); border-radius: 999px; padding: 1px 7px; font-weight: 700; }
                .tw-empty { flex: 1; color: var(--ink-400); font-size: 12px; }
                .tw-take { flex: 1; text-align: left; background: none; border: none; color: var(--ink-300); cursor: pointer; font: inherit; font-size: 12px; padding: 10px 4px; }
                .tw-take:hover { color: var(--gold-400); }
                .tw-mini { background: transparent; border: 1px solid rgba(201,165,92,.3); color: var(--gold-400); border-radius: 999px; padding: 4px 11px; font-size: 11px; font-weight: 700; cursor: pointer; }
                .tw-foot { display: grid; gap: 8px; }
                .tw-msg { color: var(--loss-bright); font-size: 12px; text-align: center; }
                .tw-wait { text-align: center; color: var(--ms-muted); padding: 12px; }
                .tw-foot .btn-cta { justify-self: center; min-width: 320px; }
                .tw-chat { border: 1px solid var(--ms-card-line); border-radius: 16px; padding: 12px; background: var(--ms-card); }
                @media (max-height: 520px) {
                    .tw-shell { padding: 0 max(16px, env(safe-area-inset-right)) 16px 20px; gap: 10px; }
                    .tw-title { font-size: 22px; margin-top: 2px; }
                    .tw-kicker { font-size: 9px; }
                    .tw-teams { grid-template-columns: 1fr 1fr !important; gap: 10px; }
                    .tw-slot { min-height: 44px; padding: 6px 10px; }
                }
                .tw-chat-log { max-height: 140px; overflow: auto; font-size: 12px; color: var(--ink-200); display: grid; gap: 3px; margin-bottom: 8px; }
            `}</style>
        </div>
    );
}

// A sala de espera escolhe a tela: por times (SELECT TEAM) ou rei da mesa (a de sempre).
(function () {
    const ChallengeWaiting = window.WaitingRoom;
    function WaitingRoomSwitch(props) {
        let team = !!props.params?.team;
        if (!team && !props.params?.roomId) { try { team = sessionStorage.getItem('mastershot.activeRoomKind') === 'team'; } catch {} }
        if (props.params?.roomId && !props.params?.team) { try { sessionStorage.removeItem('mastershot.activeRoomKind'); } catch {} }
        return team ? <TeamWaitingRoom {...props}/> : <ChallengeWaiting {...props}/>;
    }
    Object.assign(window, { TeamWaitingRoom, WaitingRoom: WaitingRoomSwitch });
})();
