/* global React, ReactDOM */
const { useState, useEffect, useMemo, useRef } = React;

// Read these dynamically — window.QUESTIONS_BANK is replaced after questions.json
// loads, so don't snapshot at module load.
const AVATARS = window.AVATARS;
const LEADERBOARD_SEED = window.LEADERBOARD_SEED;

const shuffle = (arr) => {
  const a = [...arr];
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
};

// ===== Seen-question tracking (per device, persists across sessions) =====
const SEEN_KEY = "trivia_seen_ids";
const GEN_KEY = "trivia_generated_questions";
const GEN_MAX = 200; // cap stored generated questions per device

const getSeenIds = () => {
  try {
    const raw = localStorage.getItem(SEEN_KEY);
    return new Set(raw ? JSON.parse(raw) : []);
  } catch { return new Set(); }
};

// Load previously generated questions and merge them into window.QUESTIONS_BANK.
const loadGeneratedQuestions = () => {
  try {
    const raw = localStorage.getItem(GEN_KEY);
    return raw ? JSON.parse(raw) : [];
  } catch { return []; }
};

const saveGeneratedQuestions = (qs) => {
  try {
    const trimmed = qs.slice(-GEN_MAX);
    localStorage.setItem(GEN_KEY, JSON.stringify(trimmed));
  } catch {}
};

// Fetch fresh questions from the deployed Cloudflare Worker.
async function fetchGeneratedQuestions(count = 16) {
  const url = window.TRIVIA_WORKER_URL;
  if (!url) throw new Error("worker not configured");
  const bank = window.QUESTIONS_BANK || [];
  // Send recent question texts so the model avoids semantic duplicates
  const exclude = bank.slice(-60).map((q) => q.question).filter(Boolean);
  const res = await fetch(url.replace(/\/$/, "") + "/generate", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ count, exclude }),
  });
  if (!res.ok) {
    const err = await res.text().catch(() => "");
    throw new Error("worker " + res.status + ": " + err.slice(0, 200));
  }
  const data = await res.json();
  if (!Array.isArray(data?.questions) || data.questions.length === 0) {
    throw new Error("no questions returned");
  }
  return data.questions;
}

// Add fresh generated questions to the in-memory bank + persist.
function appendGeneratedQuestions(newQs) {
  const existing = loadGeneratedQuestions();
  const merged = [...existing, ...newQs];
  saveGeneratedQuestions(merged);
  window.QUESTIONS_BANK = [...(window.QUESTIONS_BANK || []), ...newQs];
  return newQs.length;
}

const saveSeenIds = (set) => {
  try { localStorage.setItem(SEEN_KEY, JSON.stringify([...set])); } catch {}
};

const markSeen = (ids) => {
  const list = Array.isArray(ids) ? ids : [ids];
  const set = getSeenIds();
  list.forEach((id) => { if (id != null) set.add(id); });
  saveSeenIds(set);
  return set;
};

const resetSeen = () => { try { localStorage.removeItem(SEEN_KEY); } catch {} };

const buildQuizPool = (count = 8) => {
  const bank = window.QUESTIONS_BANK || [];
  const seen = getSeenIds();
  let unseen = bank.filter((q) => q.id == null || !seen.has(q.id));
  // Pool exhausted → reset seen, draw from full bank again
  if (unseen.length < count) {
    resetSeen();
    unseen = bank;
  }
  return shuffle(unseen).slice(0, count).map((q) => {
    const idxs = shuffle([0, 1, 2, 3]);
    return {
      id: q.id,
      category: q.category,
      question: q.question,
      options: idxs.map((i) => q.options[i]),
      correct: idxs.indexOf(q.correct),
    };
  });
};

// ===== خلفية زخرفية =====
function BgDecor() {
  return (
    <div className="bg-decor" aria-hidden="true">
      <svg className="bg-blob-1" width="380" height="380" viewBox="0 0 200 200">
        <circle cx="100" cy="100" r="92" fill="var(--c-pink)" stroke="var(--c-ink)" strokeWidth="4" />
      </svg>
      <svg className="bg-blob-2" width="320" height="320" viewBox="0 0 200 200">
        <polygon points="100,10 130,80 195,90 145,135 160,195 100,160 40,195 55,135 5,90 70,80" fill="var(--c-yellow)" stroke="var(--c-ink)" strokeWidth="4"/>
      </svg>
      <svg className="bg-blob-3" width="260" height="260" viewBox="0 0 200 200">
        <circle cx="100" cy="100" r="92" fill="var(--c-teal)" stroke="var(--c-ink)" strokeWidth="4"/>
      </svg>
      <svg className="bg-blob-4" width="120" height="120" viewBox="0 0 200 200">
        <rect x="20" y="20" width="160" height="160" rx="36" fill="var(--c-purple)" stroke="var(--c-ink)" strokeWidth="6" transform="rotate(15 100 100)"/>
      </svg>
    </div>
  );
}

// ===== شريط علوي =====
function TopBar({ theme, onToggleTheme, screen, onHome }) {
  return (
    <div className="top-bar">
      <div className="brand">
        <span className="brand-mark">🎯</span>
        <span>لعبة المعلومات</span>
      </div>
      <div style={{ display: "flex", gap: 10 }}>
        {screen !== "home" && (
          <button className="theme-toggle" onClick={onHome} title="الرئيسية" aria-label="الرئيسية">🏠</button>
        )}
        <button className="theme-toggle" onClick={onToggleTheme} aria-label="تبديل الثيم">
          {theme === "dark" ? "☀️" : "🌙"}
        </button>
      </div>
    </div>
  );
}

