// Public share view — read-only, accessed by share token
const { useState: useState_sh, useMemo: useMemo_sh, useEffect: useEffect_sh } = React;

function PublicShareView({ store, shareToken, onExit }) {
  const { groups, players, currentUser } = store;
  const group = groups.find(g => g.shareToken === shareToken);

  // ── Hooks must run unconditionally on every render (before any early return).
  //    The shared store hydrates async, so `group` flips undefined→defined; keeping
  //    hooks above the guards keeps their call order stable. All are null-safe.
  const playerById = useMemo_sh(
    () => Object.fromEntries(players.map(p => [p.id, p])),
    [players]
  );

  // Mini-leaderboard
  const leaderboard = useMemo_sh(() => {
    if (!group) return [];
    const agg = {};
    group.playerIds.forEach(id => {
      const p = playerById[id];
      if (p) agg[id] = { player: p, matches: 0, wins: 0 };
    });
    group.history?.forEach(h => {
      h.players.forEach(id => { if (agg[id]) agg[id].matches += 1; });
      if (h.winners) h.winners.forEach(id => { if (agg[id]) agg[id].wins += 1; });
    });
    return Object.values(agg)
      .filter(x => x.matches > 0)
      .sort((a, b) => (b.wins/Math.max(b.matches,1)) - (a.wins/Math.max(a.matches,1)))
      .slice(0, 5);
  }, [group, playerById]);

  // Auto-refresh timestamp tick
  const [, setTick] = useState_sh(0);
  useEffect_sh(() => {
    const id = setInterval(() => setTick(t => t + 1), 5000);
    return () => clearInterval(id);
  }, []);

  // Viewer Analytics — register this viewer session + heartbeat while watching;
  // mark it ended when the viewer leaves. Group Owner sees this live.
  useEffect_sh(() => {
    if (!group || !store.logViewerView) return;
    const sid = store.logViewerView({ groupId: group.id });
    const hb = setInterval(() => store.viewerHeartbeat && store.viewerHeartbeat(sid), 15000);
    return () => {
      clearInterval(hb);
      store.endViewerSession && store.endViewerSession(sid);
    };
    // eslint-disable-next-line
  }, [group?.id]);

  if (!group) {
    return (
      <div className="public-shell">
        <div className="public-empty">
          <div className="public-error-icon"><Icon name="x" size={32} /></div>
          <h2>ไม่พบลิงก์นี้</h2>
          <p className="muted">ลิงก์อาจถูกยกเลิก, ถูกสร้างใหม่ หรือก๊วนถูกลบไปแล้ว</p>        </div>
      </div>
    );
  }

  // Security gates: disabled or expired
  if (group.shareEnabled === false) {
    return (
      <div className="public-shell">
        <div className="public-empty">
          <div className="public-error-icon" style={{background:"var(--orange-soft)", color:"var(--orange)"}}>
            <Icon name="door" size={32} />
          </div>
          <h2>ลิงก์ถูกปิดอยู่</h2>
          <p className="muted">เจ้าของก๊วนได้ปิดการแชร์ชั่วคราว<br/>กรุณาติดต่อ admin เพื่อขอลิงก์ใหม่</p>        </div>
      </div>
    );
  }
  if (group.shareExpiry && new Date(group.shareExpiry).getTime() < Date.now()) {
    return (
      <div className="public-shell">
        <div className="public-empty">
          <div className="public-error-icon" style={{background:"var(--red-soft)", color:"var(--red)"}}>
            <Icon name="history" size={32} />
          </div>
          <h2>ลิงก์หมดอายุแล้ว</h2>
          <p className="muted">หมดอายุเมื่อ {group.shareExpiry}<br/>กรุณาขอลิงก์ใหม่จาก admin</p>        </div>
      </div>
    );
  }

  // Bench
  const playingIds = new Set();
  Object.values(group.active || {}).forEach(m => m?.players?.forEach(id => playingIds.add(id)));
  group.upcoming?.forEach(m => m.players?.forEach(id => playingIds.add(id)));
  const bench = group.playerIds
    .map(id => playerById[id])
    .filter(p => p && !playingIds.has(p.id));

  // Today's history
  const today = new Date().toDateString();
  const todayHistory = (group.history || []).filter(h => new Date(h.at).toDateString() === today);

  // Viewer display options — owner-configurable (gated by Super-granted permission).
  // Privacy-first: hidden unless explicitly enabled. Player levels are NEVER shown to viewers.
  const showLeaderboard = group.settings?.viewerShowLeaderboard === true;
  const showHistory = group.settings?.viewerShowHistory === true;

  return (
    <div className="public-shell" data-screen-label="Public Share">
      <header className="public-head">
        <div className="row gap-3">
          <span className="dot" style={{background: group.color, width:12, height:12}} />
          <div>
            <div className="public-title">{group.name}</div>
            <div className="public-sub">{group.venue} · {group.mode === "double" ? "ประเภทคู่" : "ประเภทเดี่ยว"}</div>
          </div>
        </div>
        <div className="row gap-2">
          <span className="chip"><span className="bench-dot" style={{background:"var(--green)"}}/> Live</span>
        </div>
      </header>

      <main className="public-content">
        {/* Live courts */}
        <section className="public-section">
          <h3 className="public-h3">สนามที่กำลังเล่น</h3>
          <div className="public-courts">
            {group.courts.map(c => (
              <PublicCourtCard key={c.id} court={c} match={group.active[c.id]}
                mode={group.mode} playerById={playerById} />
            ))}
          </div>
        </section>

        <div className="public-grid">
          {/* Upcoming */}
          <section className="public-section">
            <h3 className="public-h3">คิวรอลงสนาม <span className="muted">· {(group.upcoming || []).length}</span></h3>
            {(group.upcoming || []).length ? (
              <div className="col gap-2">
                {group.upcoming.map((m, i) => {
                  const court = group.courts.find(c => c.id === m.court);
                  const t1 = group.mode === "double" ? m.players.slice(0,2) : [m.players[0]];
                  const t2 = group.mode === "double" ? m.players.slice(2,4) : [m.players[1]];
                  return (
                    <div key={m.id} className="public-card">
                      <div className="small muted spread mb-1">
                        <span>คิว #{i + 1}</span>
                        <span>สนาม {court?.name}</span>
                      </div>
                      <div className="pair">
                        <div className="pair-side">
                          {t1.map(id => <div key={id} className="pname">
                            <span>{playerById[id]?.name?.split(" ")[0]}</span>                          </div>)}
                        </div>
                        <div className="pair-vs">VS</div>
                        <div className="pair-side">
                          {t2.map(id => <div key={id} className="pname">
                            <span>{playerById[id]?.name?.split(" ")[0]}</span>                          </div>)}
                        </div>
                      </div>
                    </div>
                  );
                })}
              </div>
            ) : <div className="public-card center muted">ยังไม่มีคิว</div>}
          </section>

          {/* Bench */}
          <section className="public-section">
            <h3 className="public-h3">ผู้เล่นที่พักรอ <span className="muted">· {bench.length}</span></h3>
            {bench.length ? (
              <div className="bench-grid">
                {bench.map(p => (
                  <div key={p.id} className="bench-card">
                    <span className="bench-dot" />
                    <span className="grow">{p.name.split(" ")[0]}</span>
                  </div>
                ))}
              </div>
            ) : <div className="public-card center muted">ทุกคนกำลังเล่นอยู่ 🏸</div>}
          </section>
        </div>

        {(showLeaderboard || showHistory) && (
        <div className="public-grid">
          {/* Mini-leaderboard */}
          {showLeaderboard && (
          <section className="public-section">
            <h3 className="public-h3">Leaderboard วันนี้ <span className="muted">· Top 5</span></h3>
            {leaderboard.length ? (
              <div className="public-card" style={{padding: 0, overflow:"hidden"}}>
                {leaderboard.map((l, i) => (
                  <div key={l.player.id} className="card-row" style={{padding: "10px 14px"}}>
                    <div style={{
                      width: 22, height: 22, borderRadius: 999,
                      background: i===0 ? "linear-gradient(135deg, #ffd60a, #ff9f0a)"
                                : i===1 ? "linear-gradient(135deg, #d4d4d8, #a1a1aa)"
                                : i===2 ? "linear-gradient(135deg, #d97706, #92400e)"
                                : "var(--bg-inset)",
                      color: i < 3 ? "white" : "var(--text-3)",
                      display:"grid", placeItems:"center", fontSize:11, fontWeight:700,
                      marginRight: 10
                    }}>{i+1}</div>
                    <div className="grow">
                      <div style={{fontWeight: 500}}>{l.player.name}</div>
                      <div className="small muted">{l.matches} แมตช์ · {l.wins} ชนะ</div>
                    </div>
                    <div style={{fontWeight: 700, color: "var(--green)"}}>
                      {Math.round(l.wins/l.matches*100)}%
                    </div>
                  </div>
                ))}
              </div>
            ) : <div className="public-card center muted">ยังไม่มีข้อมูล</div>}
          </section>
          )}

          {/* Today's history */}
          {showHistory && (
          <section className="public-section">
            <h3 className="public-h3">ประวัติแมตช์วันนี้ <span className="muted">· {todayHistory.length}</span></h3>
            {todayHistory.length ? (
              <div className="public-card" style={{padding: 0, overflow:"hidden"}}>
                {todayHistory.slice(0, 10).map(h => {
                  const court = group.courts.find(c => c.id === h.court);
                  return (
                    <div key={h.id} className="card-row" style={{padding: "10px 14px"}}>
                      <div className="grow">
                        <div style={{fontWeight: 500, fontSize: 13.5}}>
                          {h.players.map(id => playerById[id]?.name?.split(" ")[0] || "?").join(", ")}
                        </div>
                        <div className="small muted">
                          {fmtTime(h.at)} · สนาม {court?.name}
                          {h.winners && <> · ผู้ชนะ: <b style={{color:"var(--green)"}}>
                            {h.winners.map(id => playerById[id]?.name?.split(" ")[0]).join(" & ")}
                          </b></>}
                        </div>
                      </div>
                      {h.winners ? <Icon name="trophy" size={16} /> : <span className="muted small">—</span>}
                    </div>
                  );
                })}
              </div>
            ) : <div className="public-card center muted">ยังไม่มีแมตช์ที่บันทึกไว้วันนี้</div>}
          </section>
          )}
        </div>
        )}
      </main>

      <footer className="public-foot">
        <div className="small muted" style={{display:"flex", flexDirection:"column", gap:3, alignItems:"center"}}>
          <span>ดูอย่างเดียว · อัปเดตอัตโนมัติทุก 5 วินาที · BadMatch</span>
          <BrandCredit variant="inline" />
        </div>
      </footer>
    </div>
  );
}

