/* game-kniffel.jsx — Kniffel / Yahtzee scoresheet. */
const { useState: useKnf, useEffect: useKnfFX } = React;

const KNF_UPPER = [
  { id: "k1", key: "einser",  rank: 1 }, { id: "k2", key: "zweier",  rank: 2 },
  { id: "k3", key: "dreier",  rank: 3 }, { id: "k4", key: "vierer",  rank: 4 },
  { id: "k5", key: "fuenfer", rank: 5 }, { id: "k6", key: "sechser", rank: 6 },
];
const KNF_LOWER = [
  { id: "kD3",  key: "dreipasch",  inputType: "sum",   max: 30 },
  { id: "kD4",  key: "vierpasch",  inputType: "sum",   max: 30 },
  { id: "kFH",  key: "fullhouse",  inputType: "fixed", value: 25 },
  { id: "kKS",  key: "kstrasse",   inputType: "fixed", value: 30 },
  { id: "kGS",  key: "gstrasse",   inputType: "fixed", value: 40 },
  { id: "kKnf", key: "kniffel",    inputType: "fixed", value: 50 },
  { id: "kCh",  key: "chance",     inputType: "sum",   max: 30 },
];
const KNF_ALL = [...KNF_UPPER, ...KNF_LOWER];
const BONUS_THRESHOLD = 63;
const BONUS_VALUE = 35;

function knfUpperSum(board) { return KNF_UPPER.reduce((s, c) => s + (typeof board[c.id] === "number" ? board[c.id] : 0), 0); }
function knfLowerSum(board) { return KNF_LOWER.reduce((s, c) => s + (typeof board[c.id] === "number" ? board[c.id] : 0), 0); }
function knfBonus(board) { return knfUpperSum(board) >= BONUS_THRESHOLD ? BONUS_VALUE : 0; }
function knfTotal(board) { return knfUpperSum(board) + knfBonus(board) + knfLowerSum(board); }

function newKnfBoard() { const b = {}; KNF_ALL.forEach((c) => { b[c.id] = null; }); return b; }

