// Quiz components — view for an in-progress quiz
const { useState, useEffect, useRef, useMemo } = React;

// Single question view
function QuestionView({ question, index, total, selected, onSelect, onHint, hintActive, showReveal, onToggleReveal }) {
  const letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
  const [hintOptionIdx, setHintOptionIdx] = useState(null);
  const [showStudyHint, setShowStudyHint] = useState(false);

  // Find the question's global index for hint lookup
  const globalIdx = useMemo(() => {
    const allQ = window.ALL_QUESTIONS;
    for (let i = 0; i < allQ.length; i++) {
      if (allQ[i].num === question.num && allQ[i].source === question.source) return i;
    }
    return -1;
  }, [question.num, question.source]);

  const studyHintText = globalIdx >= 0 && window.QUESTION_HINTS ? window.QUESTION_HINTS[globalIdx] : null;
  const studyHintEntries = useMemo(() => {
    if (!studyHintText || typeof studyHintText === 'string') return null;
    return question.options.map((opt, i) => {
      const desc = Array.isArray(studyHintText)
        ? studyHintText[i]
        : studyHintText[opt] || studyHintText[i];
      return { letter: letters[i], option: opt, desc: desc || 'No study note is available for this option yet.' };
    });
  }, [question.options, studyHintText]);

  useEffect(() => {
    if (hintActive) {
      setHintOptionIdx(question.correct);
      const t = setTimeout(() => setHintOptionIdx(null), 3200);
      return () => clearTimeout(t);
    }
  }, [hintActive, question.correct]);

  // Reset study hint when question changes
  useEffect(() => {
    setShowStudyHint(false);
  }, [index]);

  return (
    <div>
      <div className="q-meta">
        <span>Question {index + 1} / {total}</span>
        {showReveal && (
          <span className={`source-tag ${question.source}`}>
            from {question.source} · Q{question.num}
          </span>
        )}
      </div>
      <div className="q-text" dangerouslySetInnerHTML={{ __html: renderText(question.q) }} />
      {Array.isArray(question.correct) && (
        <div style={{ fontSize: 13, color: 'var(--accent)', fontWeight: 600, marginBottom: 12, display: 'flex', alignItems: 'center', gap: 6 }}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="9 11 12 14 22 4"></polyline><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"></path></svg>
          Multiple Choice: Select {question.correct.length} answers
        </div>
      )}
      <div className="options">
        {question.options.map((opt, i) => {
          const isSelected = Array.isArray(selected) ? selected.includes(i) : selected === i;
          const isHint = Array.isArray(hintOptionIdx) ? hintOptionIdx.includes(i) : hintOptionIdx === i;
          return (
            <button
              key={i}
              className={`option ${isSelected ? 'selected' : ''} ${isHint ? 'hint-blink' : ''}`}
              onClick={() => onSelect(i)}
            >
              <span className="option-letter">{letters[i]}</span>
              <span className="option-text" dangerouslySetInnerHTML={{ __html: renderText(opt) }} />
            </button>
          );
        })}
      </div>
      <div className="q-actions">
        <div className="q-actions-left">
          <button className={`icon-btn ${hintActive ? 'active' : ''}`} onClick={onHint} title="Hint — blink correct answer">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M9 21h6"/><path d="M12 17v4"/><path d="M12 3a6 6 0 0 0-4 10.5c.5.5 1 1.5 1 2.5h6c0-1 .5-2 1-2.5A6 6 0 0 0 12 3z"/></svg>
          </button>
          {studyHintText && (
            <button className={`icon-btn ${showStudyHint ? 'active' : ''}`} onClick={() => setShowStudyHint(!showStudyHint)} title="Study hint — learn from course material">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>
            </button>
          )}
          <button className={`icon-btn ${showReveal ? 'active' : ''}`} onClick={onToggleReveal} title="Show which exam this is from">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/></svg>
          </button>
        </div>
      </div>
      {showStudyHint && studyHintText && (
        <div className="study-hint-panel">
          <div className="study-hint-header">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>
            Study Material Breakdown
          </div>
          <div className="study-hint-text">
            {typeof studyHintText === 'string' ? (
              <div>{studyHintText}</div>
            ) : (
              <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
                {studyHintEntries.map(({ letter, option, desc }, idx) => (
                  <div key={idx}>
                    <strong style={{ color: 'var(--text)' }}>{letter.toUpperCase()}. {option}:</strong> {desc}
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

// Render inline `code` backticks and escape HTML
function renderText(s) {
  const esc = s
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');
  return esc.replace(/`([^`]+)`/g, '<code>$1</code>');
}
window.renderText = renderText;

function ProgressHeader({ current, total, answered, onQuit, onReview }) {
  const pct = total > 0 ? (answered / total) * 100 : 0;
  return (
    <div className="quiz-header">
      <div className="quiz-progress">
        <div className="progress-bar"><div className="progress-fill" style={{ width: pct + '%' }} /></div>
        <span>{answered}/{total} answered</span>
      </div>
      <div className="header-actions">
        <button className="btn btn-sm btn-ghost" onClick={onReview}>Review & Finish</button>
        <button className="btn btn-sm btn-danger" onClick={onQuit}>Quit</button>
      </div>
    </div>
  );
}

function QuestionNav({ questions, answers, current, onJump }) {
  const [open, setOpen] = useState(false);
  const answeredCount = answers.filter(a => a != null).length;
  const skippedBefore = answers.slice(0, current).filter(a => a == null).length;

  return (
    <div className="q-nav-drawer">
      <button className="q-nav-toggle" onClick={() => setOpen(!open)}>
        <div className="q-nav-summary">
          <span className="q-nav-current">Q{current + 1}</span>
          <span className="q-nav-sep">/</span>
          <span>{questions.length}</span>
          <span className="q-nav-dot answered-dot" />
          <span>{answeredCount} answered</span>
          {skippedBefore > 0 && <><span className="q-nav-dot skipped-dot" /><span>{skippedBefore} skipped</span></>}
        </div>
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0, transform: open ? 'rotate(180deg)' : 'none', transition: 'transform 0.2s' }}><polyline points="6 9 12 15 18 9"/></svg>
      </button>
      {open && (
        <div className="q-nav-grid">
          {questions.map((_, i) => (
            <button
              key={i}
              className={`q-nav-pill ${i === current ? 'current' : ''} ${answers[i] != null ? 'answered' : ''}`}
              onClick={() => { onJump(i); setOpen(false); }}
            >
              {i + 1}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// Shared review item — renders a single question with correct/selected answer
// `trim` = only show your answer + correct answer; otherwise show all 4 options
function ReviewItem({ question, selected, index, trim, showNumber }) {
  const letters = ['a','b','c','d','e','f','g','h'];
  const isCorrect = Array.isArray(question.correct) 
    ? (Array.isArray(selected) && selected.length === question.correct.length && question.correct.every(x => selected.includes(x)))
    : selected === question.correct;
  const isSkipped = selected == null || (Array.isArray(selected) && selected.length === 0);
  const cls = isSkipped ? 'is-skipped' : isCorrect ? 'is-correct' : 'is-wrong';

  return (
    <div className={`review-item ${cls}`}>
      <div className="review-meta">
        {showNumber && <span>#{index + 1}</span>}
        <span className={`source-tag ${question.source}`}>{question.source} · Q{question.num}</span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
          {isSkipped ? 'Skipped' : isCorrect ? <><window.Icon.Check size={12}/> Correct</> : <><window.Icon.X size={12}/> Wrong</>}
        </span>
      </div>
      <div className="review-q" dangerouslySetInnerHTML={{ __html: window.renderText(question.q) }} />
      {trim ? (
        <div className="review-ans">
          <div className={`line ${isSkipped ? 'skipped' : isCorrect ? 'correct' : 'wrong'}`}>
            <span className="lbl">Your:</span>
            <span className="val" dangerouslySetInnerHTML={{ __html: isSkipped ? 'skipped' : (Array.isArray(selected) ? selected.map(s => letters[s] + ') ' + window.renderText(question.options[s])).join('<br/>') : `${letters[selected]}) ${window.renderText(question.options[selected])}`) }} />
          </div>
          {!isCorrect && (
            <div className="line correct">
              <span className="lbl">Correct:</span>
              <span className="val" dangerouslySetInnerHTML={{ __html: (Array.isArray(question.correct) ? question.correct.map(c => letters[c] + ') ' + window.renderText(question.options[c])).join('<br/>') : `${letters[question.correct]}) ${window.renderText(question.options[question.correct])}`) }} />
            </div>
          )}
        </div>
      ) : (
        <div className="review-ans-full">
          {question.options.map((opt, i) => {
            const isOptCorrect = Array.isArray(question.correct) ? question.correct.includes(i) : i === question.correct;
            const isOptSelected = Array.isArray(selected) ? selected.includes(i) : i === selected;
            const mark = isOptCorrect ? 'correct' : isOptSelected ? 'wrong' : 'neutral';
            const tag = isOptCorrect ? (isOptSelected ? 'Your & Correct' : 'Correct')
              : isOptSelected ? 'Your' : '';
            return (
              <div key={i} className={`line-full ${mark}`}>
                <span className="lbl">{letters[i]})</span>
                <span className="val" dangerouslySetInnerHTML={{ __html: window.renderText(opt) }} />
                {tag && <span className="mini-tag">{tag}</span>}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

// Review toggle control
function TrimToggle({ value, onChange }) {
  return (
    <div style={{ display: 'inline-flex', alignItems: 'center', gap: 10 }}>
      <span style={{ fontSize: 12, color: 'var(--text-dim)' }}>Trim to your + correct</span>
      <button
        type="button"
        className={`pill-toggle ${value ? 'on' : ''}`}
        onClick={() => onChange(!value)}
        aria-pressed={value}
      >
        <span className="pill-toggle-thumb" />
      </button>
      <span className={`pill-toggle-state ${value ? 'on' : ''}`}>{value ? 'ON' : 'OFF'}</span>
    </div>
  );
}

window.ReviewItem = ReviewItem;
window.TrimToggle = TrimToggle;

// Results view
function ResultsView({ questions, answers, elapsedMs, mode, onRestart, onHome }) {
  const { formatDuration } = window.QuizUtils;
  const [trim, setTrim] = useState(true);
  
  let correct = 0, wrong = 0, skipped = 0;
  answers.forEach((a, i) => {
    if (a == null || (Array.isArray(a) && a.length === 0)) skipped++;
    else {
      const isCorrect = Array.isArray(questions[i].correct) 
        ? (Array.isArray(a) && a.length === questions[i].correct.length && questions[i].correct.every(x => a.includes(x)))
        : a === questions[i].correct;
      if (isCorrect) correct++;
      else wrong++;
    }
  });
  
  const total = questions.length;
  const pct = total > 0 ? Math.round((correct / total) * 100) : 0;

  // Ring geometry
  const r = 78;
  const c = 2 * Math.PI * r;
  const ringColor = pct >= 80 ? 'var(--success)' : pct >= 50 ? 'var(--hint)' : 'var(--danger)';

  return (
    <div>
      <div className="card result-hero">
        <div className="score-ring">
          <svg width="180" height="180">
            <circle cx="90" cy="90" r={r} fill="none" stroke="var(--border)" strokeWidth="10" />
            <circle
              cx="90" cy="90" r={r} fill="none"
              stroke={ringColor} strokeWidth="10" strokeLinecap="round"
              strokeDasharray={c}
              strokeDashoffset={c - (c * pct / 100)}
              style={{ transition: 'stroke-dashoffset 0.8s ease-out' }}
            />
          </svg>
          <div className="score-value">
            {pct}<span className="pct">%</span>
          </div>
        </div>
        <div className="score-label">
          {correct} of {total} correct · {formatDuration(elapsedMs)}
        </div>
        <div className="result-stats">
          <div className="stat correct"><div className="stat-label">Correct</div><div className="stat-value">{correct}</div></div>
          <div className="stat wrong"><div className="stat-label">Wrong</div><div className="stat-value">{wrong}</div></div>
          <div className="stat skipped"><div className="stat-label">Skipped</div><div className="stat-value">{skipped}</div></div>
          <div className="stat"><div className="stat-label">Mode</div><div className="stat-value" style={{ fontSize: 14, textTransform: 'capitalize' }}>{mode}</div></div>
        </div>
        <div style={{ display: 'flex', gap: 8, justifyContent: 'center', marginTop: 24, flexWrap: 'wrap' }}>
          <button className="btn btn-primary" onClick={onRestart}>Try Again</button>
          <button className="btn btn-ghost" onClick={onHome}>Back to Home</button>
        </div>
      </div>

      <div className="card result-review">
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12, marginBottom: 16, flexWrap: 'wrap' }}>
          <h2 style={{ fontSize: 15, fontWeight: 600, margin: 0 }}>Review</h2>
          <TrimToggle value={trim} onChange={setTrim} />
        </div>
        {questions.map((q, i) => (
          <ReviewItem key={i} question={q} selected={answers[i]} index={i} trim={trim} showNumber />
        ))}
      </div>
    </div>
  );
}

// Finish celebration — shown the instant the quiz ends, before the detailed review
function CelebrationModal({ record, correct, total, pct, wrong, skipped, elapsedMs, onReview, onRestart, onHome, onHistory }) {
  const { formatDuration } = window.QuizUtils;
  const isGreat = pct >= 90;
  const isGood = pct >= 70;
  const isOk = pct >= 50;
  const title = isGreat ? 'Outstanding!' : isGood ? 'Nicely done!' : isOk ? 'Quiz complete' : 'Keep practicing';
  const IconBig = isGreat ? window.Icon.Trophy : isGood ? window.Icon.Confetti : isOk ? window.Icon.Sparkles : window.Icon.Book;
  const iconColor = isGreat ? 'var(--success)' : isGood ? 'var(--accent)' : isOk ? 'var(--hint)' : 'var(--text-dim)';
  const sub = isGreat ? 'You crushed it — exam ready.'
    : isGood ? 'Solid performance. Review the misses.'
    : isOk ? 'Not bad — another round will sharpen this.'
    : "Let's review where it went wrong.";

  const confetti = pct >= 70 ? Array.from({ length: 32 }, (_, i) => {
    const colors = ['#7aa2ff', '#6ee7a7', '#ffd84d', '#ff8a8a', '#b5c4ff'];
    return { left: Math.random() * 100, delay: Math.random() * 0.4, dur: 1.8 + Math.random() * 1.2, color: colors[i % colors.length], key: i };
  }) : [];

  return (
    <div className="celebrate-backdrop">
      <div className="celebrate-card">
        {confetti.length > 0 && (
          <div className="confetti">
            {confetti.map(c => (
              <span key={c.key} className="confetti-piece" style={{
                left: c.left + '%', background: c.color,
                animationDelay: c.delay + 's', animationDuration: c.dur + 's',
              }} />
            ))}
          </div>
        )}
        <div className="celebrate-emoji" style={{ color: iconColor }}><IconBig size={56} /></div>
        <div className="celebrate-title">{title}</div>
        <div className="celebrate-sub">{sub}</div>
        <div className="celebrate-score" style={{
          color: isGreat ? 'var(--success)' : isGood ? 'var(--accent)' : isOk ? 'var(--hint)' : 'var(--danger)'
        }}>
          {pct}<span className="pct-sm">%</span>
        </div>
        <div style={{ fontFamily: 'var(--mono)', fontSize: 12, color: 'var(--text-faint)' }}>
          {correct} of {total} correct · {formatDuration(elapsedMs)}
        </div>
        <div className="celebrate-breakdown">
          <div className="cb-item good"><span className="cb-val">{correct}</span><span className="cb-lbl">Correct</span></div>
          <div className="cb-item bad"><span className="cb-val">{wrong}</span><span className="cb-lbl">Wrong</span></div>
          <div className="cb-item skip"><span className="cb-val">{skipped}</span><span className="cb-lbl">Skipped</span></div>
        </div>
        <div style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--text-faint)', marginTop: 14, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}>
          <window.Icon.Check size={12}/> Saved to your history
        </div>
        <div className="celebrate-actions">
          <button className="btn btn-primary" onClick={onReview}>Review Answers</button>
          <button className="btn btn-ghost" onClick={() => window.ResultExport.downloadResult(record)}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
            Download result file
          </button>
          <button className="btn btn-ghost" onClick={onHistory}>View History</button>
          <button className="btn btn-ghost" onClick={onRestart}>Try Again</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { QuestionView, ProgressHeader, QuestionNav, ResultsView, CelebrationModal, renderText });