function PublicCourtCard({ court, match, mode, playerById }) {
  const [elapsed, setElapsed] = useState_sh(0);
  useEffect_sh(() => {
    if (!match) return;
    const tick = () => setElapsed(Math.floor((Date.now() - match.startedAt) / 1000));
    tick();
    const id = setInterval(tick, 1000);
    return () => clearInterval(id);
  }, [match]);

  if (!match) {
    return (
      <div className="court">
        <div className="court-head">
          <div className="court-title">
            <div className="court-num">{court.name}</div>
            <div>
              <div style={{fontWeight: 600}}>สนาม {court.name}</div>
              <div className="court-status">ว่าง</div>
            </div>
          </div>
        </div>
      </div>
    );
  }

  const team1 = mode === "double" ? match.players.slice(0,2) : [match.players[0]];
  const team2 = mode === "double" ? match.players.slice(2,4) : [match.players[1]];

  return (
    <div className="court playing">
      <div className="court-head">
        <div className="court-title">
          <div className="court-num">{court.name}</div>
          <div>
            <div style={{fontWeight: 600}}>สนาม {court.name}</div>
            <div className="court-status live">กำลังเล่น · {fmtElapsedShare(elapsed)}</div>
          </div>
        </div>
      </div>
      <div className="court-net">
        <div className="court-side">
          {team1.map(id => (
            <div key={id} className="player-pill">
              <div className="avatar" style={{width: 26, height: 26, fontSize: 11}}>
                {initials(playerById[id]?.name || "?")}
              </div>
              <div className="player-pill-name">{playerById[id]?.name}</div>            </div>
          ))}
        </div>
        <div className="court-divider" />
        <div className="court-side">
          {team2.map(id => (
            <div key={id} className="player-pill">
              <div className="avatar" style={{width: 26, height: 26, fontSize: 11}}>
                {initials(playerById[id]?.name || "?")}
              </div>
              <div className="player-pill-name">{playerById[id]?.name}</div>            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function fmtElapsedShare(s) {
  const m = Math.floor(s / 60), ss = s % 60;
  return `${m}:${String(ss).padStart(2,"0")}`;
}

/* ---------- Share modal (opens from group session) ---------- */
function ShareModal({ group, onClose, store }) {
  const { regenerateShareToken, setShareEnabled, setShareExpiry } = store;
  const [copied, setCopied] = useState_sh(false);
  const [confirmRegen, setConfirmRegen] = useState_sh(false);
  const toast = useToast();

  const enabled = group.shareEnabled !== false;
  const expiry = group.shareExpiry;
  const expired = expiry && new Date(expiry).getTime() < Date.now();

  const url = `${location.origin}${location.pathname}#share=${group.shareToken}`;

  const copy = async () => {
    try {
      await navigator.clipboard.writeText(url);
      setCopied(true);
      toast("คัดลอกลิงก์แล้ว");
      setTimeout(() => setCopied(false), 2000);
    } catch (e) {
      toast("คัดลอกไม่ได้");
    }
  };

  const regen = () => {
    if (confirmRegen) {
      regenerateShareToken(group.id);
      toast("สร้าง token ใหม่แล้ว — ลิงก์เดิมใช้ไม่ได้แล้ว");
      setConfirmRegen(false);
    } else {
      setConfirmRegen(true);
      setTimeout(() => setConfirmRegen(false), 4000);
    }
  };

  return (
    <Modal open title="แชร์หน้าดูสด" size="large" onClose={onClose}
      footer={<button className="btn" onClick={onClose}>ปิด</button>}>
      <p className="muted small mb-2">
        แชร์ลิงก์หรือ QR Code นี้ให้ผู้เล่น/ผู้ชม — เห็นสนามสด คิวรอ และสถิติ แต่แก้ไขไม่ได้
        <br/>👁 <b>ผู้ชมไม่ต้อง login</b> — ลิงก์นี้คือทางเข้าเดียวของเขา
      </p>

      {/* Enable/Disable toggle */}
      <div className="share-toggle-row">
        <div className="grow">
          <div style={{fontWeight: 600}}>เปิดให้ดูสาธารณะ</div>
          <div className="small muted">
            {enabled ? "ทุกคนที่มีลิงก์นี้เข้าดูได้" : "ลิงก์ถูกปิดอยู่ — ใครก็เปิดไม่ได้"}
          </div>
        </div>
        <Toggle on={enabled} onChange={(v) => { setShareEnabled(group.id, v); toast(v ? "เปิดการแชร์แล้ว" : "ปิดการแชร์แล้ว"); }} />
      </div>

      <div className="share-toggle-row">
        <div className="grow">
          <div style={{fontWeight: 600}}>วันหมดอายุของลิงก์</div>
          <div className="small muted">
            {expired
              ? <span style={{color:"var(--red)"}}>หมดอายุแล้วเมื่อ {expiry}</span>
              : expiry
                ? <>หมดอายุวันที่ <b>{expiry}</b></>
                : "ไม่จำกัด"}
          </div>
        </div>
        <input type="date" value={expiry || ""} onChange={e => setShareExpiry(group.id, e.target.value)}
          style={{maxWidth: 160}} />
      </div>

      <div className={`share-content ${(!enabled || expired) ? "share-disabled" : ""}`}>
        <div className="share-grid mt-2">
          <div className="share-qr">
            <QRCode value={url} size={200} />
          </div>
          <div className="grow">
            <div className="field">
              <label>ลิงก์สาธารณะ</label>
              <input value={url} readOnly onClick={(e) => e.target.select()} style={{fontFamily:"var(--font-mono)", fontSize: 12}} />
            </div>
            <button className="btn primary block" onClick={copy} disabled={!enabled || expired}>
              <Icon name="check" size={14} stroke={2.2} /> {copied ? "คัดลอกแล้ว" : "คัดลอกลิงก์"}
            </button>
            <button className="btn block mt-1" onClick={() => window.open(`#share=${group.shareToken}`, "_blank")} disabled={!enabled || expired}>
              <Icon name="eye" size={14} /> เปิดหน้าตัวอย่างในแท็บใหม่
            </button>
            <div className="row gap-2 mt-2 small muted">
              <span><b>Token:</b> <span className="mono">{group.shareToken}</span></span>
            </div>
            <button className={`btn block mt-2 ${confirmRegen ? "danger" : ""}`} onClick={regen}>
              <Icon name="refresh" size={13} stroke={2} />
              {confirmRegen ? "กดอีกครั้งเพื่อยืนยัน — ลิงก์เดิมจะใช้ไม่ได้" : "สร้าง Token ใหม่"}
            </button>
          </div>
        </div>

        {(!enabled || expired) && (
          <div className="share-overlay-msg">
            {!enabled ? "ลิงก์ถูกปิดอยู่ — เปิดด้านบนเพื่อเริ่มแชร์" : "ลิงก์หมดอายุแล้ว — เปลี่ยนวันหมดอายุด้านบน"}
          </div>
        )}
      </div>
    </Modal>
  );
}

/* ---------- QR Code (real, standards-compliant) ----------
   Uses the vendored `qrcode-generator` lib (window.qrcode) to encode the URL
   into a genuine scannable QR matrix. Renders as SVG with a 4-module quiet
   zone (required by the spec for reliable scanning). */
function QRCode({ value, size = 200 }) {
  const matrix = useMemo_sh(() => {
    try {
      if (typeof window.qrcode !== "function") return null;
      const qr = window.qrcode(0, "M");   // type 0 = auto-fit, error correction level M
      qr.addData(value);
      qr.make();
      const n = qr.getModuleCount();
      return Array.from({ length: n }, (_, r) =>
        Array.from({ length: n }, (_, c) => (qr.isDark(r, c) ? 1 : 0)));
    } catch (e) {
      console.error("[BadMatch] QR generate failed:", e);
      return null;
    }
  }, [value]);

  const wrap = {
    background: "white", padding: 12, borderRadius: 12,
    boxShadow: "0 2px 14px rgba(0,0,0,0.08)", border: "0.5px solid var(--sep-soft)",
    width: size + 24, height: size + 24, display: "grid", placeItems: "center",
  };

  if (!matrix) {
    return (
      <div style={wrap}>
        <span className="small muted center">QR ไม่พร้อมใช้งาน<br/>ใช้ลิงก์ด้านขวาแทน</span>
      </div>
    );
  }

  const quiet = 4;                       // quiet-zone modules on each side
  const total = matrix.length + quiet * 2;
  const cell = size / total;
  return (
    <div style={wrap}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} shapeRendering="crispEdges">
        <rect width={size} height={size} fill="#ffffff" />
        {matrix.map((row, r) => row.map((v, c) => (
          v ? <rect key={`${r}-${c}`}
                x={(c + quiet) * cell} y={(r + quiet) * cell}
                width={cell + 0.5} height={cell + 0.5} fill="#1c1c1e" /> : null
        )))}
      </svg>
    </div>
  );
}

Object.assign(window, { PublicShareView, ShareModal, QRCode });