// ===== HomeMenu (mode picker) =====
function HomeMenu({ onPick, hi, totalQuestions, onResetSeen, seenSignal, onGenerate, generating, generateError, country }) {
  // Re-compute remaining whenever totalQuestions or seenSignal changes.
  const remaining = useMemo(() => {
    const bank = window.QUESTIONS_BANK || [];
    const seen = getSeenIds();
    return bank.filter((q) => q.id == null || !seen.has(q.id)).length;
  }, [totalQuestions, seenSignal]);

  return (
    <div className="home">
      <div className="home-hero">
        <span className="home-eyebrow">⚡ تحدّي عائلي</span>
        <h1 className="home-title">
          <span className="word w1">لعبة</span>{" "}
          <span className="word w2">المعلومات</span>
        </h1>
        <p className="home-subtitle">
          العب بمفردك أو تحدَّ أصدقاءك في غرفة مباشرة. ٨ أسئلة، ١٥ ثانية، نقاط حسب السرعة.
        </p>
      </div>

      <div className="mode-grid">
        <button className="mode-btn mode-sp" onClick={() => onPick("sp")}>
          <div className="mode-icon">🎯</div>
          <div className="mode-title">لاعب واحد</div>
          <div className="mode-desc">تحدَّ نفسك</div>
        </button>
        <button className="mode-btn mode-create" onClick={() => onPick("create")}>
          <div className="mode-icon">👑</div>
          <div className="mode-title">إنشاء غرفة</div>
          <div className="mode-desc">ادعُ الأصدقاء</div>
        </button>
        <button className="mode-btn mode-join" onClick={() => onPick("join")}>
          <div className="mode-icon">🚪</div>
          <div className="mode-title">انضم بغرفة</div>
          <div className="mode-desc">باستخدام رمز</div>
        </button>
      </div>

      <div className="renew-row">
        <span className="renew-pill">
          🆕 <b>{remaining}</b> سؤال جديد متبقي من أصل <b>{totalQuestions}</b>
        </span>
        {window.TRIVIA_WORKER_URL && (
          <button className="renew-reset" onClick={onGenerate} disabled={generating}>
            {generating ? "⏳ جارٍ التوليد..." : "✨ أسئلة جديدة من Claude"}
          </button>
        )}
        <button className="renew-reset" onClick={onResetSeen}>
          ↻ إعادة تعيين
        </button>
      </div>
      {generateError && (
        <div className="error-msg" style={{ maxWidth: 520, margin: "0 auto" }}>{generateError}</div>
      )}

      {country && (
        <div style={{ textAlign: "center", color: "var(--c-ink-soft)", fontWeight: 700, fontSize: 13 }}>
          📍 موقعك: <span style={{ fontSize: 18 }}>{country.flag}</span> {country.name}
        </div>
      )}

      {hi > 0 && (
        <div style={{ textAlign: "center", color: "var(--c-ink-soft)", fontWeight: 700, fontSize: 14 }}>
          أعلى نتيجة لك (لاعب واحد): <span style={{ color: "var(--c-pink)" }}>{hi}</span>
        </div>
      )}
    </div>
  );
}

// ===== Setup (name + avatar) — used for both SP and MP =====
function SetupCard({ title, subtitle, name, setName, avatar, setAvatar, extra, primaryLabel, onPrimary, onCancel, busy, error, primaryDisabled }) {
  return (
    <div className="home">
      <div className="home-hero">
        <span className="home-eyebrow">{subtitle}</span>
        <h1 className="home-title">
          <span className="word w1">{title.split(" ")[0]}</span>{" "}
          <span className="word w2">{title.split(" ").slice(1).join(" ")}</span>
        </h1>
      </div>

      <div className="home-card">
        {extra}
        <div className="section-label">اختر اسمك</div>
        <input
          className="name-input"
          placeholder="مثال: لينا"
          value={name}
          onChange={(e) => setName(e.target.value.slice(0, 18))}
          maxLength={18}
        />

        <div className="section-label" style={{ marginTop: 24 }}>اختر شخصيتك</div>
        <div className="avatar-grid">
          {AVATARS.map((a) => (
            <button
              key={a.id}
              className={`avatar-tile ${avatar === a.id ? "is-selected" : ""}`}
              onClick={() => setAvatar(a.id)}
              title={a.name}
              aria-label={a.name}
            >
              {a.emoji}
            </button>
          ))}
        </div>

        {error && <div className="error-msg">{error}</div>}

        <div className="result-actions" style={{ marginTop: 22 }}>
          <button className="btn btn-secondary" onClick={onCancel}>← رجوع</button>
          <button
            className="btn btn-primary"
            disabled={busy || primaryDisabled || !name.trim() || avatar === null}
            onClick={onPrimary}
          >
            {busy ? "..." : primaryLabel}
          </button>
        </div>
      </div>
    </div>
  );
}

// ===== المؤقت الدائري =====
function TimerRing({ remaining, total }) {
  const pct = remaining / total;
  const r = 30;
  const c = 2 * Math.PI * r;
  const offset = c * (1 - pct);
  const isLow = remaining <= 10;
  const isCritical = remaining <= 5;
  return (
    <div className="timer-ring-wrap">
      <div className={`timer-ring ${isCritical ? "is-critical" : isLow ? "is-low" : ""}`}>
        <svg width="68" height="68">
          <circle cx="34" cy="34" r={r} fill="none" stroke="var(--c-bg-2)" strokeWidth="6" />
          <circle
            cx="34" cy="34" r={r}
            fill="none"
            stroke={isCritical ? "var(--c-ink)" : "var(--c-purple)"}
            strokeWidth="6"
            strokeLinecap="round"
            strokeDasharray={c}
            strokeDashoffset={offset}
            style={{ transition: "stroke-dashoffset 1s linear" }}
          />
        </svg>
        <span className="num">{remaining}</span>
      </div>
    </div>
  );
}

