// ── QuestionPage ──────────────────────────────────────────────────────────────

function QuestionPage({ chapterId, navigate }) {
  const [chapterData, setChapterData] = React.useState(null);
  const [questionData, setQuestionData] = React.useState(null);
  const [clockStart, setClockStart] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [loadError, setLoadError] = React.useState('');

  // Submission state
  const [inputValue, setInputValue] = React.useState('');
  const [submitting, setSubmitting] = React.useState(false);
  const [submitError, setSubmitError] = React.useState('');
  const [correctResult, setCorrectResult] = React.useState(null);
  const [wrongAttempts, setWrongAttempts] = React.useState([]);
  const [wrongMsg, setWrongMsg] = React.useState('');

  // MCQ state
  const [disabledOptions, setDisabledOptions] = React.useState(new Set());
  const [lastTappedOption, setLastTappedOption] = React.useState(null);

  // Celebration
  const [celebration, setCelebration] = React.useState(null);

  // Flag state
  const [flagged, setFlagged] = React.useState(false);           // any flag submitted
  const [showFlagModal, setShowFlagModal] = React.useState(false);
  const [flagType, setFlagType] = React.useState(null);          // 'repeat'|'broken'|'challenge'
  const [flagNote, setFlagNote] = React.useState('');
  const [flagging, setFlagging] = React.useState(false);
  const [flagToast, setFlagToast] = React.useState('');          // toast message string

  // Challenge-validator polling state
  const [challengeState, setChallengeState] = React.useState(null); // null | 'validating' | verdict object

  // PIN reveal state
  const [showRevealModal, setShowRevealModal] = React.useState(false);
  const [revealPin, setRevealPin] = React.useState('');
  const [revealing, setRevealing] = React.useState(false);
  const [revealError, setRevealError] = React.useState('');
  const [revealResult, setRevealResult] = React.useState(null); // { correct_answer, explanation }
  const [pinFailCount, setPinFailCount] = React.useState(0);

  const questionRef = React.useRef(null);
  const explanationRef = React.useRef(null);
  const revealExplanationRef = React.useRef(null);
  const pollTimerRef = React.useRef(null);

  function loadQuestion() {
    if (pollTimerRef.current) { clearInterval(pollTimerRef.current); pollTimerRef.current = null; }
    setLoading(true);
    setLoadError('');
    setCorrectResult(null);
    setInputValue('');
    setSubmitError('');
    setWrongMsg('');
    setWrongAttempts([]);
    setDisabledOptions(new Set());
    setLastTappedOption(null);
    setCelebration(null);
    setClockStart(null);
    setFlagged(false);
    setShowFlagModal(false);
    setFlagType(null);
    setFlagNote('');
    setFlagToast('');
    setChallengeState(null);
    setShowRevealModal(false);
    setRevealPin('');
    setRevealError('');
    setRevealResult(null);
    setPinFailCount(0);
    setChapterData(null);
    setQuestionData(null);

    Promise.all([
      fetch(`/api/children/chapters/${chapterId}`, { credentials: 'include' })
        .then((r) => r.json().then((body) => ({ ok: r.ok, body }))),
      fetch(`/api/children/chapters/${chapterId}/question`, {
        method: 'POST',
        credentials: 'include',
      }).then((r) => r.json().then((body) => ({ ok: r.ok, body }))),
    ])
      .then(([chRes, qRes]) => {
        if (!chRes.ok) throw new Error(chRes.body.error || 'Failed to load chapter');
        if (!qRes.ok) throw new Error(qRes.body.error || 'Failed to load question');
        setChapterData(chRes.body);
        const qBody = qRes.body;
        const serverParkedAt = new Date(qBody.parked_started_at).getTime();
        const now = Date.now();
        setClockStart((now - serverParkedAt) > 120000 ? now : serverParkedAt);
        setQuestionData(qBody);
        setWrongAttempts(qBody.previous_wrong_attempts || []);
      })
      .catch((err) => setLoadError(err.message || 'Could not load question'))
      .finally(() => setLoading(false));
  }

  React.useEffect(() => { loadQuestion(); }, [chapterId]);

  // Cleanup poll timer on unmount
  React.useEffect(() => {
    return () => { if (pollTimerRef.current) clearInterval(pollTimerRef.current); };
  }, []);

  // KaTeX after question renders
  React.useEffect(() => {
    if (!questionData || !questionRef.current) return;
    if (typeof window.renderMathInElement !== 'function') return;
    try {
      window.renderMathInElement(questionRef.current, {
        delimiters: [
          { left: '$$', right: '$$', display: true },
          { left: '$', right: '$', display: false },
        ],
        throwOnError: false,
      });
    } catch (e) {}
  }, [questionData]);

  // KaTeX on reveal explanation
  React.useEffect(() => {
    if (!revealResult || !revealExplanationRef.current) return;
    if (typeof window.renderMathInElement !== 'function') return;
    try {
      window.renderMathInElement(revealExplanationRef.current, {
        delimiters: [{ left: '$$', right: '$$', display: true }, { left: '$', right: '$', display: false }],
        throwOnError: false,
      });
    } catch (e) {}
  }, [revealResult]);

  // KaTeX on explanation after correct answer
  React.useEffect(() => {
    if (!explanationRef.current) return;
    if (typeof window.renderMathInElement !== 'function') return;
    try {
      window.renderMathInElement(explanationRef.current, {
        delimiters: [
          { left: '$$', right: '$$', display: true },
          { left: '$', right: '$', display: false },
        ],
        throwOnError: false,
      });
    } catch (e) {}
  }, [correctResult]);

  // Auto-dismiss celebration
  React.useEffect(() => {
    if (!celebration) return;
    const ms = celebration.type === 'band_crossing' ? 3000 : 1500;
    const t = setTimeout(() => setCelebration(null), ms);
    return () => clearTimeout(t);
  }, [celebration]);

  async function submitFIB(e) {
    e.preventDefault();
    if (!inputValue.trim() || submitting || correctResult) return;
    setSubmitting(true);
    setSubmitError('');
    setWrongMsg('');
    try {
      const r = await fetch(
        `/api/children/chapters/${chapterId}/question/${questionData.question.id}/submit`,
        {
          method: 'POST',
          credentials: 'include',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ typed_answer: inputValue }),
        }
      );
      const data = await r.json();
      if (!r.ok) throw new Error(data.error || 'Submit failed');
      if (data.correct) {
        setCorrectResult(data);
        if (data.level_up) {
          const type = data.band_crossed ? 'band_crossing' : 'level_up';
          setCelebration({ type, result: data });
          if (data.band_crossed && typeof window.confetti === 'function') {
            window.confetti({ particleCount: 150, spread: 80, origin: { y: 0.6 } });
          }
        }
      } else {
        setWrongAttempts((prev) => [...prev, inputValue]);
        setWrongMsg('Not quite — try again');
        setInputValue('');
      }
    } catch (err) {
      setSubmitError('Something went wrong — try again');
    } finally {
      setSubmitting(false);
    }
  }

  async function submitMCQ(chosenIndex) {
    if (submitting || correctResult || disabledOptions.has(chosenIndex)) return;
    setLastTappedOption(chosenIndex);
    setSubmitting(true);
    setSubmitError('');
    setWrongMsg('');
    try {
      const r = await fetch(
        `/api/children/chapters/${chapterId}/question/${questionData.question.id}/submit`,
        {
          method: 'POST',
          credentials: 'include',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ chosen_index: chosenIndex }),
        }
      );
      const data = await r.json();
      if (!r.ok) throw new Error(data.error || 'Submit failed');
      if (data.correct) {
        setCorrectResult(data);
        if (data.level_up) {
          const type = data.band_crossed ? 'band_crossing' : 'level_up';
          setCelebration({ type, result: data });
          if (data.band_crossed && typeof window.confetti === 'function') {
            window.confetti({ particleCount: 150, spread: 80, origin: { y: 0.6 } });
          }
        }
      } else {
        setDisabledOptions((prev) => new Set([...prev, chosenIndex]));
        setWrongAttempts((prev) => [...prev, `Option ${String.fromCharCode(65 + chosenIndex)}`]);
        setWrongMsg('Not quite — try another option');
      }
    } catch (err) {
      setSubmitError('Something went wrong — try again');
      setLastTappedOption(null);
    } finally {
      setSubmitting(false);
    }
  }

  async function submitFlag() {
    if (flagging || !flagType) return;
    setFlagging(true);
    try {
      const r = await fetch(
        `/api/children/questions/${questionData.question.id}/flag/${flagType}`,
        {
          method: 'POST',
          credentials: 'include',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ note: flagNote.trim() || null }),
        }
      );
      const data = await r.json();
      if (!r.ok) throw new Error(data.error || 'Flag failed');

      setFlagged(true);
      setShowFlagModal(false);
      setFlagNote('');

      if (flagType === 'repeat') {
        setFlagToast('Moved on to a new question');
        setTimeout(() => { setFlagToast(''); loadQuestion(); }, 1500);
      } else if (flagType === 'broken') {
        setFlagToast('Sent for review. Moving on.');
        setTimeout(() => { setFlagToast(''); loadQuestion(); }, 1500);
      } else if (flagType === 'challenge') {
        // Switch to polling state
        setChallengeState({ status: 'validating', flag_id: data.flag_id });
        startPolling(data.flag_id);
      }
    } catch (err) {
      // silent — don't disrupt question flow
      setShowFlagModal(false);
    } finally {
      setFlagging(false);
    }
  }

  async function submitReveal(e) {
    e.preventDefault();
    if (revealing) return;
    setRevealing(true);
    setRevealError('');
    try {
      const r = await fetch(
        `/api/children/questions/${questionData.question.id}/reveal`,
        {
          method: 'POST',
          credentials: 'include',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ pin: revealPin }),
        }
      );
      const data = await r.json();
      if (r.status === 429) { setRevealError('Too many tries. Wait a moment and try again.'); return; }
      if (!r.ok) {
        const newCount = pinFailCount + 1;
        setPinFailCount(newCount);
        setRevealError(newCount >= 5 ? 'Too many tries. Wait a moment and try again.' : 'Incorrect PIN, try again');
        setRevealPin('');
        return;
      }
      setRevealResult(data);
      setShowRevealModal(false);
      setRevealPin('');
    } catch (err) {
      setRevealError('Could not reach server');
    } finally {
      setRevealing(false);
    }
  }

  function startPolling(flagId) {
    if (pollTimerRef.current) clearInterval(pollTimerRef.current);
    pollTimerRef.current = setInterval(async () => {
      try {
        const r = await fetch(`/api/children/flags/${flagId}/status`, { credentials: 'include' });
        const data = await r.json();
        if (data.status === 'done') {
          clearInterval(pollTimerRef.current);
          pollTimerRef.current = null;
          setChallengeState({ status: 'done', ...data });
          if (data.unblocked) {
            if (data.band_crossed && typeof window.confetti === 'function') {
              window.confetti({ particleCount: 150, spread: 80, origin: { y: 0.6 } });
            }
          }
        }
      } catch (e) { /* keep polling */ }
    }, 1500);
  }

  function optionClass(i) {
    if (correctResult && lastTappedOption === i) return 'question-option-card question-option-card--correct';
    if (disabledOptions.has(i)) return 'question-option-card question-option-card--wrong';
    return 'question-option-card';
  }

  // ── Loading / error shells ──────────────────────────────────────────────────
  if (loading) {
    return (
      <div className="question-shell">
        <div className="question-topbar">
          <button className="chapter-back-btn" onClick={() => navigate(`/chapter/${chapterId}`)}>← Back</button>
        </div>
        <div className="question-body">
          <p className="child-loading">Preparing your question…</p>
        </div>
      </div>
    );
  }

  if (loadError) {
    return (
      <div className="question-shell">
        <div className="question-topbar">
          <button className="chapter-back-btn" onClick={() => navigate(`/chapter/${chapterId}`)}>← Back</button>
        </div>
        <div className="question-body">
          <p className="subject-error">{loadError}</p>
          <button className="chapter-start-btn" style={{ marginTop: '1.5rem' }} onClick={loadQuestion}>Retry</button>
        </div>
      </div>
    );
  }

  // ── Challenge validator overlay ─────────────────────────────────────────────
  if (challengeState) {
    const { status, verdict, reasoning, unblocked, new_level, band_crossed, old_band, new_band } = challengeState;

    if (status === 'validating') {
      return (
        <div className="question-shell">
          <div className="question-body" style={{ textAlign: 'center', paddingTop: '4rem' }}>
            <div className="challenge-spinner">⏳</div>
            <div className="challenge-checking">Checking with senior teacher…</div>
            <div className="challenge-sub">This takes a few seconds</div>
          </div>
        </div>
      );
    }

    if (status === 'done') {
      if (unblocked) {
        return (
          <div className="question-shell">
            <div className="question-body" style={{ textAlign: 'center', paddingTop: '3rem' }}>
              <div className="challenge-result-icon">⭐</div>
              <div className="challenge-result-title">Great catch! Your answer was correct.</div>
              <div className="challenge-result-sub">{reasoning}</div>
              {band_crossed
                ? <div className="question-levelup-badge">You've reached {new_band}! (Level {new_level})</div>
                : <div className="question-levelup-badge">Level up! → Level {new_level}</div>
              }
              <button className="chapter-start-btn" style={{ marginTop: '2rem' }} onClick={loadQuestion}>
                Next question →
              </button>
            </div>
          </div>
        );
      }

      if (verdict === 'child_wrong') {
        return (
          <div className="question-shell">
            <div className="question-topbar">
              <button className="chapter-back-btn" onClick={() => navigate(`/chapter/${chapterId}`)}>← Back</button>
            </div>
            <div className="question-body" style={{ textAlign: 'center', paddingTop: '3rem' }}>
              <div className="challenge-result-icon">🔍</div>
              <div className="challenge-result-title">The senior teacher checked your answer.</div>
              <div className="challenge-result-sub">{reasoning}</div>
              <div className="challenge-result-cta">Please try again or ask your parent to help.</div>
              <button className="chapter-start-btn" style={{ marginTop: '2rem' }}
                onClick={() => setChallengeState(null)}>
                Back to question
              </button>
            </div>
          </div>
        );
      }

      // verdict === 'unclear'
      return (
        <div className="question-shell">
          <div className="question-topbar">
            <button className="chapter-back-btn" onClick={() => navigate(`/chapter/${chapterId}`)}>← Back</button>
          </div>
          <div className="question-body" style={{ textAlign: 'center', paddingTop: '3rem' }}>
            <div className="challenge-result-icon">🤔</div>
            <div className="challenge-result-title">The senior teacher couldn't decide.</div>
            <div className="challenge-result-sub">Please ask your parent to look at this with you.</div>
            <button className="chapter-start-btn" style={{ marginTop: '2rem' }}
              onClick={() => setChallengeState(null)}>
              Back to question
            </button>
          </div>
        </div>
      );
    }
  }

  const { chapter, subject } = chapterData;
  const { question } = questionData;
  const breadcrumb = `${subject.emoji} ${subject.name} › ${chapter.name} · Level ${question.level}`;

  return (
    <div className="question-shell">
      {/* Top bar */}
      <div className="question-topbar">
        <button className="chapter-back-btn" onClick={() => navigate(`/chapter/${chapterId}`)}>← Back</button>
        {clockStart && !correctResult && <QuestionClock startedAt={clockStart} />}
      </div>

      <div className="question-breadcrumb">{breadcrumb}</div>

      {/* Question body */}
      <div className="question-body" ref={questionRef}>
        <div className="question-text">{question.question_text}</div>

        {/* ── FIB ── */}
        {question.format === 'FIB' && !correctResult && (
          <form className="question-fib-area" onSubmit={submitFIB}>
            <input
              className="question-input"
              type="text"
              placeholder="Type your answer…"
              autoComplete="off"
              value={inputValue}
              disabled={submitting}
              onChange={(e) => { setInputValue(e.target.value); setWrongMsg(''); setSubmitError(''); }}
              autoFocus
            />
            <button
              className="question-submit-btn question-submit-btn--active"
              type="submit"
              disabled={submitting || !inputValue.trim()}
            >
              {submitting ? 'Checking…' : 'Submit'}
            </button>
          </form>
        )}

        {/* ── MCQ ── */}
        {question.format === 'MCQ' && question.options && !correctResult && (
          <div className="question-options">
            {question.options.map((opt, i) => (
              <button
                key={i}
                className={optionClass(i)}
                disabled={submitting || disabledOptions.has(i)}
                onClick={() => submitMCQ(i)}
              >
                <span className="question-option-letter">{String.fromCharCode(65 + i)}.</span>
                {' '}{opt}
              </button>
            ))}
          </div>
        )}

        {/* Wrong feedback */}
        {wrongMsg && <p className="question-wrong-msg">{wrongMsg}</p>}
        {submitError && <p className="question-submit-error">{submitError}</p>}

        {/* Wrong attempts list */}
        {wrongAttempts.length > 0 && !correctResult && (
          <div className="question-prev-attempts">
            <strong>You&apos;ve tried:</strong>
            <ul>
              {wrongAttempts.map((a, i) => <li key={i}>{a}</li>)}
            </ul>
          </div>
        )}

        {/* ── Flag button — visible after at least one wrong attempt ── */}
        {wrongAttempts.length > 0 && !correctResult && !flagged && (
          <button className="flag-btn" onClick={() => setShowFlagModal(true)}>⚐ Flag this question</button>
        )}
        {wrongAttempts.length > 0 && !correctResult && flagged && (
          <span className="flag-btn flag-btn--done">⚐ Flagged</span>
        )}

        {/* ── Parent help link ── */}
        {!correctResult && !revealResult && (
          <button className="reveal-link" onClick={() => { setShowRevealModal(true); setRevealError(''); setRevealPin(''); }}>
            Parent help
          </button>
        )}

        {/* ── Reveal result panel ── */}
        {revealResult && (
          <div className="reveal-result-panel" ref={revealExplanationRef}>
            <div className="reveal-result-label">Answer (shown by parent)</div>
            <div className="reveal-result-answer">{revealResult.correct_answer}</div>
            {revealResult.explanation && (
              <div className="reveal-result-explanation">{revealResult.explanation}</div>
            )}
            <button className="chapter-start-btn" style={{ marginTop: '1.25rem' }} onClick={loadQuestion}>
              Next question →
            </button>
          </div>
        )}

        {/* ── Correct result panel ── */}
        {correctResult && (
          <div className="question-result-panel">
            <div className="question-result-correct">✓ Correct!</div>

            {correctResult.explanation && (
              <div className="question-result-explanation" ref={explanationRef}>{correctResult.explanation}</div>
            )}

            {correctResult.level_up && (
              <div className="question-levelup-badge">
                {correctResult.band_crossed
                  ? `You've reached ${correctResult.new_band}! (Level ${correctResult.new_level})`
                  : `Level up! ${correctResult.old_level} → ${correctResult.new_level}`}
              </div>
            )}

            <button className="chapter-start-btn" style={{ marginTop: '1.5rem' }} onClick={loadQuestion}>
              Next question →
            </button>
          </div>
        )}
      </div>

      {/* ── Band crossing overlay ── */}
      {celebration && celebration.type === 'band_crossing' && (
        <div className="band-crossing-overlay" onClick={() => setCelebration(null)}>
          <div className="band-crossing-content">
            <div className="band-crossing-emoji">{subject.emoji}</div>
            <div className="band-crossing-title">You&apos;ve reached</div>
            <div className="band-crossing-band">{celebration.result.new_band}!</div>
            <div className="band-crossing-level">Level {celebration.result.old_level} → {celebration.result.new_level}</div>
          </div>
        </div>
      )}

      {/* ── Plain level-up toast ── */}
      {celebration && celebration.type === 'level_up' && (
        <div className="levelup-toast">
          ⬆ Level {celebration.result.old_level} → {celebration.result.new_level}
        </div>
      )}

      {/* ── Flag toast ── */}
      {flagToast && <div className="flag-toast">{flagToast}</div>}

      {/* ── PIN reveal modal ── */}
      {showRevealModal && (
        <div className="flag-modal-overlay" onClick={(e) => { if (e.target === e.currentTarget) setShowRevealModal(false); }}>
          <div className="flag-modal">
            <div className="flag-modal-title">Parent, please type your PIN to see the answer.</div>
            <form onSubmit={submitReveal}>
              <input
                className="parent-input"
                type="password"
                inputMode="numeric"
                pattern="[0-9]{4}"
                maxLength={4}
                placeholder="4-digit PIN"
                autoComplete="off"
                value={revealPin}
                onChange={(e) => setRevealPin(e.target.value)}
                autoFocus
                style={{ marginBottom: '0.75rem' }}
              />
              {revealError && <p className="parent-error" style={{ marginBottom: '0.5rem' }}>{revealError}</p>}
              <div className="flag-modal-actions">
                <button type="button" className="flag-modal-cancel" onClick={() => setShowRevealModal(false)}>Cancel</button>
                <button type="submit" className="flag-modal-send" disabled={revealing || revealPin.length !== 4}>
                  {revealing ? 'Checking…' : 'Reveal'}
                </button>
              </div>
            </form>
          </div>
        </div>
      )}

      {/* ── Flag modal ── */}
      {showFlagModal && (
        <div className="flag-modal-overlay" onClick={(e) => { if (e.target === e.currentTarget) setShowFlagModal(false); }}>
          <div className="flag-modal">
            <div className="flag-modal-title">What's wrong with this question?</div>

            <div className="flag-type-options">
              <button
                className={`flag-type-card${flagType === 'repeat' ? ' flag-type-card--selected' : ''}`}
                onClick={() => setFlagType('repeat')}
              >
                <div className="flag-type-icon">⟲</div>
                <div className="flag-type-label">I've seen this before</div>
                <div className="flag-type-desc">You'll move on to a new question.</div>
              </button>

              <button
                className={`flag-type-card${flagType === 'broken' ? ' flag-type-card--selected' : ''}`}
                onClick={() => setFlagType('broken')}
              >
                <div className="flag-type-icon">✗</div>
                <div className="flag-type-label">Question seems broken or incomplete</div>
                <div className="flag-type-desc">A senior teacher will review it.</div>
              </button>

              <button
                className={`flag-type-card${flagType === 'challenge' ? ' flag-type-card--selected' : ''}`}
                onClick={() => setFlagType('challenge')}
              >
                <div className="flag-type-icon">⚖</div>
                <div className="flag-type-label">I think my answer is correct</div>
                <div className="flag-type-desc">A senior teacher will double-check. If you're right, you level up.</div>
              </button>
            </div>

            <textarea
              className="flag-modal-textarea"
              placeholder="Add a note (optional)"
              maxLength={200}
              value={flagNote}
              onChange={(e) => setFlagNote(e.target.value)}
              rows={2}
            />

            <div className="flag-modal-actions">
              <button className="flag-modal-cancel" onClick={() => { setShowFlagModal(false); setFlagType(null); setFlagNote(''); }}>
                Cancel
              </button>
              <button
                className="flag-modal-send"
                onClick={submitFlag}
                disabled={flagging || !flagType}
              >
                {flagging ? 'Sending…' : 'Flag'}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