function KniffelGame({ sess, account, nav, onChange, lang, setLang }) {
  const [editing, setEditing] = useKnf(null); // {pi, catId}
  const [showResults, setShowResults] = useKnf(sess.status === "finished");
  const [showRules, setShowRules] = useKnf(false);
  const [toast, setToast] = useKnf("");

  useKnfFX(() => { if (!toast) return; const tm = setTimeout(() => setToast(""), 1700); return () => clearTimeout(tm); }, [toast]);
  useKnfFX(() => { if (sess.status === "finished") setShowResults(true); }, [sess.status]);

  const n = sess.players.length;
  const entry = sess.entryThisTurn;
  const cp = sess.turn;

  function patch(updater) {
    const next = JSON.parse(JSON.stringify(sess));
    updater(next);
    onChange(next);
  }

  function commitEntry(pi, catId, value) {
    patch((s) => {
      if (s.entryThisTurn && !(s.entryThisTurn.pi === pi && s.entryThisTurn.catId === catId)) {
        s.boards[s.entryThisTurn.pi][s.entryThisTurn.catId] = null;
      }
      s.boards[pi][catId] = value;
      s.entryThisTurn = { pi, catId };
      // check done
      const done = s.players.every((_, i) => KNF_ALL.every((c) => typeof s.boards[i][c.id] === "number"));
      if (done) s.status = "finished";
    });
    setEditing(null);
  }

  function nextPlayer() {
    if (!entry) { setToast(t("game.enterfirst")); return; }
    patch((s) => {
      const np = (s.turn + 1) % s.players.length;
      if (np === 0) s.round += 1;
      s.turn = np;
      s.entryThisTurn = null;
    });
  }

  const totals = sess.players.map((_, i) => knfTotal(sess.boards[i]));
  const leadVal = Math.max(...totals);

  return (
    <div className="app">
      <AppHeader account={account} nav={nav} onSignOut={() => {}} crumb={t("game.kniffel.name")} lang={lang} setLang={setLang} />
      <main className="wrap" style={{ flex: 1, paddingBottom: 80 }}>
        <div className="game-top">
          <button className="btn ghost sm" onClick={() => nav("#/")} style={{ paddingLeft: 6 }}><Icon name="back" size={16} />{t("nav.dashboard")}</button>
          <span className="round-pill">{t("sess.round", { n: sess.round })}</span>
          <span style={{ flex: 1 }}></span>
          <button className="btn sm" onClick={() => setShowRules(true)}><Icon name="book" size={15}/>{t("game.rules")}</button>
          {sess.status === "finished" && <button className="btn sm primary" onClick={() => setShowResults(true)}><Icon name="crown" size={15} />{t("game.results")}</button>}
        </div>

        {/* Player chips */}
        <div className="player-rail">
          {sess.players.map((p, i) => (
            <div key={i} className={"pchip" + (i === cp ? " active" : "") + (totals[i] === leadVal && leadVal > 0 ? " lead" : "")}>
              <div className="ptop">
                <Avatar name={p.name} size="sm" idx={i} />
                <span className="pname">{p.name}</span>
                {totals[i] === leadVal && leadVal > 0 && <span className="crown"><Icon name="crown" size={15} /></span>}
                {i === cp && sess.status === "active" && <span className="turn-dot"></span>}
              </div>
              <div className="score">{totals[i]}</div>
            </div>
          ))}
        </div>

        {/* Sheet */}
        <KnfSheet boards={sess.boards} players={sess.players} cp={cp} entry={entry} status={sess.status}
          onCell={(pi, catId) => { if (pi === cp && sess.status === "active") setEditing({ pi, catId }); }} />
      </main>

      {sess.status === "active" && (
        <div className="action-bar">
          <div className="wrap inner">
            <Avatar name={sess.players[cp].name} idx={cp} />
            <span className="turn-label"><b>{sess.players[cp].name}</b> — {entry ? t("game.readynext") : t("game.addscore")}</span>
            <span style={{ flex: 1 }}></span>
            <button className="btn primary lg" disabled={!entry} onClick={nextPlayer}>{t("game.next")}<Icon name="arrow" /></button>
          </div>
        </div>
      )}

      {editing && <KnfEntryModal editing={editing} sess={sess} lang={lang}
        onCommit={commitEntry} onClose={() => setEditing(null)} />}
      {showResults && (
        <div className="scrim" onClick={() => setShowResults(false)}>
          <div className="modal wide" onClick={(e) => e.stopPropagation()}>
            <div style={{ textAlign: "center", marginBottom: 6 }}>
              <div style={{ color: "var(--gold)", display: "flex", justifyContent: "center" }}><Icon name="crown" size={34} /></div>
              <h3 style={{ fontSize: 24, marginTop: 8 }}>{t("res.over")}</h3>
            </div>
            {sess.players.map((p, i) => ({ name: p.name, total: totals[i], idx: i }))
              .sort((a, b) => b.total - a.total).map((r, pos) => (
              <div className="results-row" key={r.idx}>
                <span className={"rank-badge" + (pos === 0 ? " gold" : "")}>{pos + 1}</span>
                <Avatar name={r.name} idx={r.idx} /><span style={{ fontWeight: 700, flex: 1 }}>{r.name}</span>
                <span style={{ fontFamily: "var(--font-display)", fontWeight: 600, fontSize: 22 }}>{r.total}</span>
              </div>
            ))}
            <div style={{ display: "flex", gap: 10, marginTop: 16 }}>
              <button className="btn primary block" onClick={() => nav("#/new/kniffel")}>{t("res.newgame")}</button>
              <button className="btn ghost block" onClick={() => setShowResults(false)}>{t("res.close")}</button>
            </div>
          </div>
        </div>
      )}
      {showRules && <GameRulesModal gameId="kniffel" lang={lang} onClose={() => setShowRules(false)} />}
      <Toast msg={toast} />
    </div>
  );
}