function Heart({ lost }) {
  return (
    <svg className={`heart ${lost ? "lost" : ""}`} viewBox="0 0 24 24">
      <path d="M12 21s-7-4.5-9.5-9C0.5 8 3 4 7 4c2 0 3.5 1 5 3 1.5-2 3-3 5-3 4 0 6.5 4 4.5 8C19 16.5 12 21 12 21z"
        fill={lost ? "var(--c-ink-soft)" : "var(--c-pink)"} stroke="var(--c-ink)" strokeWidth="2" strokeLinejoin="round" />
    </svg>
  );
}

// ===== Single-Player Quiz =====
function QuestionScreen({ player, qIndex, total, question, score, lives, streak, timer, onAnswer, locked, lastPick }) {
  const colors = ["p", "y", "t", "u"];
  const letters = ["أ", "ب", "ج", "د"];
  return (
    <div className="quiz">
      <div className="quiz-hud">
        <div className="hud-pill hud-score">
          <span className="ico">⭐</span>
          <span className="num">{score}</span>
        </div>
        <div className="progress-track">
          <div className="progress-fill" style={{ width: `${((qIndex) / total) * 100}%` }}></div>
        </div>
        <div className="hud-pill hud-lives" aria-label={`أرواح متبقية ${lives}`}>
          {[0,1,2].map(i => <Heart key={i} lost={i >= lives} />)}
        </div>
      </div>

      <div className="player-strip">
        <div className="av">{AVATARS[player.avatar].emoji}</div>
        <div className="name">{player.name}</div>
        {streak >= 2 && <div className="streak">سلسلة ×{streak}</div>}
      </div>

      <div className="question-card">
        <TimerRing remaining={timer} total={15} />
        <div className="q-meta" style={{ marginTop: 8, paddingRight: 96 }}>
          <span className="cat-tag">📚 {question.category}</span>
          <span className="q-num">سؤال {qIndex + 1} / {total}</span>
        </div>
        <div className="q-text">{question.question}</div>
        <div className="options-grid">
          {question.options.map((opt, i) => {
            let cls = "option-btn";
            if (locked) {
              if (i === question.correct) cls += " is-correct";
              else if (i === lastPick) cls += " is-wrong";
              else cls += " is-faded";
            }
            return (
              <button key={i} className={cls} data-color={colors[i]} onClick={() => onAnswer(i)} disabled={locked}>
                <span className="option-letter">{letters[i]}</span>
                <span>{opt}</span>
              </button>
            );
          })}
        </div>
      </div>
    </div>
  );
}

function ResultScreen({ correct, gained, timeBonus, totalScore, isLast, onNext, lives, correctAnswerText }) {
  const fact = correct
    ? ["رهيب! 🎉", "ممتاز!", "أحسنت!", "بطل/ة!"][Math.floor(Math.random()*4)]
    : ["للأسف خاطئ", "حاول مرة أخرى", "لا بأس!", "قريب جدًا"][Math.floor(Math.random()*4)];
  return (
    <div className={`result ${correct ? "result-correct" : "result-wrong"}`}>
      <div className="result-card">
        <div className="result-emoji">{correct ? "🎉" : (lives === 0 ? "💔" : "😅")}</div>
        <h2 className="result-headline">{fact}</h2>
        <p className="result-body">
          {correct
            ? <>الإجابة <b>صحيحة</b>. كلما أسرعت كلما زادت نقاطك!</>
            : <>الإجابة الصحيحة كانت: <b>{correctAnswerText}</b></>}
        </p>
        <div className="points-row">
          <div className="points-cell gain"><div className="lbl">نقاط السؤال</div><div className="val">+{gained}</div></div>
          <div className="points-cell time"><div className="lbl">مكافأة السرعة</div><div className="val">+{timeBonus}</div></div>
          <div className="points-cell total"><div className="lbl">المجموع</div><div className="val">{totalScore}</div></div>
        </div>
        <div className="result-actions">
          <button className="btn btn-primary" onClick={onNext}>
            {isLast || lives === 0 ? "النتيجة النهائية ←" : "السؤال التالي ←"}
          </button>
        </div>
      </div>
    </div>
  );
}

function EndScreen({ player, score, correctCount, total, onPlayAgain, onLeaderboard }) {
  const pct = total > 0 ? (correctCount / total) * 100 : 0;
  const tier = pct >= 80 ? { emoji: "🏆", title: "أسطورة المعلومات!", c: "var(--c-yellow)" }
    : pct >= 50 ? { emoji: "⭐", title: "أداء رائع!", c: "var(--c-pink)" }
    : { emoji: "💪", title: "محاولة جيدة", c: "var(--c-teal)" };
  return (
    <div className="end-state">
      <div className="result-card" style={{ background: tier.c }}>
        <div className="result-emoji">{tier.emoji}</div>
        <h1 className="end-headline">{tier.title}</h1>
        <p className="result-body" style={{ color: "var(--c-ink)" }}>
          أجبت بشكل صحيح على <b>{correctCount}</b> من <b>{total}</b> أسئلة
        </p>
        <div className="end-tags">
          <div className="end-tag">⭐ {score} نقطة</div>
          <div className="end-tag">{AVATARS[player.avatar].emoji} {player.name}</div>
          <div className="end-tag">📊 {Math.round(pct)}%</div>
        </div>
        <div className="result-actions" style={{ marginTop: 18 }}>
          <button className="btn btn-secondary" onClick={onPlayAgain}>↻ إعادة اللعب</button>
          <button className="btn btn-primary" onClick={onLeaderboard}>لوحة المتصدرين 🏅</button>
        </div>
      </div>
    </div>
  );
}

