// Records table view & detail modal
const { useState: useStateR, useMemo: useMemoR } = React;

function RecordsView({ onBack }) {
  const [records, setRecords] = useStateR(window.Store.all());
  const [filter, setFilter] = useStateR('all');
  const [detail, setDetail] = useStateR(null);
  const [confirmClear, setConfirmClear] = useStateR(false);
  const [selected, setSelected] = useStateR(new Set()); // ids
  const [mergedReview, setMergedReview] = useStateR(null); // {records, mode}
  const { formatDate, formatDuration } = window.QuizUtils;

  const filtered = useMemoR(() => {
    if (filter === 'all') return records;
    return records.filter(r => r.mode === filter);
  }, [records, filter]);

  const stats = useMemoR(() => {
    if (records.length === 0) return null;
    const avg = Math.round(records.reduce((a, r) => a + r.pct, 0) / records.length);
    const best = Math.max(...records.map(r => r.pct));
    const total = records.length;
    return { avg, best, total };
  }, [records]);

  const clear = () => {
    window.Store.clear();
    setRecords([]);
    setSelected(new Set());
    setConfirmClear(false);
  };

  const remove = (id) => {
    window.Store.remove(id);
    setRecords(window.Store.all());
    setSelected(s => { const n = new Set(s); n.delete(id); return n; });
  };

  const toggleSelect = (id) => {
    setSelected(s => {
      const n = new Set(s);
      if (n.has(id)) n.delete(id); else n.add(id);
      return n;
    });
  };

  const toggleSelectAll = () => {
    if (selected.size === filtered.length) setSelected(new Set());
    else setSelected(new Set(filtered.map(r => r.id)));
  };

  const selectedRecords = useMemoR(() => records.filter(r => selected.has(r.id)), [records, selected]);

  const exportSelected = (onlyWrong) => {
    if (selectedRecords.length === 0) return;
    const letters = ['a','b','c','d'];
    let out = `QUIZE — CYBERSECURITY EXAM PRACTICE · ${onlyWrong ? 'WRONG QUESTIONS' : 'FULL REVIEW'}\n`;
    out += `Exported: ${new Date().toString()}\n`;
    out += `Attempts: ${selectedRecords.length}\n\n`;
    const allItems = [];
    selectedRecords.forEach(rec => {
      const items = onlyWrong
        ? rec.details.filter(d => d.answered !== d.correct)
        : rec.details;
      items.forEach(q => allItems.push({ rec, q }));
    });
    out += `Total items: ${allItems.length}\n\n`;
    out += '='.repeat(60) + '\n\n';
    allItems.forEach(({ rec, q }, i) => {
      const isCorrect = q.answered === q.correct;
      const isSkipped = q.answered == null;
      const status = isSkipped ? 'SKIPPED' : isCorrect ? 'CORRECT' : 'WRONG';
      out += `[${i + 1}/${allItems.length}] ${q.source} · Q${q.num} — ${status}\n`;
      out += `  From attempt: ${formatDate(rec.ts)} (${rec.pct}%, ${rec.mode})\n`;
      out += `  Q: ${q.q}\n`;
      q.options.forEach((opt, oi) => {
        const marks = [];
        if (oi === q.correct) marks.push('CORRECT');
        if (oi === q.answered) marks.push('YOUR');
        const tag = marks.length ? ` [${marks.join(' / ')}]` : '';
        out += `    ${letters[oi]}) ${opt}${tag}\n`;
      });
      out += '\n';
    });
    const stamp = `${Date.now()}`;
    const label = onlyWrong ? 'wrong' : 'review';
    window.ResultExport.downloadBlob(out, 'text/plain', `quize-${label}-${selectedRecords.length}attempts-${stamp}.txt`);
  };

  const reviewSelected = (onlyWrong) => {
    if (selectedRecords.length === 0) return;
    const allItems = [];
    selectedRecords.forEach(rec => {
      const items = onlyWrong
        ? rec.details.filter(d => d.answered !== d.correct)
        : rec.details;
      items.forEach(q => allItems.push({ rec, q }));
    });
    setMergedReview({ items: allItems, onlyWrong, attempts: selectedRecords.length });
  };

  const allFilteredSelected = filtered.length > 0 && filtered.every(r => selected.has(r.id));
  const someSelected = selected.size > 0;

  return (
    <div>
      {records.length > 0 && <HistoryOverview records={records} />}
      <div className="card">
        <div className="records-head">
          <div>
            <h2>History</h2>
            {stats && (
              <div style={{ fontSize: 12, color: 'var(--text-faint)', fontFamily: 'var(--mono)', marginTop: 4 }}>
                {stats.total} attempts · avg {stats.avg}% · best {stats.best}%
              </div>
            )}
          </div>
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            {records.length > 0 && <button className="btn btn-sm btn-danger" onClick={() => setConfirmClear(true)}>Clear all</button>}
          </div>
        </div>

        {someSelected && (
          <div className="bulk-bar">
            <div className="bulk-info">
              <strong>{selected.size}</strong> attempt{selected.size !== 1 ? 's' : ''} selected
            </div>
            <div className="bulk-actions">
              <button className="btn btn-sm btn-ghost" onClick={() => reviewSelected(true)}>Review wrong</button>
              <button className="btn btn-sm btn-ghost" onClick={() => reviewSelected(false)}>Review all</button>
              <button className="btn btn-sm btn-ghost" onClick={() => exportSelected(true)}>
                <svg width="12" height="12" 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>
                Export wrong
              </button>
              <button className="btn btn-sm btn-ghost" onClick={() => exportSelected(false)}>
                <svg width="12" height="12" 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>
                Export all
              </button>
              <button className="btn btn-sm btn-ghost" onClick={() => setSelected(new Set())}>Clear</button>
            </div>
          </div>
        )}

        {filtered.length === 0 ? (
          <div className="empty-state">
            {records.length === 0
              ? 'No records yet. Finish a quiz to see your history here.'
              : `No ${filter} attempts yet.`}
          </div>
        ) : (
          <div style={{ overflowX: 'auto' }}>
            <table className="records-table selectable">
              <thead>
                <tr>
                  <th className="check-col">
                    <input type="checkbox" checked={allFilteredSelected} onChange={toggleSelectAll} aria-label="Select all" />
                  </th>
                  <th>Date</th>
                  <th>Mode</th>
                  <th>Score</th>
                  <th>Correct</th>
                  <th className="hide-mobile">Wrong</th>
                  <th className="hide-mobile">Skipped</th>
                  <th className="hide-mobile">Duration</th>
                  <th></th>
                </tr>
              </thead>
              <tbody>
                {filtered.map(r => {
                  const scoreCls = r.pct >= 80 ? 'high' : r.pct >= 50 ? 'mid' : 'low';
                  const isSel = selected.has(r.id);
                  return (
                    <tr key={r.id} className={isSel ? 'row-selected' : ''}>
                      <td data-label="" className="check-col">
                        <input type="checkbox" checked={isSel} onChange={() => toggleSelect(r.id)} aria-label="Select attempt" />
                      </td>
                      <td data-label="Date">{formatDate(r.ts)}</td>
                      <td data-label="Mode"><span className={`mode-pill ${r.mode}`}>{r.mode}</span></td>
                      <td data-label="Score" className={`score-cell ${scoreCls}`}>{r.pct}%</td>
                      <td data-label="Correct">{r.correct}/{r.total}</td>
                      <td data-label="Wrong" className="hide-mobile">{r.wrong}</td>
                      <td data-label="Skipped" className="hide-mobile">{r.skipped}</td>
                      <td data-label="Duration" className="hide-mobile">{formatDuration(r.durationMs)}</td>
                      <td style={{ display: 'flex', gap: 4 }}>
                        <button className="btn btn-sm btn-ghost" onClick={() => setDetail(r)}>View</button>
                        <button className="btn btn-sm btn-ghost" title="Download result" onClick={() => window.ResultExport.downloadResult(r)}>
                          <svg width="12" height="12" 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>
                        </button>
                        <button className="btn btn-sm btn-ghost" title="Delete" onClick={() => remove(r.id)}><window.Icon.X size={12}/></button>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}
      </div>

      {detail && <RecordDetailModal record={detail} onClose={() => setDetail(null)} />}
      {mergedReview && <MergedReviewModal data={mergedReview} onClose={() => setMergedReview(null)} />}
      {confirmClear && (
        <div className="modal-backdrop" onClick={() => setConfirmClear(false)}>
          <div className="modal" onClick={e => e.stopPropagation()}>
            <div className="modal-head"><h3>Clear all records?</h3></div>
            <div className="modal-body">
              <p style={{ color: 'var(--text-dim)', fontSize: 14 }}>This will permanently delete all {records.length} saved attempts. This cannot be undone.</p>
            </div>
            <div className="modal-foot">
              <button className="btn btn-ghost btn-sm" onClick={() => setConfirmClear(false)}>Cancel</button>
              <button className="btn btn-danger btn-sm" onClick={clear}>Delete all</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function RecordDetailModal({ record, onClose }) {
  const { formatDate, formatDuration } = window.QuizUtils;
  const wrongOnes = record.details.filter(d => d.answered !== d.correct);
  const [tab, setTab] = useStateR('wrong');
  const [trim, setTrim] = useStateR(true);
  const list = tab === 'wrong' ? wrongOnes : record.details;

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <h3>Attempt · {formatDate(record.ts)}</h3>
            <div style={{ fontSize: 12, color: 'var(--text-faint)', fontFamily: 'var(--mono)', marginTop: 2 }}>
              <span className={`mode-pill ${record.mode}`} style={{ marginRight: 8 }}>{record.mode}</span>
              {record.pct}% · {record.correct}/{record.total} · {formatDuration(record.durationMs)}
            </div>
          </div>
          <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
            <button className="btn btn-sm btn-ghost" onClick={() => window.ResultExport.downloadResult(record)}>
              <svg width="12" height="12" 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
            </button>
            <button className="icon-btn" onClick={onClose}><window.Icon.X size={14}/></button>
          </div>
        </div>
        <div className="modal-body">
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12, marginBottom: 16, flexWrap: 'wrap' }}>
            <div className="toggle-group" style={{ margin: 0 }}>
              <button className={tab === 'wrong' ? 'active' : ''} onClick={() => setTab('wrong')}>Wrong only ({wrongOnes.length})</button>
              <button className={tab === 'all' ? 'active' : ''} onClick={() => setTab('all')}>All ({record.details.length})</button>
            </div>
            <window.TrimToggle value={trim} onChange={setTrim} />
          </div>
          {list.length === 0 ? (
            <div className="empty-state" style={{ padding: 24, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8 }}><window.Icon.Check size={16}/> All correct!</div>
          ) : list.map((d, i) => (
            <window.ReviewItem
              key={i}
              question={{ q: d.q, options: d.options, correct: d.correct, source: d.source, num: d.num }}
              selected={d.answered}
              index={i}
              trim={trim}
              showNumber={false}
            />
          ))}
        </div>
      </div>
    </div>
  );
}

function MergedReviewModal({ data, onClose }) {
  const { formatDate } = window.QuizUtils;
  const [trim, setTrim] = useStateR(true);
  const { items, onlyWrong, attempts } = data;

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal modal-wide" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <h3>{onlyWrong ? 'Wrong questions' : 'Full review'} · {attempts} attempt{attempts !== 1 ? 's' : ''}</h3>
            <div style={{ fontSize: 12, color: 'var(--text-faint)', fontFamily: 'var(--mono)', marginTop: 2 }}>
              {items.length} question{items.length !== 1 ? 's' : ''} across selected attempts
            </div>
          </div>
          <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
            <window.TrimToggle value={trim} onChange={setTrim} />
            <button className="icon-btn" onClick={onClose}><window.Icon.X size={14}/></button>
          </div>
        </div>
        <div className="modal-body">
          {items.length === 0 ? (
            <div className="empty-state" style={{ padding: 24, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8 }}>
              <window.Icon.Check size={16}/> {onlyWrong ? 'No wrong answers in selected attempts!' : 'No questions found.'}
            </div>
          ) : items.map(({ rec, q }, i) => (
            <div key={i} style={{ marginBottom: 12 }}>
              <div className="merged-source-hint">
                from <strong>{formatDate(rec.ts)}</strong> · {rec.pct}% · {rec.mode}
              </div>
              <window.ReviewItem
                question={{ q: q.q, options: q.options, correct: q.correct, source: q.source, num: q.num }}
                selected={q.answered}
                index={i}
                trim={trim}
                showNumber={true}
              />
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function HistoryOverview({ records }) {
  const { formatDate } = window.QuizUtils;
  // chronological for chart (oldest -> newest)
  const chron = [...records].reverse();
  // Show last up to 30 attempts
  const recent = chron.slice(-30);

  const avg = Math.round(records.reduce((a, r) => a + r.pct, 0) / records.length);
  const best = Math.max(...records.map(r => r.pct));
  const lastPct = records[0].pct;
  const prevPct = records.length > 1 ? records[1].pct : null;
  const trend = prevPct != null ? lastPct - prevPct : 0;

  // Streak: how many consecutive recent attempts >= 70%
  let streak = 0;
  for (const r of records) {
    if (r.pct >= 70) streak++;
    else break;
  }

  return (
    <>
      <div className="stat-cards">
        <div className="stat-card accent">
          <div className="sc-label">Attempts</div>
          <div className="sc-value">{records.length}</div>
          <div className="sc-sub">total sessions</div>
        </div>
        <div className="stat-card success">
          <div className="sc-label">Best score</div>
          <div className="sc-value">{best}%</div>
          <div className="sc-sub">personal record</div>
        </div>
        <div className="stat-card">
          <div className="sc-label">Average</div>
          <div className="sc-value">{avg}%</div>
          <div className="sc-sub">across all attempts</div>
        </div>
        <div className="stat-card warn">
          <div className="sc-label">Last attempt</div>
          <div className="sc-value">{lastPct}%</div>
          <div className="sc-sub">
            {trend === 0 ? 'first attempt' : trend > 0 ? `▲ +${trend}%` : `▼ ${trend}%`}
            {streak >= 2 && <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, marginLeft: 6 }}> · <window.Icon.Flame size={11}/> {streak} pass streak</span>}
          </div>
        </div>
      </div>
      <div className="history-chart">
        <div className="chart-head">
          <div>
            <div className="chart-title">Score over time</div>
            <div className="chart-sub">last {recent.length} attempt{recent.length !== 1 ? 's' : ''}</div>
          </div>
        </div>
        <div className="chart-body">
          <div className="chart-grid">
            <div className="chart-grid-line" data-label="100"></div>
            <div className="chart-grid-line" data-label="75"></div>
            <div className="chart-grid-line" data-label="50"></div>
            <div className="chart-grid-line" data-label="25"></div>
            <div className="chart-grid-line" data-label="0"></div>
          </div>
          {recent.map((r, i) => {
            const cls = r.pct >= 80 ? 'high' : r.pct >= 50 ? 'mid' : 'low';
            const h = Math.max(2, (r.pct / 100) * 100);
            return (
              <div key={r.id} className={`chart-bar ${cls}`} style={{ height: h + '%' }}>
                <div className="chart-bar-tip">
                  {r.pct}% · {r.mode} · {formatDate(r.ts)}
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </>
  );
}

Object.assign(window, { HistoryOverview, RecordsView, RecordDetailModal, MergedReviewModal });

