/* Host (Game Master) screens — lobby + control panel */
(function () {
  const { useState, useEffect, useRef } = React;
  const S = () => window.TraitorsStore;

  function QR({ text, size = 188 }) {
    if (typeof qrcode === "undefined") {
      return <div className="t-muted" style={{ fontSize: ".8rem" }}>{text}</div>;
    }
    const qr = qrcode(0, "M");
    qr.addData(text); qr.make();
    const svg = qr.createSvgTag({ cellSize: 4, margin: 1, scalable: true });
    return <div style={{ width: size, height: size, background: "#fff", borderRadius: 14, padding: 10 }} dangerouslySetInnerHTML={{ __html: svg }} />;
  }

  function joinUrl(code) { return `${location.origin}/?code=${code}`; }

  /* ============================== LOBBY ============================== */
  function HostLobby({ snap }) {
    const g = snap.game;
    const [mode, setMode] = useState("random");
    const [picks, setPicks] = useState({}); // uid -> bool (manual)
    const [busy, setBusy] = useState(false);
    const [error, setError] = useState("");

    const players = snap.players;
    const manualCount = Object.values(picks).filter(Boolean).length;
    const enough = players.length >= 3;

    async function deal() {
      setBusy(true); setError("");
      try {
        if (mode === "manual") {
          const traitorUids = Object.keys(picks).filter((u) => picks[u]);
          await S().assignRoles("manual", traitorUids);
        } else {
          await S().assignRoles("random");
        }
      } catch (e) { setError(e && e.message ? e.message : "Couldn't deal roles."); }
      setBusy(false);
    }

    return (
      <div className="t-stack t-scroll" style={{ flex: 1, minHeight: 0 }}>
        <TopBar title={g.name} sub="Host · Lobby" right={<button className="t-pill" onClick={() => S().leave()}>Exit</button>} />

        <div className="t-screen" style={{ gap: 18, paddingTop: 6 }}>
          {/* Join code + QR */}
          <div className="t-card t-pad t-center" style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }}>
            <p className="t-eyebrow">Players join with</p>
            <div style={{ fontWeight: 900, fontSize: "2.8rem", letterSpacing: ".34em", color: "var(--t-gold)", paddingLeft: ".34em" }}>{g.joinCode}</div>
            <QR text={joinUrl(g.joinCode)} />
            <p className="t-muted" style={{ fontSize: ".74rem" }}>Scan, or go to the site and enter the code</p>
          </div>

          {/* Roster */}
          <div>
            <div className="t-spread" style={{ marginBottom: 10 }}>
              <p className="t-eyebrow">In the castle · {players.length}</p>
              <button className="t-pill" onClick={() => S().setJoinLocked(!g.joinLocked)}>{g.joinLocked ? "🔒 Locked" : "🔓 Open"}</button>
            </div>
            <div className="t-stack" style={{ gap: 8 }}>
              {players.map((p) => (
                <div key={p.id} className="t-card" style={{ display: "flex", alignItems: "center", gap: 12, padding: "9px 13px" }}>
                  <Avatar player={p} size={36} />
                  <span style={{ flex: 1, fontWeight: 800 }}>{p.name}</span>
                  {mode === "manual" ? (
                    <button className={"t-pill" + (picks[p.id] ? " t-pill--red" : "")}
                      onClick={() => setPicks((s) => ({ ...s, [p.id]: !s[p.id] }))}>
                      {picks[p.id] ? "✦ Traitor" : "Mark"}
                    </button>
                  ) : (
                    <button className="t-pill" onClick={() => S().kick(p.id)}>Remove</button>
                  )}
                </div>
              ))}
              {!players.length && <p className="t-muted t-center">No one has joined yet…</p>}
            </div>
          </div>

          {/* Role assignment */}
          <div className="t-card t-pad">
            <p className="t-eyebrow" style={{ marginBottom: 12 }}>Deal the roles</p>
            <div style={{ display: "flex", gap: 8, marginBottom: 14 }}>
              <button className={"t-btn t-btn--sm " + (mode === "random" ? "t-btn--gold" : "t-btn--ghost")} style={{ flex: 1 }} onClick={() => setMode("random")}>Random</button>
              <button className={"t-btn t-btn--sm " + (mode === "manual" ? "t-btn--gold" : "t-btn--ghost")} style={{ flex: 1 }} onClick={() => setMode("manual")}>Choose</button>
            </div>
            {mode === "random" ? (
              <div className="t-spread">
                <span className="t-body">Number of traitors</span>
                <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                  <button className="t-pill" onClick={() => S().setTraitorCount(Math.max(1, (g.traitorCount || 1) - 1))}>−</button>
                  <span style={{ fontWeight: 900, fontSize: "1.3rem", color: "var(--t-gold)", minWidth: 20, textAlign: "center" }}>{g.traitorCount || 1}</span>
                  <button className="t-pill" onClick={() => S().setTraitorCount(Math.min(players.length - 1 || 1, (g.traitorCount || 1) + 1))}>+</button>
                </div>
              </div>
            ) : (
              <p className="t-body">{manualCount} traitor{manualCount === 1 ? "" : "s"} selected — tap players above to mark them.</p>
            )}
          </div>

          {error && <p style={{ color: "#ff9aa0", fontWeight: 700 }}>{error}</p>}
        </div>

        <div className="t-actionbar">
          <button className="t-btn t-btn--gold" disabled={busy || !enough || (mode === "manual" && manualCount < 1)} onClick={deal}>
            {busy ? "Sealing the fates…" : enough ? "Deal roles & begin" : "Need at least 3 players"}
          </button>
        </div>
      </div>
    );
  }

  /* ============================== CONTROL ============================== */
  function can(status, action) {
    const map = {
      newMission: ["roles_assigned", "mission", "conclave", "results"],
      openRound: ["roles_assigned", "mission", "conclave", "results"],
      conclave: ["roles_assigned", "mission", "round_table", "results"],
      reveal: ["round_table"],
      endGame: ["results", "round_table", "mission", "conclave"],
    };
    return (map[action] || []).includes(status);
  }

  function MissionSheet({ onClose }) {
    const [title, setTitle] = useState("");
    const [rules, setRules] = useState("");
    const [points, setPoints] = useState(10);
    const [secret, setSecret] = useState("");
    const [secretPts, setSecretPts] = useState(15);
    const [busy, setBusy] = useState(false);
    async function go() {
      setBusy(true);
      try {
        const id = await S().openMission(title.trim() || "Mission", rules.trim(), points | 0);
        if (secret.trim()) await S().addSecretTask(id, secret.trim(), secretPts | 0);
        onClose();
      } catch (e) { setBusy(false); }
    }
    return (
      <Sheet onClose={onClose}>
        <p className="t-eyebrow" style={{ marginBottom: 10 }}>New mission</p>
        <input className="t-field" style={{ marginBottom: 10 }} placeholder="Title (e.g. The Silent Relay)" value={title} maxLength={80} onChange={(e) => setTitle(e.target.value)} />
        <textarea className="t-field" style={{ marginBottom: 10, minHeight: 90, resize: "vertical" }} placeholder="Public rules — shown to everyone" value={rules} onChange={(e) => setRules(e.target.value)} />
        <div className="t-spread" style={{ marginBottom: 14 }}>
          <span className="t-body">Points for completion</span>
          <input className="t-field" style={{ width: 90, textAlign: "center" }} type="number" value={points} onChange={(e) => setPoints(e.target.value)} />
        </div>
        <p className="t-kicker" style={{ color: "var(--t-traitor-glow)", marginBottom: 8 }}>✦ Secret task (traitors only — optional)</p>
        <textarea className="t-field" style={{ marginBottom: 10, minHeight: 64, resize: "vertical" }} placeholder="Secret objective for the traitors" value={secret} onChange={(e) => setSecret(e.target.value)} />
        <div className="t-spread" style={{ marginBottom: 18 }}>
          <span className="t-body">Secret task points</span>
          <input className="t-field" style={{ width: 90, textAlign: "center" }} type="number" value={secretPts} onChange={(e) => setSecretPts(e.target.value)} />
        </div>
        <button className="t-btn t-btn--gold" disabled={busy} onClick={go}>{busy ? "Opening…" : "Open mission"}</button>
      </Sheet>
    );
  }

  function ControlTab({ snap }) {
    const g = snap.game;
    const round = snap.round;
    const [sheet, setSheet] = useState(false);
    const [busy, setBusy] = useState("");
    const [error, setError] = useState("");

    async function run(label, fn) {
      setBusy(label); setError("");
      try { await fn(); } catch (e) { setError(e && e.message ? e.message : "Action failed."); }
      setBusy("");
    }
    async function reveal() {
      if (!round) return;
      await run("reveal", async () => { await S().closeRound(round.id); await S().tally(round.id); });
    }

    const liveCount = snap.liveVotes.length;

    return (
      <div className="t-stack" style={{ gap: 16, padding: "4px 20px 24px" }}>
        <div className="t-card t-pad t-center">
          <p className="t-kicker">Current stage</p>
          <div style={{ fontWeight: 900, fontSize: "1.5rem", color: "var(--t-gold)", margin: "4px 0 2px" }}>
            {({ roles_assigned: "Roles dealt", mission: "Mission live", conclave: "Nightfall", round_table: "Round Table", results: "Results", game_over: "Game over" })[g.status] || g.status}
          </div>
          {snap.activeMission && <p className="t-body">{snap.activeMission.title}</p>}
          {g.status === "round_table" && <p className="t-gold" style={{ marginTop: 6, fontWeight: 800 }}>{liveCount} vote{liveCount === 1 ? "" : "s"} cast</p>}
        </div>

        {error && <p style={{ color: "#ff9aa0", fontWeight: 700 }}>{error}</p>}

        <div className="t-stack" style={{ gap: 10 }}>
          {can(g.status, "newMission") && <button className="t-btn t-btn--ghost" onClick={() => setSheet(true)}>✚ New mission</button>}
          {can(g.status, "openRound") && <button className="t-btn t-btn--gold" disabled={busy === "round"} onClick={() => run("round", () => S().openRound())}>☀ Open the Round Table</button>}
          {can(g.status, "conclave") && <button className="t-btn t-btn--purple" disabled={busy === "night"} onClick={() => run("night", () => S().openConclave())}>☾ Nightfall (conclave)</button>}
          {can(g.status, "reveal") && <button className="t-btn t-btn--gold" disabled={busy === "reveal"} onClick={reveal}>{busy === "reveal" ? "Revealing…" : "⚖ Close & reveal votes"}</button>}
          {can(g.status, "endGame") && <button className="t-btn t-btn--danger" disabled={busy === "end"} onClick={() => { if (confirm("End the game and reveal all roles?")) run("end", () => S().endGame()); }}>End game</button>}
        </div>

        {round && round.revealed && round.tally && (
          <div className="t-card t-pad">
            <p className="t-eyebrow" style={{ marginBottom: 8 }}>Last round result</p>
            {Object.entries(round.tally).sort((a, b) => b[1] - a[1]).map(([uid, c]) => {
              const p = snap.players.find((x) => x.id === uid);
              return <div key={uid} className="t-spread" style={{ padding: "4px 0" }}><span className="t-body">{p ? p.name : uid}</span><span className="t-gold" style={{ fontWeight: 900 }}>{c}</span></div>;
            })}
          </div>
        )}

        {sheet && <MissionSheet onClose={() => setSheet(false)} />}
      </div>
    );
  }

  function PlayersTab({ snap }) {
    const [showRoles, setShowRoles] = useState(false);
    const rows = snap.players.slice().sort((a, b) => b.score - a.score);
    function bump(uid, delta) { S().awardPoints(uid, delta, "GM adjustment"); }
    return (
      <div className="t-stack" style={{ gap: 10, padding: "4px 20px 24px" }}>
        <div className="t-spread">
          <p className="t-eyebrow">Players · {rows.length}</p>
          <button className="t-pill" onClick={() => setShowRoles((s) => !s)}>{showRoles ? "Hide roles" : "👁 Reveal roles"}</button>
        </div>
        {rows.map((p) => {
          const role = snap.allRoles[p.id];
          return (
            <div key={p.id} className="t-card t-pad" style={{ display: "flex", flexDirection: "column", gap: 10 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                <Avatar player={p} size={38} />
                <span style={{ flex: 1, fontWeight: 800 }}>
                  {p.name}{p.murdered ? " · murdered" : ""}
                  {showRoles && role && <span style={{ marginLeft: 8, fontSize: ".74rem", fontWeight: 800, color: role === "traitor" ? "var(--t-traitor-glow)" : "var(--t-faithful-glow)" }}>{role.toUpperCase()}</span>}
                </span>
                <span style={{ fontWeight: 900, fontSize: "1.15rem" }}>{p.score}</span>
              </div>
              <div style={{ display: "flex", gap: 6, justifyContent: "flex-end" }}>
                {[-5, -1, 1, 5, 10].map((d) => (
                  <button key={d} className="t-pill" onClick={() => bump(p.id, d)}>{d > 0 ? "+" + d : d}</button>
                ))}
              </div>
            </div>
          );
        })}
      </div>
    );
  }

  function TraitorsTab({ snap }) {
    const g = snap.game;
    const conclave = g.status === "conclave";
    const nameOf = (uid) => { const p = snap.players.find((x) => x.id === uid); return p ? p.name : "someone"; };
    const candidates = snap.players.filter((p) => !p.murdered && snap.allRoles[p.id] !== "traitor");
    const scroller = useRef(null);
    useEffect(() => { if (scroller.current) scroller.current.scrollTop = scroller.current.scrollHeight; }, [snap.traitorChat.length]);
    async function kill(targetUid, proposalId) {
      try { await S().commitMurder(targetUid, proposalId); } catch (e) { alert(e.message || "Couldn't commit the murder."); }
    }
    return (
      <div className="t-stack" style={{ gap: 14, padding: "4px 20px 24px" }}>
        <div className="t-card t-pad">
          <p className="t-eyebrow" style={{ color: "var(--t-traitor-glow)", marginBottom: 10 }}>Murder — confirm the kill</p>
          {!conclave && <p className="t-body">Open Nightfall to let the traitors choose. You can also confirm a victim directly below during the conclave.</p>}
          {conclave && snap.murderProposals.length > 0 && (
            <div className="t-stack" style={{ gap: 8, marginBottom: 12 }}>
              <p className="t-kicker">Traitor proposals</p>
              {snap.murderProposals.map((m) => (
                <div key={m.id} className="t-spread t-card" style={{ padding: "8px 12px" }}>
                  <span className="t-body">{nameOf(m.targetUid)} <span className="t-muted">· by {nameOf(m.proposedByUid)}</span></span>
                  <button className="t-btn t-btn--danger t-btn--sm" onClick={() => kill(m.targetUid, m.id)}>Confirm</button>
                </div>
              ))}
            </div>
          )}
          {conclave && (
            <div className="t-stack" style={{ gap: 6 }}>
              <p className="t-kicker">Or choose directly</p>
              {candidates.map((p) => (
                <div key={p.id} className="t-spread t-card" style={{ padding: "8px 12px" }}>
                  <span className="t-body">{p.name}</span>
                  <button className="t-btn t-btn--danger t-btn--sm" onClick={() => kill(p.id, null)}>Murder</button>
                </div>
              ))}
            </div>
          )}
        </div>

        <div className="t-card t-pad">
          <p className="t-eyebrow" style={{ marginBottom: 8 }}>Traitor chat (monitor)</p>
          <div ref={scroller} className="t-scroll" style={{ maxHeight: 280, display: "flex", flexDirection: "column", gap: 8 }}>
            {snap.traitorChat.map((m) => (
              <div key={m.id} style={{ maxWidth: "88%" }}>
                <div className="t-muted" style={{ fontSize: ".66rem", marginBottom: 2 }}>{m.senderName}</div>
                <div style={{ padding: "8px 12px", borderRadius: 12, fontSize: ".9rem", background: "var(--t-panel2)", border: "1px solid var(--t-line)" }}>{m.text}</div>
              </div>
            ))}
            {!snap.traitorChat.length && <p className="t-muted">No messages yet.</p>}
          </div>
        </div>
      </div>
    );
  }

  function FeedTab({ snap }) {
    const [msg, setMsg] = useState("");
    function send() { if (msg.trim()) { S().broadcast(msg.trim()); setMsg(""); } }
    return (
      <div className="t-stack" style={{ gap: 12, padding: "4px 20px 24px" }}>
        <p className="t-eyebrow">Announce to the castle</p>
        <div style={{ display: "flex", gap: 8 }}>
          <input className="t-field" style={{ flex: 1 }} value={msg} maxLength={200} placeholder="Read this aloud / post a note" onChange={(e) => setMsg(e.target.value)} onKeyDown={(e) => e.key === "Enter" && send()} />
          <button className="t-btn t-btn--gold t-btn--sm" disabled={!msg.trim()} onClick={send}>Post</button>
        </div>
        <div className="t-stack" style={{ gap: 8, marginTop: 6 }}>
          {snap.events.map((e) => (
            <div key={e.id} className="t-card" style={{ padding: "10px 13px" }}>
              <p className="t-body" style={{ fontSize: ".9rem", color: "var(--t-fg)" }}>{e.message}</p>
            </div>
          ))}
        </div>
      </div>
    );
  }

  function HostControl({ snap }) {
    const [tab, setTab] = useState("control");
    let body;
    if (tab === "control") body = <ControlTab snap={snap} />;
    else if (tab === "players") body = <PlayersTab snap={snap} />;
    else if (tab === "traitors") body = <TraitorsTab snap={snap} />;
    else body = <FeedTab snap={snap} />;
    return (
      <div className="t-stack" style={{ flex: 1, minHeight: 0 }}>
        <TopBar title={snap.game.name} sub={`Host · code ${snap.game.joinCode}`} right={<button className="t-pill" onClick={() => S().leave()}>Exit</button>} />
        <div className="t-scroll" style={{ flex: 1, minHeight: 0 }}>{body}</div>
        <div style={{ display: "flex", borderTop: "1px solid var(--t-line)", background: "var(--t-bg)" }}>
          {[["control", "Control", "⚜"], ["players", "Players", "♛"], ["traitors", "Traitors", "☾"], ["feed", "Feed", "✦"]].map(([id, label, icon]) => (
            <button key={id} onClick={() => setTab(id)} style={{
              appearance: "none", border: 0, background: "transparent", cursor: "pointer", flex: 1,
              padding: "9px 4px calc(9px + env(safe-area-inset-bottom))", fontFamily: "inherit",
              color: tab === id ? "var(--t-gold)" : "var(--t-fg3)",
            }}>
              <div style={{ fontSize: "1.2rem", lineHeight: 1 }}>{icon}</div>
              <div style={{ fontSize: ".62rem", fontWeight: 800, letterSpacing: ".08em", textTransform: "uppercase", marginTop: 4 }}>{label}</div>
            </button>
          ))}
        </div>
      </div>
    );
  }

  Object.assign(window, { HostLobby, HostControl });
})();