function Leaderboard({ player, score, onBack }) {
  const all = useMemo(() => {
    const me = score > 0 && player.avatar !== null
      ? [{ name: player.name + " (أنت)", avatar: player.avatar, score, isSelf: true, streak: 0 }]
      : [];
    return [...LEADERBOARD_SEED, ...me].sort((a, b) => b.score - a.score);
  }, [player, score]);
  const top3 = all.slice(0, 3);
  const rest = all.slice(3);
  return (
    <div className="lb">
      <div className="home-hero">
        <span className="home-eyebrow">🏅 الأبطال</span>
        <h1 className="home-title" style={{ fontSize: "clamp(40px,7vw,72px)" }}>
          <span className="word w1">لوحة</span> <span className="word w2">المتصدّرين</span>
        </h1>
      </div>
      {top3.length >= 3 && (
        <div className="lb-podium">
          <div className="podium-cell silver"><div className="rank">2</div><div className="podium-av">{AVATARS[top3[1].avatar].emoji}</div><div className="podium-name">{top3[1].name}</div><div className="podium-score">{top3[1].score}</div></div>
          <div className="podium-cell gold"><div className="rank">1</div><div className="podium-av">{AVATARS[top3[0].avatar].emoji}</div><div className="podium-name">{top3[0].name}</div><div className="podium-score">{top3[0].score}</div></div>
          <div className="podium-cell bronze"><div className="rank">3</div><div className="podium-av">{AVATARS[top3[2].avatar].emoji}</div><div className="podium-name">{top3[2].name}</div><div className="podium-score">{top3[2].score}</div></div>
        </div>
      )}
      <div className="lb-list">
        {rest.map((row, i) => (
          <div key={i} className={`lb-row ${row.isSelf ? "is-self" : ""}`}>
            <div className="lb-rank">#{i + 4}</div>
            <div className="lb-av">{AVATARS[row.avatar].emoji}</div>
            <div>
              <div className="lb-name">{row.name}</div>
              {row.streak > 0 && <div className="lb-streak">🔥 سلسلة {row.streak}</div>}
            </div>
            <div></div>
            <div className="lb-score">{row.score}</div>
          </div>
        ))}
      </div>
      <div style={{ display: "flex", justifyContent: "center" }}>
        <button className="btn btn-yellow" style={{ flex: "0 0 auto", padding: "16px 36px" }} onClick={onBack}>← رجوع</button>
      </div>
    </div>
  );
}

function Confetti({ active }) {
  if (!active) return null;
  const pieces = Array.from({ length: 36 });
  const colors = ["var(--c-pink)", "var(--c-yellow)", "var(--c-teal)", "var(--c-purple)", "var(--c-green)"];
  return (
    <>
      {pieces.map((_, i) => (
        <span key={i} className="confetti-piece" style={{
          left: `${Math.random() * 100}%`,
          background: colors[i % colors.length],
          border: "2px solid var(--c-ink)",
          animationDelay: `${Math.random() * 0.4}s`,
          animationDuration: `${1.4 + Math.random() * 0.8}s`,
          transform: `rotate(${Math.random() * 360}deg)`,
          borderRadius: i % 3 === 0 ? "50%" : "2px",
        }} />
      ))}
    </>
  );
}

// ===== Single Player flow (unchanged from original) =====
function SinglePlayerGame({ onExit, hi, setHi }) {
  const [screen, setScreen] = useState("setup");
  const [name, setName] = useState("");
  const [avatar, setAvatar] = useState(null);
  const [questions, setQuestions] = useState([]);
  const [qIndex, setQIndex] = useState(0);
  const [score, setScore] = useState(0);
  const [lives, setLives] = useState(3);
  const [streak, setStreak] = useState(0);
  const [correctCount, setCorrectCount] = useState(0);
  const [timer, setTimer] = useState(15);
  const [locked, setLocked] = useState(false);
  const [lastPick, setLastPick] = useState(null);
  const [lastResult, setLastResult] = useState(null);

  useEffect(() => {
    if (screen !== "quiz" || locked) return;
    if (timer <= 0) { handleAnswer(-1); return; }
    const t = setTimeout(() => setTimer((s) => s - 1), 1000);
    return () => clearTimeout(t);
  }, [screen, timer, locked]);

  function startGame() {
    setQuestions(buildQuizPool(8));
    setQIndex(0); setScore(0); setLives(3); setStreak(0); setCorrectCount(0);
    setTimer(15); setLocked(false); setLastPick(null);
    setScreen("quiz");
  }

  function handleAnswer(pickIdx) {
    if (locked) return;
    const q = questions[qIndex];
    if (q?.id != null) markSeen(q.id);
    const correct = pickIdx === q.correct;
    const timeBonus = correct ? Math.max(0, timer * 10) : 0;
    const base = correct ? 50 : 0;
    const streakBonus = correct && streak >= 1 ? streak * 20 : 0;
    const gained = base + streakBonus;
    const totalGained = gained + timeBonus;

    setLocked(true);
    setLastPick(pickIdx);
    if (correct) {
      setScore((s) => s + totalGained);
      setStreak((s) => s + 1);
      setCorrectCount((c) => c + 1);
    } else {
      setLives((l) => l - 1);
      setStreak(0);
    }
    setLastResult({ correct, gained, timeBonus, totalScore: score + (correct ? totalGained : 0) });
    setTimeout(() => setScreen("result"), 900);
  }

  function nextQuestion() {
    const isLast = qIndex >= questions.length - 1;
    if (isLast || lives <= 0) {
      if (score > hi) { setHi(score); localStorage.setItem("trivia_hi", String(score)); }
      setScreen("end");
    } else {
      setQIndex((i) => i + 1);
      setTimer(15); setLocked(false); setLastPick(null);
      setScreen("quiz");
    }
  }

  const player = { name, avatar };
  const showConfetti = screen === "result" && lastResult?.correct;

  return (
    <>
      {screen === "setup" && (
        <SetupCard
          subtitle="🎯 لاعب واحد"
          title="ابدأ التحدي"
          name={name} setName={setName}
          avatar={avatar} setAvatar={setAvatar}
          primaryLabel="🚀 ابدأ التحدّي"
          onPrimary={startGame}
          onCancel={onExit}
        />
      )}
      {screen === "quiz" && questions[qIndex] && (
        <QuestionScreen
          player={player} qIndex={qIndex} total={questions.length}
          question={questions[qIndex]} score={score} lives={lives} streak={streak}
          timer={timer} onAnswer={handleAnswer} locked={locked} lastPick={lastPick}
        />
      )}
      {screen === "result" && lastResult && (
        <ResultScreen
          correct={lastResult.correct} gained={lastResult.gained}
          timeBonus={lastResult.timeBonus} totalScore={lastResult.totalScore}
          isLast={qIndex >= questions.length - 1} lives={lives}
          correctAnswerText={questions[qIndex]?.options[questions[qIndex].correct]}
          onNext={nextQuestion}
        />
      )}
      {screen === "end" && (
        <EndScreen
          player={player} score={score} correctCount={correctCount}
          total={questions.length}
          onPlayAgain={startGame}
          onLeaderboard={() => setScreen("leaderboard")}
        />
      )}
      {screen === "leaderboard" && (
        <Leaderboard player={player} score={score} onBack={onExit} />
      )}
      <Confetti active={showConfetti} />
    </>
  );
}

