/* maydays — Rapids: hub, filter builder, sequential quiz */
const { useState: _rus, useEffect: _rue, useMemo: _rum, useRef: _rur } = React;

/* ====================================================
   Storage helpers — per-user, per-difficulty-variant
   ==================================================== */
const RDX_STATUS  = 'rdx_status';   // map: '{qId}__{diff}__{pool}' -> 'correct'|'incorrect'
const RDX_RATINGS = 'rdx_ratings';  // map: '{qId}__{diff}__{pool}' -> 'solid'|'shaky'|'lost'

const kKey = (poolId, qId, diff) => `${poolId}__${qId}__${diff}`;

function readStatus()  { return window.loadUserData(RDX_STATUS,  {}); }
function writeStatus(m){ window.saveUserData(RDX_STATUS, m); }
function readRatings() { return window.loadUserData(RDX_RATINGS, {}); }
function writeRatings(m){ window.saveUserData(RDX_RATINGS, m); }

/* ====================================================
   Tiny seeded shuffle (so retrying the same filter is
   stable across renders within a quiz session)
   ==================================================== */
function shuffleSeed(arr, seed) {
  const a = arr.slice();
  let s = seed >>> 0;
  for (let i = a.length - 1; i > 0; i--) {
    s = (s * 1664525 + 1013904223) >>> 0;
    const j = s % (i + 1);
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

/* ====================================================
   Build the pool of items {qId, sectionId, difficulty, question}
   that pass the filter.
   ==================================================== */
function buildPool(pool, filter, statusMap) {
  const items = [];
  pool.sections.forEach(sec => {
    if (filter.sections && !filter.sections.includes(sec.id)) return;
    sec.questions.forEach(q => {
      ['easy','medium','hard'].forEach(diff => {
        if (!filter.difficulties.includes(diff)) return;
        if (!q.vignettes || !q.vignettes[diff]) return;
        const key = kKey(pool.id, q.id, diff);
        const status = statusMap[key] || 'notdone';
        if (!filter.statuses.includes(status)) return;
        items.push({ qId: q.id, sectionId: sec.id, sectionTitle: sec.title, difficulty: diff, question: q });
      });
    });
  });
  return items;
}

/* ====================================================
   RapidsHub — 3 pool cards
   ==================================================== */
function RapidsHub({ data, onNavigate }) {
  const pools = data.RAPIDS_POOLS;
  const ids = ['dx', 'bugs', 'drugs'];
  const statusMap = readStatus();
  return (
    <div className="fade">
      <Crumbs items={[{ label: 'Home', to: { name: 'home' } }, { label: 'Rapids' }]} onNavigate={onNavigate} />

      <div className="row" style={{ justifyContent:'space-between', alignItems:'flex-end', gap: 24, marginBottom: 24 }}>
        <div>
          <div className="eyebrow">{ORN.sprig} rapids</div>
          <h1 style={{ marginTop: 8 }}>Quick reps, three pools.</h1>
          <p className="ink-soft" style={{ fontSize: 17, marginTop: 10, maxWidth: 640 }}>
            Pick a pool, set your filters (system, difficulty, status, count), and run a qbank-style
            session. Every question is a single vignette with three quick answers and a link back
            to the lesson.
          </p>
        </div>
      </div>

      <div className="grid-3">
        {ids.map(id => {
          const p = pools[id];
          const totalQs = p.sections.reduce((a, s) => a + s.questions.length, 0);
          const totalVariants = p.sections.reduce((a, s) =>
            a + s.questions.reduce((b, q) => b + Object.keys(q.vignettes||{}).length, 0), 0);
          // stats from per-user status
          let correct = 0, missed = 0, seen = 0;
          p.sections.forEach(s => s.questions.forEach(q => {
            ['easy','medium','hard'].forEach(d => {
              if (!q.vignettes || !q.vignettes[d]) return;
              const st = statusMap[kKey(p.id, q.id, d)];
              if (st) { seen++; if (st === 'correct') correct++; else missed++; }
            });
          }));
          return (
            <div key={id} className="card hov rdx-section-card"
                 onClick={() => onNavigate({ name: 'rapids-filter', poolId: id })}>
              <div style={{ position:'absolute', top: 14, right: 16, opacity: 0.55 }}>
                <BotanicalFern size={26} />
              </div>
              <div className="eyebrow">POOL</div>
              <div className="serif" style={{ fontSize: 30, marginTop: 6 }}>{p.title}</div>
              <p className="ink-soft" style={{ fontSize: 14, marginTop: 8, color: 'var(--muted)' }}>{p.tagline}</p>
              <div className="row" style={{ marginTop: 14, gap: 8, flexWrap: 'wrap' }}>
                {p.sections.slice(0, 4).map(s => <span key={s.id} className="chip">{s.title}</span>)}
                {p.sections.length > 4 && <span className="muted mono" style={{ fontSize: 11 }}>+{p.sections.length - 4} more</span>}
              </div>
              <div className="row" style={{ marginTop: 18, gap: 14, fontSize: 12, color: 'var(--muted)' }}>
                <span>{totalQs} stems · {totalVariants} variants</span>
                <span style={{ marginLeft: 'auto', color: 'var(--clay)', fontWeight: 500 }}>Set up &rarr;</span>
              </div>
              {seen > 0 && (
                <div className="row" style={{ marginTop: 14, gap: 12, fontSize: 12, color: 'var(--muted)' }}>
                  <span><span className="dot correct" /> {correct}</span>
                  <span><span className="dot incorrect" /> {missed}</span>
                  <span>· {seen} variants attempted</span>
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ====================================================
   RapidsFilter — qbank-style filter form
   ==================================================== */
function RapidsFilter({ data, poolId, onNavigate }) {
  const pool = data.RAPIDS_POOLS[poolId];
  if (!pool) {
    return <div className="card" style={{ padding: 32, textAlign:'center', color:'var(--muted)' }}>Unknown pool.</div>;
  }

  const allSecIds = pool.sections.map(s => s.id);
  const [sections, setSections]         = _rus(allSecIds);
  const [difficulties, setDifficulties] = _rus(['easy','medium','hard']);
  const [statuses, setStatuses]         = _rus(['notdone','correct','incorrect']);
  const [count, setCount]               = _rus(10);

  const statusMap = readStatus();
  const available = _rum(() => buildPool(pool, { sections, difficulties, statuses }, statusMap),
                         [pool, sections, difficulties, statuses, statusMap]);
  const max = available.length;

  // clamp count when available shrinks
  _rue(() => { if (count > max && max > 0) setCount(max); }, [max]);

  const toggle = (arr, setter, val) =>
    setter(arr.includes(val) ? arr.filter(x => x !== val) : [...arr, val]);

  const toggleAllSecs = (on) => setSections(on ? allSecIds : []);

  const start = () => {
    if (available.length === 0) return;
    const seed = Math.floor(Math.random() * 2_000_000_000);
    onNavigate({ name: 'rapids-quiz', poolId,
                 config: { sections, difficulties, statuses, count: Math.min(count, max), seed } });
  };

  return (
    <div className="fade">
      <Crumbs items={[
        { label: 'Home', to: { name: 'home' } },
        { label: 'Rapids', to: { name: 'rapids' } },
        { label: pool.title },
      ]} onNavigate={onNavigate} />

      <div className="row" style={{ justifyContent:'space-between', alignItems:'flex-end', gap: 24, marginBottom: 24 }}>
        <div>
          <div className="eyebrow">{ORN.sprig} build a session</div>
          <h1 style={{ marginTop: 8 }}>{pool.title} rapids</h1>
          <p className="ink-soft" style={{ fontSize: 16, marginTop: 8, maxWidth: 640 }}>{pool.tagline}</p>
        </div>
      </div>

      <div className="rapids-filter">

        <FilterBlock title="Sections" right={
          <div className="row" style={{ gap: 6 }}>
            <button className="link-btn" onClick={() => toggleAllSecs(true)}>All</button>
            <span className="muted mono" style={{ fontSize: 10 }}>·</span>
            <button className="link-btn" onClick={() => toggleAllSecs(false)}>None</button>
          </div>
        }>
          <div className="pill-row">
            {pool.sections.map(s => (
              <span key={s.id}
                    className={`pill ${sections.includes(s.id) ? 'active' : ''}`}
                    onClick={() => toggle(sections, setSections, s.id)}>
                {s.title}
                <span className="count mono" style={{ marginLeft: 6, fontSize: 11, opacity: 0.7 }}>{s.questions.length}</span>
              </span>
            ))}
          </div>
        </FilterBlock>

        <FilterBlock title="Difficulty">
          <div className="pill-row">
            {[
              { v:'easy',   label:'Easy — every classic finding' },
              { v:'medium', label:'Medium — fewer hints' },
              { v:'hard',   label:'Hard — minimal info' },
            ].map(d => (
              <span key={d.v}
                    className={`pill ${difficulties.includes(d.v) ? 'active' : ''}`}
                    onClick={() => toggle(difficulties, setDifficulties, d.v)}>
                {d.label}
              </span>
            ))}
          </div>
        </FilterBlock>

        <FilterBlock title="Status">
          <div className="pill-row">
            {[
              { v:'notdone',   label:'Not done' },
              { v:'correct',   label:'Correct' },
              { v:'incorrect', label:'Missed' },
            ].map(s => (
              <span key={s.v}
                    className={`pill ${statuses.includes(s.v) ? 'active' : ''}`}
                    onClick={() => toggle(statuses, setStatuses, s.v)}>
                {s.label}
              </span>
            ))}
          </div>
        </FilterBlock>

        <FilterBlock title="Number of questions">
          <div className="row" style={{ gap: 18, alignItems:'center' }}>
            <input type="range" min="1" max={Math.max(1, max)} step="1"
                   value={Math.min(count, Math.max(1, max))}
                   onChange={e => setCount(parseInt(e.target.value, 10))}
                   style={{ flex: 1 }} />
            <div className="serif" style={{ fontSize: 30, minWidth: 60, textAlign:'right' }}>{Math.min(count, max)}</div>
            <button className="btn ghost sm" onClick={() => setCount(max)} disabled={max === 0}>All ({max})</button>
          </div>
          <div className="muted" style={{ fontSize: 12.5, marginTop: 6 }}>
            {max} variant{max === 1 ? '' : 's'} match your filter.
          </div>
        </FilterBlock>

        <div className="rapids-filter-foot">
          <div className="muted" style={{ fontSize: 13 }}>
            {max === 0
              ? 'No variants match. Loosen the filter to start.'
              : <>You will see {Math.min(count, max)} of {max} possible variant{max === 1 ? '' : 's'}.</>}
          </div>
          <button className="btn" disabled={max === 0} onClick={start}>
            Start session &rarr;
          </button>
        </div>
      </div>
    </div>
  );
}

function FilterBlock({ title, right, children }) {
  return (
    <div className="filter-block">
      <div className="row" style={{ justifyContent:'space-between', alignItems:'baseline', marginBottom: 12 }}>
        <h4 style={{ margin: 0 }}>{title}</h4>
        {right}
      </div>
      {children}
    </div>
  );
}

/* ====================================================
   RapidsQuiz — one question at a time, sequential reveals
   ==================================================== */
function RapidsQuiz({ data, poolId, config, onNavigate }) {
  const pool = data.RAPIDS_POOLS[poolId];
  const statusMap = _rum(() => readStatus(), []);
  const queue = _rum(() => {
    const all = buildPool(pool, config, statusMap);
    const shuffled = shuffleSeed(all, config.seed);
    return shuffled.slice(0, config.count);
  }, [pool, config, statusMap]);

  const [idx, setIdx]               = _rus(0);
  const [done, setDone]             = _rus(false);
  const [sessionStats, setSessStat] = _rus({ correct: 0, missed: 0, solid: 0, shaky: 0, lost: 0 });

  if (!queue.length) {
    return (
      <div className="card" style={{ padding: 40, textAlign:'center', margin: '40px auto', maxWidth: 560 }}>
        <h3>No questions match this filter.</h3>
        <p className="muted" style={{ marginTop: 8 }}>Loosen the filter and try again.</p>
        <button className="btn" onClick={() => onNavigate({ name: 'rapids-filter', poolId })} style={{ marginTop: 14 }}>
          Back to filter
        </button>
      </div>
    );
  }

  if (done) {
    const pct = queue.length ? Math.round((sessionStats.correct / queue.length) * 100) : 0;
    return (
      <div className="fade">
        <Crumbs items={[
          { label: 'Home', to: { name: 'home' } },
          { label: 'Rapids', to: { name: 'rapids' } },
          { label: pool.title, to: { name: 'rapids-filter', poolId } },
          { label: 'Session complete' },
        ]} onNavigate={onNavigate} />

        <div className="quiz-end">
          <div className="eyebrow">{ORN.sprig} session complete</div>
          <h1 style={{ marginTop: 8 }}>Well done.</h1>
          <p className="ink-soft" style={{ fontSize: 16, maxWidth: 560, marginTop: 6 }}>
            You answered {queue.length} variant{queue.length === 1 ? '' : 's'} in this session.
          </p>
          <div className="quiz-end-grid">
            <Stat big={pct + '%'}        label="Accuracy" />
            <Stat big={sessionStats.correct} label="Correct" tone="sage" />
            <Stat big={sessionStats.missed}  label="Missed"  tone="clay" />
            <Stat big={sessionStats.solid}   label="Felt solid" />
            <Stat big={sessionStats.shaky}   label="Felt shaky" />
            <Stat big={sessionStats.lost}    label="Lost" />
          </div>
          <div className="row" style={{ gap: 10, marginTop: 24 }}>
            <button className="btn"      onClick={() => onNavigate({ name: 'rapids-filter', poolId })}>
              New session &rarr;
            </button>
            <button className="btn ghost" onClick={() => onNavigate({ name: 'rapids' })}>
              Back to pools
            </button>
          </div>
        </div>
      </div>
    );
  }

  const item = queue[idx];

  const advance = (deltaStats) => {
    setSessStat(s => ({
      correct: s.correct + (deltaStats.correct || 0),
      missed:  s.missed  + (deltaStats.missed  || 0),
      solid:   s.solid   + (deltaStats.solid   || 0),
      shaky:   s.shaky   + (deltaStats.shaky   || 0),
      lost:    s.lost    + (deltaStats.lost    || 0),
    }));
    if (idx + 1 >= queue.length) setDone(true);
    else setIdx(idx + 1);
  };

  return (
    <div className="fade">
      <div className="quiz-header">
        <div>
          <div className="eyebrow">{pool.title.toUpperCase()} · {item.sectionTitle.toUpperCase()} · {diffLabel(item.difficulty)}</div>
          <h2 style={{ marginTop: 6, fontSize: 26 }}>Question {idx + 1} of {queue.length}</h2>
        </div>
        <div className="quiz-actions">
          <div className="quiz-progress" aria-label="progress">
            <i style={{ width: `${(idx / queue.length) * 100}%` }} />
          </div>
          <button className="btn ghost sm" onClick={() => {
            if (confirm('Quit this session? Your saved progress per question is kept.')) {
              onNavigate({ name: 'rapids-filter', poolId });
            }
          }}>Quit</button>
        </div>
      </div>

      <QuizCard
        key={`${item.qId}_${item.difficulty}_${idx}`}
        pool={pool}
        item={item}
        onComplete={(deltaStats) => advance(deltaStats)}
        onNavigate={onNavigate}
      />
    </div>
  );
}

function diffLabel(d) {
  return d === 'easy' ? 'Easy' : d === 'hard' ? 'Hard' : 'Medium';
}

function Stat({ big, label, tone }) {
  return (
    <div className="card" style={{ padding: 22 }}>
      <div className="muted mono" style={{ fontSize: 11 }}>{label.toUpperCase()}</div>
      <div className="serif" style={{ fontSize: 36, marginTop: 4,
        color: tone === 'sage' ? 'var(--sage-2)' : tone === 'clay' ? 'var(--clay)' : 'var(--ink)' }}>{big}</div>
    </div>
  );
}

/* ====================================================
   QuizCard — vignette + sequential sub-questions
   ==================================================== */
function QuizCard({ pool, item, onComplete, onNavigate }) {
  const q = item.question;
  const parts = [
    { key: 'dx',    label: pool.labels[0], data: q.dx },
    { key: 'next',  label: pool.labels[1], data: q.next },
  ];
  if (q.assoc) parts.push({ key: 'assoc', label: pool.labels[2], data: q.assoc });

  // step = currently visible sub-question index. step grows as user answers.
  const [step, setStep]       = _rus(0);
  const [picks, setPicks]     = _rus({});      // {dx:'x', next:'y', ...}
  const [rated, setRated]     = _rus(false);

  const totalSteps = parts.length;
  const allPicked  = parts.every(p => picks[p.key]);

  const choose = (key, opt) => {
    if (picks[key]) return; // already locked in for this sub-Q
    setPicks(prev => ({ ...prev, [key]: opt }));
    // auto-advance step after a brief beat so user sees the result settle
    setTimeout(() => {
      setStep(s => Math.min(totalSteps, s + 1));
    }, 50);
  };

  const allCorrect = allPicked && parts.every(p => picks[p.key] === p.data.answer);
  const numCorrect = parts.filter(p => picks[p.key] === p.data.answer).length;

  // persist auto-status when all sub-Qs answered (once)
  _rue(() => {
    if (!allPicked) return;
    const key = kKey(pool.id, q.id, item.difficulty);
    const s = readStatus();
    s[key] = allCorrect ? 'correct' : 'incorrect';
    writeStatus(s);
  }, [allPicked]);

  const rate = (r) => {
    if (rated) return;
    setRated(true);
    const ratings = readRatings();
    ratings[kKey(pool.id, q.id, item.difficulty)] = r;
    writeRatings(ratings);
    onComplete({
      correct: allCorrect ? 1 : 0,
      missed:  allCorrect ? 0 : 1,
      solid:   r === 'solid' ? 1 : 0,
      shaky:   r === 'shaky' ? 1 : 0,
      lost:    r === 'lost'  ? 1 : 0,
    });
  };

  const vignette = q.vignettes[item.difficulty] || q.vignettes.medium;

  return (
    <div className="quiz-card">
      <div className="quiz-vignette">
        <div className="eyebrow">vignette</div>
        <p>{vignette}</p>
      </div>

      {parts.slice(0, step + 1).map((p, i) => {
        const pick = picks[p.key];
        const answered = !!pick;
        const correct = answered && pick === p.data.answer;
        return (
          <div key={p.key} className={`quiz-part ${answered ? (correct ? 'correct' : 'incorrect') : ''}`}>
            <div className="quiz-part-head">
              <span className="mono muted">{String(i + 1).padStart(2, '0')}</span>
              <span className="quiz-part-label">{p.label}</span>
              {answered && (
                <span className={`rdx-badge ${correct ? 'correct' : 'incorrect'}`}>
                  {correct ? '● Correct' : '● Missed'}
                </span>
              )}
            </div>
            <div className="quiz-options">
              {p.data.options.map(opt => {
                let cls = 'rdx-opt';
                if (answered) {
                  if (opt === p.data.answer) cls += ' correct';
                  else if (opt === pick) cls += ' incorrect';
                  else cls += ' dim';
                }
                return (
                  <button key={opt} className={cls}
                          disabled={answered}
                          onClick={() => choose(p.key, opt)}>
                    {opt}
                  </button>
                );
              })}
            </div>
            {answered && p.data.explain && (
              <div className="rdx-explain"><b>Answer: {p.data.answer}.</b> {p.data.explain}</div>
            )}
          </div>
        );
      })}

      {allPicked && (
        <div className="quiz-summary">
          <div className="row" style={{ justifyContent:'space-between', flexWrap: 'wrap', gap: 10, alignItems: 'baseline' }}>
            <div>
              <div className="eyebrow">summary</div>
              <h3 style={{ marginTop: 4 }}>{numCorrect} of {totalSteps} answered correctly.</h3>
            </div>
            {q.refLesson && (
              <button className="btn ghost sm"
                      onClick={() => onNavigate(q.refLesson.subtopicId
                                                ? { name: 'lesson', ...q.refLesson }
                                                : { name: 'topic',  ...q.refLesson })}>
                Open lesson: {q.refLessonLabel || 'in library'} &rarr;
              </button>
            )}
          </div>

          {!rated && (
            <div className="rating-bar">
              <div className="rating-prompt">How did that feel?</div>
              <div className="rating-buttons">
                <button className="rating solid" onClick={() => rate('solid')}>Solid · next →</button>
                <button className="rating shaky" onClick={() => rate('shaky')}>Shaky · next →</button>
                <button className="rating lost"  onClick={() => rate('lost')}>Lost · next →</button>
              </div>
              <div className="muted" style={{ fontSize: 12 }}>
                Self-rating saves separately from correct/missed and helps surface what to revisit.
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { RapidsHub, RapidsFilter, RapidsQuiz });
