// Guest Mode — ออฟไลน์ ไม่ต้องล็อคอิน เก็บทุกอย่างใน localStorage
const { useState: usg, useEffect: ueg, useMemo: umg } = React;

const GUEST_KEY = "badmatch_guest_v1";
const gId = (p = "g") => p + Math.random().toString(36).slice(2, 8);

function guestDefault() {
  return {
    players: [],
    mode: "double",
    courtCount: 2,
    active: {},          // { courtId: { id, players, startedAt } }
    queue: [],           // [{ id, players }]
    history: [],         // [{ id, players, at }]
    plays: {},           // { playerId: count }
    recentRounds: [],    // [[id,...], ...] most-recent first — for streak calc
  };
}

function guestLoad() {
  try { const r = localStorage.getItem(GUEST_KEY); return r ? JSON.parse(r) : null; }
  catch { return null; }
}

// deterministic hue from string (same as group.jsx)
function gHashColor(seed) {
  let h = 0;
  for (let i = 0; i < seed.length; i++) h = (h * 31 + seed.charCodeAt(i)) & 0xffffff;
  return `hsl(${h % 360}, 65%, 60%)`;
}

/* ═══════════════════════════════════════════════════════
   GuestApp — top-level component, owns all state
═══════════════════════════════════════════════════════ */
function GuestApp({ onExit }) {
  const [state, setState] = usg(() => guestLoad() || guestDefault());
  const [tab, setTab] = usg("play");
  const toast = useToast();

  // Persist on every change
  ueg(() => {
    try { localStorage.setItem(GUEST_KEY, JSON.stringify(state)); } catch (_) {}
  }, [state]);

  const upd = (patch) => setState(prev => ({ ...prev, ...patch }));

  const playerById = umg(
    () => Object.fromEntries(state.players.map(p => [p.id, p])),
    [state.players]
  );

  const courtIds = Array.from({ length: state.courtCount }, (_, i) => `c${i}`);
  const activeCourts = new Set(Object.keys(state.active));
  const freeCourts = courtIds.filter(c => !activeCourts.has(c));

  // ── Player actions ──────────────────────────────────
  function addPlayer(name, level) {
    const p = { id: gId("p"), name: name.trim(), level: Math.round(parseFloat(level)) };
    upd({ players: [...state.players, p] });
    toast(`เพิ่ม ${p.name} แล้ว`);
  }
  function removePlayer(id) {
    const name = playerById[id]?.name;
    upd({
      players: state.players.filter(p => p.id !== id),
      queue: state.queue.filter(q => !q.players.includes(id)),
    });
    toast(`ลบ ${name} แล้ว`);
  }
  function savePlayer(id, name, level) {
    upd({ players: state.players.map(p => p.id === id ? { ...p, name: name.trim(), level: Math.round(parseFloat(level)) } : p) });
  }

  // ── Generate queue ───────────────────────────────────
  function generateQueue() {
    const { players, mode, courtCount, plays, active, queue, recentRounds, history } = state;
    const perCourt = mode === "double" ? 4 : 2;
    const minPlayers = courtCount * perCourt;

    if (players.length < minPlayers) {
      return toast(`ต้องการผู้เล่นอย่างน้อย ${minPlayers} คน (ตอนนี้มี ${players.length})`);
    }

    const courts = Array.from({ length: courtCount }, (_, i) => ({ id: `c${i}`, name: String(i + 1) }));
    const playerObjs = players.map(p => ({ ...p, gender: "M" }));

    // Bump active players' simulated plays so they're de-prioritised in the queue round
    const simPlays = { ...plays };
    Object.values(active).forEach(m => {
      m.players.forEach(id => { simPlays[id] = (simPlays[id] || 0) + 1; });
    });

    // simRounds: prepend current active round (most-recent first)
    const currentRound = Object.values(active).flatMap(m => m.players);
    const simRounds = (currentRound.length ? [currentRound] : []).concat(recentRounds).slice(0, 8);

    // Include existing queue + history as recentMatches so the algorithm
    // penalises repeated partner pairs and rotates pairings each generation.
    const recentMatches = [
      ...queue.slice(-courtCount * 2),
      ...history.slice(-courtCount * 2),
    ].slice(0, courtCount * 4).map(h => ({ players: h.players }));

    const result = window.generateMatches({
      players: playerObjs,
      courts,
      mode,
      plays: simPlays,
      settings: { balanceMode: "total", skillGap: 99, genderMode: "any", matchPriority: "diversity" },
      recentMatches,
      recentRounds: simRounds,
    });

    if (!result || !result.matches?.length) {
      return toast("สร้างคิวไม่ได้ — ผู้เล่นอาจไม่พอ");
    }

    const newItems = result.matches
      .filter(m => m.players?.length >= perCourt)
      .map(m => ({ id: gId("q"), players: m.players }));

    if (!newItems.length) return toast("สร้างคิวไม่ได้");
    upd({ queue: [...state.queue, ...newItems] });
    toast(`เพิ่มคิว ${newItems.length} แมตช์`);
  }

  // ── Place queue → active ─────────────────────────────
  function placeMatch(qItem) {
    if (!freeCourts.length) return toast("ไม่มีสนามว่าง");
    const courtId = freeCourts[0];
    upd({
      active: { ...state.active, [courtId]: { ...qItem, startedAt: Date.now() } },
      queue: state.queue.filter(q => q.id !== qItem.id),
    });
  }

  // ── End match ────────────────────────────────────────
  function endMatch(courtId) {
    const match = state.active[courtId];
    if (!match) return;

    const newActive = { ...state.active };
    delete newActive[courtId];

    const newPlays = { ...state.plays };
    match.players.forEach(id => { newPlays[id] = (newPlays[id] || 0) + 1; });

    const newRecentRounds = [match.players, ...state.recentRounds].slice(0, 12);
    const newHistory = [...state.history, { ...match, at: Date.now() }].slice(-200);

    upd({ active: newActive, plays: newPlays, recentRounds: newRecentRounds, history: newHistory });
    toast("จบแมตช์ ✓");
  }

  // ── Delete queue item ────────────────────────────────
  function deleteQueue(qId) {
    upd({ queue: state.queue.filter(q => q.id !== qId) });
  }

  // ── Reset session ────────────────────────────────────
  function resetSession() {
    if (!confirm("รีเซ็ตแมตช์และคิวทั้งหมด? ผู้เล่นและสถิติรวมจะยังอยู่")) return;
    upd({ active: {}, queue: [], history: [], plays: {}, recentRounds: [] });
    toast("รีเซ็ตแล้ว");
  }

  function clearAll() {
    if (!confirm("ล้างข้อมูลทั้งหมด รวมถึงผู้เล่น?")) return;
    const fresh = guestDefault();
    setState(fresh);
    try { localStorage.removeItem(GUEST_KEY); } catch (_) {}
    toast("ล้างข้อมูลทั้งหมดแล้ว");
  }

  return (
    <div className="guest-shell">
      {/* ── Topbar ── */}
      <div className="guest-topbar">
        <div className="row gap-2" style={{alignItems:"center"}}>
          <div style={{width:30,height:30,borderRadius:9,background:"linear-gradient(135deg,#ff9f0a,#ff6b00)",display:"grid",placeItems:"center",flexShrink:0}}>
            <Icon name="shuttle" size={15} stroke={2} />
          </div>
          <div>
            <div style={{fontWeight:700, fontSize:15, lineHeight:1.1}}>Guest Mode</div>
            <div style={{fontSize:11, color:"var(--text-3)", lineHeight:1.2}}>
              {state.mode === "double" ? "คู่" : "เดี่ยว"} · {state.courtCount} สนาม · {state.players.length} ผู้เล่น
            </div>
          </div>
        </div>
        <div className="row gap-2">
          <Segmented value={tab} onChange={setTab}
            options={[{value:"play",label:"สนาม & คิว"},{value:"players",label:"ผู้เล่น"}]} />
          <button className="btn sm" onClick={onExit}>
            <Icon name="door" size={13}/> ออก
          </button>
        </div>
      </div>

      {/* ── Content ── */}
      <div className="scroll">
        {tab === "players" && (
          <GuestPlayersTab
            players={state.players}
            plays={state.plays}
            onAdd={addPlayer}
            onRemove={removePlayer}
            onSave={savePlayer}
            onClearAll={clearAll}
            playerById={playerById}
          />
        )}
        {tab === "play" && (
          <GuestMatchTab
            state={state}
            courtIds={courtIds}
            playerById={playerById}
            freeCourts={freeCourts}
            onGenerate={generateQueue}
            onPlace={placeMatch}
            onEnd={endMatch}
            onDeleteQueue={deleteQueue}
            onReset={resetSession}
            onSetMode={m => upd({ mode: m, queue: [], active: {} })}
            onSetCourts={n => upd({ courtCount: n, active: {} })}
            onGoToPlayers={() => setTab("players")}
          />
        )}
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════
   GuestMatchTab — สนาม + คิว
═══════════════════════════════════════════════════════ */
function GuestMatchTab({ state, courtIds, playerById, freeCourts, onGenerate, onPlace, onEnd, onDeleteQueue, onReset, onSetMode, onSetCourts, onGoToPlayers }) {
  const { active, queue, mode, courtCount, players } = state;
  const minPlayers = courtCount * (mode === "double" ? 4 : 2);
  const needMore = players.length < minPlayers;

  return (
    <>
      {/* Settings */}
      <div className="row gap-2 mb-3" style={{flexWrap:"wrap", alignItems:"flex-end"}}>
        <div className="card" style={{padding:"10px 14px", flex:"0 0 auto"}}>
          <div className="row gap-4">
            <div>
              <div style={{fontSize:10,fontWeight:600,color:"var(--text-3)",textTransform:"uppercase",letterSpacing:"0.05em",marginBottom:6}}>โหมด</div>
              <Segmented value={mode} onChange={onSetMode}
                options={[{value:"double",label:"คู่"},{value:"single",label:"เดี่ยว"}]} />
            </div>
            <div>
              <div style={{fontSize:10,fontWeight:600,color:"var(--text-3)",textTransform:"uppercase",letterSpacing:"0.05em",marginBottom:6}}>จำนวนสนาม</div>
              <Segmented value={String(courtCount)} onChange={v => onSetCourts(Number(v))}
                options={["1","2","3","4"].map(v => ({value:v, label:v}))} />
            </div>
          </div>
        </div>
        <div style={{flex:1}}/>
        <button className="btn sm" onClick={onReset}>
          <Icon name="refresh" size={13} stroke={2}/> รีเซ็ต
        </button>
        <button className="btn primary" onClick={onGenerate} disabled={needMore} title={needMore ? `ต้องการผู้เล่น ${minPlayers} คน` : ""}>
          <Icon name="history" size={13}/> สุ่มคิว
        </button>
      </div>

      {needMore && (
        <div className="card card-pad mb-3" style={{background:"var(--orange-soft)", border:"1px solid rgba(255,159,10,0.3)"}}>
          <div className="row gap-2">
            <Icon name="help" size={16}/>
            <div>ต้องการผู้เล่นอย่างน้อย <b>{minPlayers} คน</b> — ตอนนี้มี {players.length} คน
              &nbsp;· <button className="btn ghost sm" style={{display:"inline-flex",padding:"2px 8px"}}
                onClick={onGoToPlayers}>ไปเพิ่มผู้เล่น →</button>
            </div>
          </div>
        </div>
      )}

      {/* Courts */}
      <section>
        <div style={{fontSize:11,fontWeight:600,color:"var(--text-3)",textTransform:"uppercase",letterSpacing:"0.06em",marginBottom:10}}>สนาม</div>
        <div className="guest-courts-grid">
          {courtIds.map((cid, i) => {
            const match = active[cid];
            return match ? (
              <GuestCourtActive key={cid} name={String(i+1)} match={match}
                playerById={playerById} mode={mode} plays={state.plays}
                onEnd={() => onEnd(cid)} />
            ) : (
              <GuestCourtEmpty key={cid} name={String(i+1)}
                canPlace={!!(queue[0] && freeCourts[0] === cid)}
                onPlace={queue[0] ? () => onPlace(queue[0]) : null} />
            );
          })}
        </div>
      </section>

      {/* Queue */}
      {queue.length > 0 && (
        <section>
          <div className="row gap-2 mb-2" style={{alignItems:"center"}}>
            <div style={{fontSize:11,fontWeight:600,color:"var(--text-3)",textTransform:"uppercase",letterSpacing:"0.06em"}}>คิวรอลงสนาม</div>
            <span className="chip" style={{fontSize:11}}>{queue.length}</span>
          </div>
          <div className="queue">
            {queue.map((q, i) => (
              <GuestQueueCard key={q.id} match={q} index={i+1}
                playerById={playerById} mode={mode} plays={state.plays}
                canPlace={freeCourts.length > 0 && i === 0}
                onPlace={() => onPlace(q)}
                onDelete={() => onDeleteQueue(q.id)} />
            ))}
          </div>
        </section>
      )}

      {!Object.keys(active).length && !queue.length && !needMore && (
        <div className="card empty" style={{marginTop:8}}>
          <div className="em">🏸</div>
          <div style={{fontWeight:600}}>พร้อมแล้ว</div>
          <div className="small muted">กด "สุ่มคิว" เพื่อจับคู่ผู้เล่น {players.length} คน ลง {courtCount} สนาม</div>
        </div>
      )}
    </>
  );
}

/* ═══════════════════════════════════════════════════════
   GuestCourtActive — สนามที่กำลังเล่น
═══════════════════════════════════════════════════════ */
function GuestCourtActive({ name, match, playerById, mode, plays, onEnd }) {
  const isDouble = mode === "double";
  const teamA = isDouble ? match.players.slice(0,2) : [match.players[0]];
  const teamB = isDouble ? match.players.slice(2,4) : [match.players[1]];
  const getName = id => playerById[id]?.name?.split(" ")[0] || "?";
  const getLevel = id => Math.round(playerById[id]?.level ?? 0);
  const avgA = (teamA.reduce((s,id) => s + getLevel(id), 0) / teamA.length).toFixed(1);
  const avgB = (teamB.reduce((s,id) => s + getLevel(id), 0) / teamB.length).toFixed(1);

  return (
    <div className="guest-court-card" style={{borderColor:"var(--tint)", borderWidth:1.5}}>
      <div className="guest-court-head">
        <div className="row gap-2">
          <div className="court-num">{name}</div>
          <span className="chip green" style={{fontSize:11}}>● กำลังเล่น</span>
        </div>
        <button className="btn sm primary" onClick={onEnd}>✓ จบแมตช์</button>
      </div>
      <div className="court-net" style={{marginTop:10}}>
        <div className="court-side">
          <div style={{fontSize:11,fontWeight:600,color:"var(--text-3)",marginBottom:6}}>ทีม A · Lv {avgA}</div>
          {teamA.map(id => (
            <div key={id} className="player-pill">
              <div className="avatar" style={{width:28,height:28,fontSize:10,flexShrink:0,
                background:`linear-gradient(135deg,${gHashColor(id)},${gHashColor(id+"z")})`}}>
                {initials(getName(id))}
              </div>
              <div className="grow" style={{fontSize:13,fontWeight:500}}>{getName(id)}</div>
              <LevelPill level={getLevel(id)} />
              <span className="play-count" title="เล่นแล้วกี่รอบ">{plays[id]||0}</span>
            </div>
          ))}
        </div>
        <div className="court-vs">VS</div>
        <div className="court-side">
          <div style={{fontSize:11,fontWeight:600,color:"var(--text-3)",marginBottom:6}}>ทีม B · Lv {avgB}</div>
          {teamB.map(id => (
            <div key={id} className="player-pill">
              <div className="avatar" style={{width:28,height:28,fontSize:10,flexShrink:0,
                background:`linear-gradient(135deg,${gHashColor(id)},${gHashColor(id+"z")})`}}>
                {initials(getName(id))}
              </div>
              <div className="grow" style={{fontSize:13,fontWeight:500}}>{getName(id)}</div>
              <LevelPill level={getLevel(id)} />
              <span className="play-count">{plays[id]||0}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════
   GuestCourtEmpty — สนามว่าง (ไม่แสดง preview ผู้เล่น)
═══════════════════════════════════════════════════════ */
function GuestCourtEmpty({ name, canPlace, onPlace }) {
  return (
    <div className="guest-court-card" style={{borderStyle:"dashed", opacity:0.6}}>
      <div className="guest-court-head">
        <div className="row gap-2">
          <div className="court-num" style={{opacity:0.7}}>{name}</div>
          <span className="small muted">ว่าง</span>
        </div>
        {canPlace && onPlace && (
          <button className="btn sm primary" onClick={onPlace}>
            <Icon name="play" size={12} stroke={2}/> ลงสนาม
          </button>
        )}
      </div>
      <div className="center small muted" style={{marginTop:20, marginBottom:8}}>
        {canPlace ? "กด ลงสนาม เพื่อเริ่มแมตช์" : "ยังไม่มีคิว"}
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════
   GuestQueueCard — คิวรอ
═══════════════════════════════════════════════════════ */
function GuestQueueCard({ match, index, playerById, mode, plays, canPlace, onPlace, onDelete }) {
  const isDouble = mode === "double";
  const teamA = isDouble ? match.players.slice(0,2) : [match.players[0]];
  const teamB = isDouble ? match.players.slice(2,4) : [match.players[1]];
  const getName = id => playerById[id]?.name?.split(" ")[0] || "?";
  const getLv = id => Math.round(playerById[id]?.level ?? 0);

  return (
    <div className="queue-card">
      <div className="queue-head"><span>คิว #{index}</span></div>
      <div className="pair">
        <div className="pair-side">
          {teamA.map(id => (
            <div key={id} className="pname">
              <span>{getName(id)}</span>
              <span className="play-count">{plays[id]||0}</span>
              <LevelPill level={getLv(id)} />
            </div>
          ))}
        </div>
        <div className="pair-vs">VS</div>
        <div className="pair-side">
          {teamB.map(id => (
            <div key={id} className="pname">
              <span>{getName(id)}</span>
              <span className="play-count">{plays[id]||0}</span>
              <LevelPill level={getLv(id)} />
            </div>
          ))}
        </div>
      </div>
      <div className="queue-foot">
        {canPlace ? (
          <button className="btn primary sm" onClick={onPlace}>
            <Icon name="play" size={12} stroke={2.2}/> ลงสนาม
          </button>
        ) : (
          <span className="queue-order-hint">รอสนามว่าง</span>
        )}
        <div className="grow"/>
        <button className="btn icon danger" onClick={onDelete} title="ลบคิวนี้">
          <Icon name="trash" size={12}/>
        </button>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════
   GuestPlayersTab — จัดการผู้เล่น
═══════════════════════════════════════════════════════ */
function GuestPlayersTab({ players, plays, onAdd, onRemove, onSave, onClearAll }) {
  const [name, setName] = usg("");
  const [level, setLevel] = usg("5");
  const [editing, setEditing] = usg(null);

  const submit = (e) => {
    e.preventDefault();
    const n = name.trim();
    const l = parseFloat(level);
    if (!n) return;
    if (isNaN(l) || l < 1 || l > 10) return;
    if (editing) {
      onSave(editing, n, l);
      setEditing(null);
    } else {
      onAdd(n, l);
    }
    setName(""); setLevel("5");
  };

  const cancelEdit = () => { setEditing(null); setName(""); setLevel("5"); };
  const startEdit = (p) => { setEditing(p.id); setName(p.name); setLevel(String(p.level)); };

  const sorted = [...players].sort((a, b) => b.level - a.level);
  const totalPlays = Object.values(plays).reduce((s, v) => s + v, 0);

  return (
    <>
      {/* Add / Edit form */}
      <div className="card card-pad mb-3">
        <div style={{fontWeight:600, marginBottom:10, fontSize:14}}>
          {editing ? "✏️ แก้ไขผู้เล่น" : "➕ เพิ่มผู้เล่น"}
        </div>
        <form onSubmit={submit}>
          <div className="row gap-2" style={{flexWrap:"wrap"}}>
            <input value={name} onChange={e => setName(e.target.value)}
              placeholder="ชื่อผู้เล่น" autoFocus
              style={{flex:"1 1 140px", minWidth:120}} />
            <div className="row gap-1" style={{alignItems:"center", flex:"0 0 auto"}}>
              <span className="small muted">Lv</span>
              <input type="number" value={level} onChange={e => setLevel(e.target.value)}
                min="1" max="10" step="1"
                style={{width:60, textAlign:"center"}} />
            </div>
            <div className="row gap-1" style={{flex:"0 0 auto"}}>
              <button type="submit" className="btn primary">
                {editing ? <><Icon name="check" size={13}/> บันทึก</> : <><Icon name="plus" size={13} stroke={2.2}/> เพิ่ม</>}
              </button>
              {editing && (
                <button type="button" className="btn" onClick={cancelEdit}>ยกเลิก</button>
              )}
            </div>
          </div>
          <div className="hint" style={{marginTop:6}}>
            ระดับ 1 (มือใหม่) – 10 (โปร)
          </div>
        </form>
      </div>

      {/* Player list */}
      <div className="card">
        {sorted.length === 0 && (
          <div className="empty" style={{padding:"24px 0"}}>
            <div className="em">👥</div>
            <div>ยังไม่มีผู้เล่น</div>
            <div className="small muted">เพิ่มผู้เล่นด้านบนก่อนเริ่มจับคู่</div>
          </div>
        )}
        {sorted.map(p => (
          <div key={p.id} className="card-row">
            <div className="avatar" style={{width:34,height:34,fontSize:11,flexShrink:0,
              background:`linear-gradient(135deg,${gHashColor(p.id)},${gHashColor(p.id+"z")})`}}>
              {initials(p.name)}
            </div>
            <div className="grow">
              <div style={{fontWeight:500}}>{p.name}</div>
              <div className="small muted">เล่นแล้ว {plays[p.id]||0} รอบ</div>
            </div>
            <LevelPill level={Math.round(p.level)} />
            <button className="btn icon" onClick={() => startEdit(p)} title="แก้ไข">
              <Icon name="edit" size={13}/>
            </button>
            <button className="btn icon danger" onClick={() => onRemove(p.id)} title="ลบ">
              <Icon name="trash" size={13}/>
            </button>
          </div>
        ))}
        {sorted.length > 0 && (
          <div className="card-row" style={{background:"var(--bg-elev-2)",fontSize:12,color:"var(--text-3)",flexWrap:"wrap",gap:8}}>
            <span>{players.length} คน</span>
            <span>·</span>
            <span>เล่นรวม {totalPlays} รอบ</span>
            <div style={{flex:1}}/>
            <button className="btn sm" style={{color:"var(--red)"}} onClick={onClearAll}>ล้างทั้งหมด</button>
          </div>
        )}
      </div>
    </>
  );
}

Object.assign(window, { GuestApp });