// ===== Multiplayer setup (create/join) =====
function MPSetup({ mode, onSuccess, onCancel, country }) {
  const [name, setName] = useState("");
  const [avatar, setAvatar] = useState(null);
  const [code, setCode] = useState("");
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");

  async function submit() {
    if (!name.trim() || avatar === null) return;
    if (mode === "join" && code.trim().length !== 4) {
      setError("رمز الغرفة 4 أحرف");
      return;
    }
    setBusy(true); setError("");
    try {
      const payload = { name: name.trim(), avatar, country: country?.code || null };
      const r = mode === "create"
        ? await window.MP.createRoom(payload)
        : await window.MP.joinRoom(code, payload);
      onSuccess(r.code, r.playerId);
    } catch (e) {
      setError(e.message || "حدث خطأ");
      setBusy(false);
    }
  }

  return (
    <SetupCard
      subtitle={mode === "create" ? "👑 إنشاء غرفة" : "🚪 انضم بغرفة"}
      title={mode === "create" ? "غرفة جديدة" : "ادخل الغرفة"}
      name={name} setName={setName}
      avatar={avatar} setAvatar={setAvatar}
      extra={mode === "join" && (
        <>
          <div className="section-label">رمز الغرفة</div>
          <input
            className="name-input code-input"
            placeholder="ABCD"
            value={code}
            onChange={(e) => setCode(e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, 4))}
            maxLength={4}
          />
          <div style={{ height: 18 }} />
        </>
      )}
      primaryLabel={mode === "create" ? "أنشئ الغرفة" : "انضم"}
      onPrimary={submit}
      onCancel={onCancel}
      busy={busy}
      error={error}
      primaryDisabled={mode === "join" && code.length !== 4}
    />
  );
}

// ===== Multiplayer Lobby =====
function Lobby({ room, code, playerId, onLeave }) {
  const me = room.players?.[playerId];
  if (!me) return null;
  const isHost = !!me.isHost;
  const players = Object.entries(room.players || {})
    .map(([id, p]) => ({ ...p, id }))
    .sort((a, b) => (a.joinedAt || 0) - (b.joinedAt || 0));
  const [copied, setCopied] = useState(false);

  function copyCode() {
    if (navigator.clipboard) {
      navigator.clipboard.writeText(code).then(() => {
        setCopied(true);
        setTimeout(() => setCopied(false), 1500);
      });
    }
  }

  async function handleStart() {
    if (!isHost) return;
    const pool = buildQuizPool(window.MP.TOTAL_QUESTIONS);
    await window.MP.startRoom(code, pool);
  }

  return (
    <div className="home">
      <div className="home-hero">
        <span className="home-eyebrow">🎮 غرفة اللعب</span>
        <h1 className="home-title" style={{ fontSize: "clamp(48px, 11vw, 96px)" }}>
          <span className="word w1">رمز</span> <span className="word w2">{code}</span>
        </h1>
        <button className="nav-pill" onClick={copyCode}>{copied ? "✓ نُسخ" : "📋 نسخ الرمز"}</button>
      </div>
      <div className="home-card">
        <div className="section-label">اللاعبون ({players.length})</div>
        <div className="lobby-players">
          {players.map((p) => (
            <div key={p.id} className={`lobby-player ${p.id === playerId ? "is-self" : ""}`}>
              <div className="lobby-av">{AVATARS[p.avatar].emoji}</div>
              <div className="lobby-info">
                <div className="lobby-name">
                  {p.country && <span title={window.arabicCountryName?.(p.country)} style={{ marginLeft: 4 }}>{window.codeToFlag?.(p.country)}</span>}
                  {p.name}{p.id === playerId ? " (أنت)" : ""}
                </div>
                {p.isHost && <div className="lobby-host">👑 مضيف</div>}
              </div>
            </div>
          ))}
        </div>
        {isHost ? (
          <button className="start-btn" style={{ marginTop: 18 }} onClick={handleStart}>
            🚀 ابدأ اللعبة
          </button>
        ) : (
          <div className="lobby-waiting">في انتظار المضيف لبدء اللعبة...</div>
        )}
        <button className="btn btn-secondary" style={{ marginTop: 12, width: "100%" }} onClick={onLeave}>← مغادرة الغرفة</button>
      </div>
    </div>
  );
}