function KnfSheet({ boards, players, cp, entry, status, onCell }) {
  const n = players.length;
  function cell(pi, cat) {
    const v = boards[pi][cat.id];
    const isEntry = entry && entry.pi === pi && entry.catId === cat.id;
    const editable = pi === cp && status === "active";
    const locked = !editable || (entry && !isEntry);
    let cls = "scell " + (v === null ? "empty" : v === 0 ? "struck" : "filled") + (locked ? " locked" : "") + (isEntry ? " lastentry" : "");
    return <td key={pi} className={cls} onClick={() => !locked && onCell(pi, cat.id)}>{typeof v === "number" && v !== 0 ? v : ""}</td>;
  }
  const upperSums = boards.map(knfUpperSum);
  const bonuses = boards.map(knfBonus);
  const lowerSums = boards.map(knfLowerSum);
  const totals = boards.map(knfTotal);
  return (
    <div className="sheet-wrap">
      <table className="sheet">
        <thead>
          <tr>
            <th className="cat-cell" style={{ textAlign: "left", background: "var(--surface-2)" }}>{t("sheet.category")}</th>
            {players.map((p, i) => <th key={i}><span style={{ fontSize: 13 }}>{p.name}</span></th>)}
          </tr>
        </thead>
        <tbody>
          <tr><td className="cat-cell" style={{ background: "var(--surface-2)" }}><span className="eyebrow" style={{ fontSize: 11 }}>{t("kniffel.upper")}</span></td>{players.map((_, i) => <td key={i} style={{ background: "var(--surface-2)" }}></td>)}</tr>
          {KNF_UPPER.map((c) => (
            <tr key={c.id}>
              <td className="cat-cell"><div className="cl"><span className="clabel">{t("kniffel." + c.key)}</span><span className="cval">×{c.rank}</span></div></td>
              {boards.map((_, pi) => cell(pi, c))}
            </tr>
          ))}
          <tr className="sub-row"><td className="cat-cell">{t("sheet.upper")}</td>{upperSums.map((v, i) => <td key={i} className="scell">{v} {v >= 63 ? "✓" : `/ ${BONUS_THRESHOLD}`}</td>)}</tr>
          <tr className="sub-row"><td className="cat-cell">{t("kniffel.bonus")}</td>{bonuses.map((v, i) => <td key={i} className="scell" style={{ color: v > 0 ? "var(--good)" : "var(--faint)" }}>{v > 0 ? "+35" : "—"}</td>)}</tr>
          <tr><td className="cat-cell" style={{ background: "var(--surface-2)" }}><span className="eyebrow" style={{ fontSize: 11 }}>{t("kniffel.lower")}</span></td>{players.map((_, i) => <td key={i} style={{ background: "var(--surface-2)" }}></td>)}</tr>
          {KNF_LOWER.map((c) => (
            <tr key={c.id}>
              <td className="cat-cell"><div className="cl"><span className="clabel">{t("kniffel." + c.key)}</span><span className="cval">{c.value || "Σ"}</span></div></td>
              {boards.map((_, pi) => cell(pi, c))}
            </tr>
          ))}
          <tr className="sub-row"><td className="cat-cell">{t("sheet.lower")}</td>{lowerSums.map((v, i) => <td key={i} className="scell">{v}</td>)}</tr>
          <tr className="total-row"><td className="cat-cell">{t("sheet.total")}</td>{totals.map((v, i) => <td key={i} className="scell">{v}</td>)}</tr>
        </tbody>
      </table>
    </div>
  );
}