// ===== Live scoreboard during MP game =====
function MPLiveBoard({ players, myId }) {
  return (
    <div className="mp-board">
      {players.map((p, i) => (
        <div key={p.id} className={`mp-board-row ${p.id === myId ? "is-self" : ""}`}>
          <div className="mp-board-rank">#{i + 1}</div>
          <div className="mp-board-av">{AVATARS[p.avatar].emoji}</div>
          <div className="mp-board-name">
            {p.country && <span style={{ marginLeft: 4 }}>{window.codeToFlag?.(p.country)}</span>}
            {p.name}{p.id === myId ? " (أنت)" : ""}
          </div>
          <div className="mp-board-score">{p.score || 0}</div>
        </div>
      ))}
    </div>
  );
}

// ===== Multiplayer Game (synced quiz) =====
function MPGame({ room, code, playerId, onLeave }) {
  const me = room.players[playerId];
  const questions = room.questions || [];
  const total = questions.length || window.MP.TOTAL_QUESTIONS;

  // Per-player local pace — each player gets a fresh 15s for every question,
  // counted from when THEY first see it. The room only synchronizes scores
  // and the question pool; not the per-question countdown.
  const [qIndex, setQIndex] = useState(0);
  const [timer, setTimer] = useState(15);
  const [phase, setPhase] = useState("question"); // question | result | done
  const [lastPick, setLastPick] = useState(null);
  const [lastResult, setLastResult] = useState(null);

  const handleAnswerRef = useRef(null);

  // Local 1-second countdown during question phase. Times out → handleAnswer(-1).
  useEffect(() => {
    if (phase !== "question") return;
    if (timer <= 0) { handleAnswerRef.current?.(-1); return; }
    const t = setTimeout(() => setTimer((s) => s - 1), 1000);
    return () => clearTimeout(t);
  }, [timer, phase]);

  async function handleAnswer(pickIdx) {
    if (phase !== "question") return;
    const q = questions[qIndex];
    if (!q) return;

    if (q.id != null) markSeen(q.id);

    const correct = pickIdx === q.correct;
    const timeBonus = correct ? Math.max(0, timer * 10) : 0;
    const base = correct ? 50 : 0;
    const myStreak = me.streak || 0;
    const streakBonus = correct && myStreak >= 1 ? myStreak * 20 : 0;
    const gained = base + streakBonus;
    const newStreak = correct ? myStreak + 1 : 0;
    const newScore = (me.score || 0) + gained + timeBonus;
    const newCorrect = (me.correctCount || 0) + (correct ? 1 : 0);

    setLastPick(pickIdx);
    setLastResult({ correct, gained, timeBonus });
    setPhase("result");

    try {
      await window.MP.submitAnswer(code, playerId, qIndex, {
        pickIdx, correct, gained, timeBonus,
        score: newScore, correctCount: newCorrect, streak: newStreak,
      });
    } catch (e) {
      console.error("submitAnswer failed", e);
    }

    setTimeout(() => {
      const next = qIndex + 1;
      if (next >= total) {
        setPhase("done");
        try { window.FB_DB.ref("rooms/" + code + "/players/" + playerId).update({ done: true }); } catch {}
      } else {
        setQIndex(next);
        setTimer(15);
        setLastPick(null);
        setLastResult(null);
        setPhase("question");
      }
    }, 2800);
  }
  handleAnswerRef.current = handleAnswer;

  // Any player can trigger room-end once everyone has finished — this avoids
  // the room being stuck if the host leaves before others finish.
  useEffect(() => {
    if (room.meta?.state !== "playing") return;
    const ps = Object.values(room.players || {});
    if (ps.length > 0 && ps.every((p) => p.done)) {
      window.MP.endRoom(code).catch(() => {});
    }
  }, [room.players, room.meta?.state, code]);

  const players = Object.entries(room.players || {})
    .map(([id, p]) => ({ ...p, id }))
    .sort((a, b) => (b.score || 0) - (a.score || 0));
  const finishedCount = players.filter((p) => p.done).length;

  if (phase === "done") {
    return (
      <div className="quiz">
        <div className="quiz-hud">
          <div className="hud-pill hud-score">
            <span className="ico">⭐</span>
            <span className="num">{me.score || 0}</span>
          </div>
          <div className="progress-track">
            <div className="progress-fill" style={{ width: "100%" }}></div>
          </div>
          <div className="hud-pill" title="رمز الغرفة"><span className="ico">🎮</span><span style={{fontFamily:"Cairo", fontWeight:900}}>{code}</span></div>
        </div>
        <MPLiveBoard players={players} myId={playerId} />
        <div className="result-card" style={{ textAlign: "center" }}>
          <div className="result-emoji">⏳</div>
          <h2 className="result-headline" style={{ color: "var(--c-purple)" }}>أنهيت!</h2>
          <p className="result-body">في انتظار باقي اللاعبين... ({finishedCount} / {players.length})</p>
        </div>
      </div>
    );
  }

  const question = questions[qIndex];
  if (!question) {
    return (
      <div className="home">
        <div className="home-hero"><h2 className="home-title" style={{fontSize:"clamp(28px,5vw,44px)"}}>جارٍ التحميل...</h2></div>
      </div>
    );
  }

  const colors = ["p", "y", "t", "u"];
  const letters = ["أ", "ب", "ج", "د"];

  return (
    <div className="quiz">
      <div className="quiz-hud">
        <div className="hud-pill hud-score">
          <span className="ico">⭐</span>
          <span className="num">{me.score || 0}</span>
        </div>
        <div className="progress-track">
          <div className="progress-fill" style={{ width: `${(qIndex / total) * 100}%` }}></div>
        </div>
        <div className="hud-pill" title="رمز الغرفة"><span className="ico">🎮</span><span style={{fontFamily:"Cairo", fontWeight:900}}>{code}</span></div>
      </div>

      <MPLiveBoard players={players} myId={playerId} />

      <div className="question-card">
        <TimerRing remaining={timer} total={15} />
        <div className="q-meta" style={{ marginTop: 8, paddingRight: 96 }}>
          <span className="cat-tag">📚 {question.category}</span>
          <span className="q-num">سؤال {qIndex + 1} / {total}</span>
        </div>
        <div className="q-text">{question.question}</div>
        <div className="options-grid">
          {question.options.map((opt, i) => {
            let cls = "option-btn";
            if (phase === "result") {
              if (i === question.correct) cls += " is-correct";
              else if (i === lastPick && !lastResult?.correct) cls += " is-wrong";
              else cls += " is-faded";
            }
            return (
              <button key={i} className={cls} data-color={colors[i]}
                onClick={() => handleAnswer(i)}
                disabled={phase !== "question"}>
                <span className="option-letter">{letters[i]}</span>
                <span>{opt}</span>
              </button>
            );
          })}
        </div>
        {phase === "result" && (
          <div className="mp-result-banner">
            {lastResult?.correct ? <>🎉 صحيح! +{(lastResult.gained || 0) + (lastResult.timeBonus || 0)} نقطة</>
              : lastPick != null ? <>❌ خاطئ. الإجابة: {question.options[question.correct]}</>
              : <>⏰ انتهى الوقت. الإجابة: {question.options[question.correct]}</>}
          </div>
        )}
      </div>
    </div>
  );
}

// ===== Multiplayer End =====
function MPEnd({ room, code, playerId, onLeave }) {
  const players = Object.entries(room.players || {})
    .map(([id, p]) => ({ ...p, id }))
    .sort((a, b) => (b.score || 0) - (a.score || 0));
  const top3 = players.slice(0, 3);
  const rest = players.slice(3);
  const myRank = players.findIndex((p) => p.id === playerId) + 1;
  const myMedal = myRank === 1 ? "🥇" : myRank === 2 ? "🥈" : myRank === 3 ? "🥉" : "🎖️";

  return (
    <div className="lb">
      <div className="home-hero">
        <span className="home-eyebrow">🏆 النتائج النهائية</span>
        <h1 className="home-title" style={{ fontSize: "clamp(40px,7vw,72px)" }}>
          <span className="word w1">{myMedal}</span>{" "}
          <span className="word w2">المركز {myRank}</span>
        </h1>
      </div>

      {top3.length >= 3 && (
        <div className="lb-podium">
          <div className="podium-cell silver">
            <div className="rank">2</div>
            <div className="podium-av">{AVATARS[top3[1].avatar].emoji}</div>
            <div className="podium-name">{top3[1].country && <span style={{marginLeft:4}}>{window.codeToFlag?.(top3[1].country)}</span>}{top3[1].name}</div>
            <div className="podium-score">{top3[1].score || 0}</div>
          </div>
          <div className="podium-cell gold">
            <div className="rank">1</div>
            <div className="podium-av">{AVATARS[top3[0].avatar].emoji}</div>
            <div className="podium-name">{top3[0].country && <span style={{marginLeft:4}}>{window.codeToFlag?.(top3[0].country)}</span>}{top3[0].name}</div>
            <div className="podium-score">{top3[0].score || 0}</div>
          </div>
          <div className="podium-cell bronze">
            <div className="rank">3</div>
            <div className="podium-av">{AVATARS[top3[2].avatar].emoji}</div>
            <div className="podium-name">{top3[2].country && <span style={{marginLeft:4}}>{window.codeToFlag?.(top3[2].country)}</span>}{top3[2].name}</div>
            <div className="podium-score">{top3[2].score || 0}</div>
          </div>
        </div>
      )}

      {top3.length > 0 && top3.length < 3 && (
        <div className="lb-list">
          {top3.map((p, i) => (
            <div key={p.id} className={`lb-row ${p.id === playerId ? "is-self" : ""}`}>
              <div className="lb-rank">#{i + 1}</div>
              <div className="lb-av">{AVATARS[p.avatar].emoji}</div>
              <div><div className="lb-name">{p.country && <span style={{marginLeft:4}}>{window.codeToFlag?.(p.country)}</span>}{p.name}</div></div>
              <div></div>
              <div className="lb-score">{p.score || 0}</div>
            </div>
          ))}
        </div>
      )}

      {rest.length > 0 && (
        <div className="lb-list">
          {rest.map((p, i) => (
            <div key={p.id} className={`lb-row ${p.id === playerId ? "is-self" : ""}`}>
              <div className="lb-rank">#{i + 4}</div>
              <div className="lb-av">{AVATARS[p.avatar].emoji}</div>
              <div><div className="lb-name">{p.country && <span style={{marginLeft:4}}>{window.codeToFlag?.(p.country)}</span>}{p.name}</div></div>
              <div></div>
              <div className="lb-score">{p.score || 0}</div>
            </div>
          ))}
        </div>
      )}

      <div style={{ display: "flex", justifyContent: "center" }}>
        <button className="btn btn-yellow" style={{ padding: "16px 36px" }} onClick={onLeave}>← الرئيسية</button>
      </div>
    </div>
  );
}