function KnfEntryModal({ editing, sess, lang, onCommit, onClose }) {
  const { pi, catId } = editing;
  const [sumVal, setSumVal] = useKnf("");
  const upper = KNF_UPPER.find((c) => c.id === catId);
  const lower = KNF_LOWER.find((c) => c.id === catId);
  const catName = t("kniffel." + (upper || lower).key);
  const current = sess.boards[pi][catId];

  if (upper) {
    const opts = Array.from({ length: 6 }, (_, n) => ({ count: n, value: n * upper.rank }));
    return (
      <div className="scrim" onClick={onClose}>
        <div className="modal" onClick={(e) => e.stopPropagation()}>
          <h3 style={{ marginBottom: 4 }}>{catName}</h3>
          <p className="muted" style={{ fontSize: 13, marginBottom: 16 }}>{sess.players[pi].name} · ×{upper.rank} {t("kniffel.einser").slice(0, 2)}…</p>
          <div className="entry-grid">
            {opts.map((o) => (
              <div key={o.count} className={"entry-opt" + (o.count === 0 ? " zero" : "")} onClick={() => onCommit(pi, catId, o.value)}>
                <span className="pts" style={o.count === 0 ? { color: "var(--strike)", fontSize: 18 } : {}}>{o.count === 0 ? "—" : o.value}</span>
                <span className="cnt">{o.count === 0 ? t("entry.strike") : `${o.count}×${upper.rank}`}</span>
              </div>
            ))}
          </div>
          <button className="btn ghost block" onClick={onClose}>{t("entry.cancel")}</button>
        </div>
      </div>
    );
  }

  if (lower.inputType === "fixed") {
    return (
      <div className="scrim" onClick={onClose}>
        <div className="modal" onClick={(e) => e.stopPropagation()}>
          <h3>{catName}</h3>
          <p className="muted" style={{ fontSize: 13, marginBottom: 16 }}>{sess.players[pi].name}</p>
          <div className="entry-grid" style={{ gridTemplateColumns: "1fr 1fr", margin: "0 0 14px" }}>
            <div className="entry-opt" style={{ height: 80 }} onClick={() => onCommit(pi, catId, lower.value)}>
              <span className="pts" style={{ fontSize: 30 }}>{lower.value}</span>
              <span className="cnt">{t("entry.done")}</span>
            </div>
            <div className="entry-opt zero" style={{ height: 80 }} onClick={() => onCommit(pi, catId, 0)}>
              <span className="pts" style={{ color: "var(--strike)", fontSize: 18 }}>{t("entry.strike")}</span>
              <span className="cnt">{t("entry.points0")}</span>
            </div>
          </div>
          <button className="btn ghost block" onClick={onClose}>{t("entry.cancel")}</button>
        </div>
      </div>
    );
  }

  // sum type
  return (
    <div className="scrim" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <h3>{catName}</h3>
        <p className="muted" style={{ fontSize: 13, marginBottom: 14 }}>{sess.players[pi].name} · max {lower.max}</p>
        <div style={{ display: "flex", gap: 8, marginBottom: 14 }}>
          <input className="input" type="number" min="0" max={lower.max} placeholder="5 – 30" value={sumVal}
            onChange={(e) => setSumVal(e.target.value)} autoFocus
            onKeyDown={(e) => { if (e.key === "Enter" && sumVal !== "") onCommit(pi, catId, Number(sumVal)); }} />
        </div>
        <div style={{ display: "flex", gap: 10, marginBottom: 10 }}>
          {[0, 5, 10, 15, 20, 25, 30].map((v) => (
            <button key={v} className="btn sm ghost" onClick={() => onCommit(pi, catId, v)}>{v || "—"}</button>
          ))}
        </div>
        <div style={{ display: "flex", gap: 10 }}>
          <button className="btn primary block" disabled={sumVal === ""} onClick={() => onCommit(pi, catId, Number(sumVal))}>{t("entry.done")}</button>
          <button className="btn ghost block" onClick={onClose}>{t("entry.cancel")}</button>
        </div>
      </div>
    </div>
  );
}

window.KniffelGame = KniffelGame;
window.KNF_UPPER = KNF_UPPER;
window.KNF_LOWER = KNF_LOWER;
window.newKnfBoard = newKnfBoard;