// ===== Multiplayer Room (routes between lobby/game/end) =====
function MultiplayerRoom({ code, playerId, onExit }) {
  const [room, setRoom] = useState(null);

  useEffect(() => {
    const unsub = window.MP.watchRoom(code, (data) => setRoom(data));
    return unsub;
  }, [code]);

  // Also try to remove player on tab close.
  useEffect(() => {
    const handler = () => { try { window.MP.leaveRoom(code, playerId); } catch {} };
    window.addEventListener("beforeunload", handler);
    return () => window.removeEventListener("beforeunload", handler);
  }, [code, playerId]);

  async function leave() {
    try { await window.MP.leaveRoom(code, playerId); } catch {}
    onExit();
  }

  if (!room) {
    return (
      <div className="home">
        <div className="home-hero">
          <h2 className="home-title" style={{ fontSize: "clamp(32px,5vw,48px)" }}>جارٍ الاتصال...</h2>
        </div>
      </div>
    );
  }

  const me = room.players?.[playerId];
  if (!me) {
    return (
      <div className="home">
        <div className="home-card" style={{ textAlign: "center" }}>
          <h2 style={{ marginBottom: 12 }}>تمت إزالتك من الغرفة</h2>
          <button className="btn btn-primary" onClick={onExit}>← الرئيسية</button>
        </div>
      </div>
    );
  }

  const state = room.meta?.state || "lobby";

  if (state === "lobby") return <Lobby room={room} code={code} playerId={playerId} onLeave={leave} />;
  if (state === "playing") return <MPGame room={room} code={code} playerId={playerId} onLeave={leave} />;
  if (state === "finished") return <MPEnd room={room} code={code} playerId={playerId} onLeave={leave} />;
  return null;
}

// ===== App root =====
function App() {
  const [tweaks, setTweak] = window.useTweaks({ theme: "light" });
  const [route, setRoute] = useState({ name: "home" });
  const [hi, setHi] = useState(() => Number(localStorage.getItem("trivia_hi") || 0));
  const [questionCount, setQuestionCount] = useState((window.QUESTIONS_BANK || []).length);
  // Bump this whenever the seen-set changes so HomeMenu recomputes the remaining count.
  const [seenSignal, setSeenSignal] = useState(0);
  // Auto-detected from the player's IP via geo.js. null until resolved/failed.
  const [country, setCountry] = useState(null);

  useEffect(() => {
    if (typeof window.detectCountry !== "function") return;
    window.detectCountry().then((c) => { if (c) setCountry(c); }).catch(() => {});
  }, []);

  useEffect(() => {
    document.documentElement.setAttribute("data-theme", tweaks.theme);
  }, [tweaks.theme]);

  useEffect(() => {
    (async () => {
      let n = (window.QUESTIONS_BANK || []).length;
      if (typeof window.loadQuestions === "function") {
        n = await window.loadQuestions();
      }
      // Merge previously-generated questions from localStorage
      const generated = loadGeneratedQuestions();
      if (generated.length > 0) {
        window.QUESTIONS_BANK = [...(window.QUESTIONS_BANK || []), ...generated];
      }
      setQuestionCount((window.QUESTIONS_BANK || []).length);
    })();
  }, []);

  // When the route returns to home, recompute remaining (player likely just played a round).
  useEffect(() => {
    if (route.name === "home") setSeenSignal((s) => s + 1);
  }, [route.name]);

  function handleResetSeen() {
    resetSeen();
    setSeenSignal((s) => s + 1);
  }

  const [generating, setGenerating] = useState(false);
  const [generateError, setGenerateError] = useState("");

  async function handleGenerate() {
    if (generating) return;
    setGenerating(true);
    setGenerateError("");
    try {
      const fresh = await fetchGeneratedQuestions(16);
      appendGeneratedQuestions(fresh);
      setQuestionCount((window.QUESTIONS_BANK || []).length);
      setSeenSignal((s) => s + 1);
    } catch (e) {
      setGenerateError("تعذّر توليد أسئلة جديدة: " + (e?.message || "خطأ"));
    } finally {
      setGenerating(false);
    }
  }

  function pickMode(mode) {
    if (mode === "sp") setRoute({ name: "sp" });
    else if (mode === "create") setRoute({ name: "mp-create" });
    else if (mode === "join") setRoute({ name: "mp-join" });
  }

  const goHome = () => setRoute({ name: "home" });

  return (
    <>
      <BgDecor />
      <TopBar
        theme={tweaks.theme}
        onToggleTheme={() => setTweak("theme", tweaks.theme === "dark" ? "light" : "dark")}
        screen={route.name}
        onHome={goHome}
      />
      <div className="app-shell">
        {route.name === "home" && (
          <HomeMenu
            onPick={pickMode}
            hi={hi}
            totalQuestions={questionCount}
            seenSignal={seenSignal}
            onResetSeen={handleResetSeen}
            onGenerate={handleGenerate}
            generating={generating}
            generateError={generateError}
            country={country}
          />
        )}
        {route.name === "sp" && <SinglePlayerGame onExit={goHome} hi={hi} setHi={setHi} />}
        {route.name === "mp-create" && (
          <MPSetup mode="create" country={country} onSuccess={(code, playerId) => setRoute({ name: "mp-room", code, playerId })} onCancel={goHome} />
        )}
        {route.name === "mp-join" && (
          <MPSetup mode="join" country={country} onSuccess={(code, playerId) => setRoute({ name: "mp-room", code, playerId })} onCancel={goHome} />
        )}
        {route.name === "mp-room" && (
          <MultiplayerRoom code={route.code} playerId={route.playerId} onExit={goHome} />
        )}
      </div>
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
