/* blueyetutor — /history
 * Workbook history. Card list, expand to view answer key (manifest items)
 * + re-download. Answer key is recoverable from manifest even if the
 * printed PDF was generated with `answers_included=false`.
 *
 * Assumed endpoints:
 *   GET /api/workbooks                 → WbHistory[]
 *   GET /api/workbooks/{id}/pdf        → file download
 */
const { useState: histUseState } = React;

function HistoryPage() {
  const store = useStore();
  const rows = store.history;
  return (
    <div className="page col" style={{ gap: 20 }}>
      <div className="page-header">
        <div className="eyebrow">History</div>
        <h1>지금까지 만든 문제집</h1>
        <p className="subtitle">생성한 모든 문제집·Mock Exam·오답노트. 답지는 PDF 미포함이어도 여기서 항상 확인 가능합니다.</p>
      </div>
      {rows.length === 0 ? (
        <EmptyState title="아직 생성된 문제집이 없습니다."
          hint="문제집 페이지에서 첫 PDF 를 만들어 보세요."
          action={<Button variant="primary" onClick={() => location.hash = "#/workbook"}>문제집 만들러 가기</Button>} />
      ) : (
        <div className="col" style={{ gap: 8 }}>
          {rows.map(w => <HistoryRow key={w.id} w={w} />)}
        </div>
      )}
    </div>
  );
}

function HistoryRow({ w }) {
  const [open, setOpen] = histUseState(false);
  const [keyOpen, setKeyOpen] = histUseState(!w.answers_included);
  const [assignOpen, setAssignOpen] = histUseState(false);
  const [sEmail, setSEmail] = histUseState("");
  const [sTitle, setSTitle] = histUseState(w.file_name || "과제");
  const [aBusy, setABusy] = histUseState(false);
  const [aMsg, setAMsg] = histUseState(null);  // {ok, text}

  const doAssign = async () => {
    const email = sEmail.trim().toLowerCase();
    if (!/\S+@\S+\.\S+/.test(email)) { setAMsg({ ok: false, text: "이메일 형식이 올바르지 않습니다." }); return; }
    setABusy(true); setAMsg(null);
    const r = await window.storeActions.assignWorkbook(w.id, email, sTitle.trim() || w.file_name);
    setABusy(false);
    if (r && r.ok) setAMsg({ ok: true, text: `${email} 에게 배정했습니다 (MCQ ${r.n_mcq} · FRQ ${r.n_frq}). 학생은 이 이메일로 가입하면 됩니다.` });
    else setAMsg({ ok: false, text: (r && r.message) || "배정에 실패했습니다." });
  };

  return (
    <div className="card">
      <div className="card-header" style={{ cursor: "pointer" }} onClick={() => setOpen(!open)}>
        {open ? <Icon.ChevDown /> : <Icon.ChevRight />}
        <strong className="mono small">{w.created_at}</strong>
        <Badge>{w.subject || "?"}</Badge>
        <Badge>{w.qtype || "?"}</Badge>
        <span className="muted small">{w.n || "?"}문제</span>
        {w.answers_included
          ? <Badge kind="navy">답지 포함</Badge>
          : <Badge>답지 없음</Badge>}
        <div className="spacer" />
        <Button size="sm" variant="ghost" onClick={e => { e.stopPropagation(); setAMsg(null); setAssignOpen(true); }}><Icon.Students /> 학생 배정</Button>
        <Button size="sm" onClick={e => { e.stopPropagation(); window.storeActions.downloadWorkbook(w.id, w.file_name); }}><Icon.Download /> 다운로드</Button>
      </div>

      <Modal open={assignOpen} title="학생에게 배정" onClose={() => setAssignOpen(false)}
        footer={<>
          <Button variant="ghost" onClick={() => setAssignOpen(false)}>닫기</Button>
          <Button variant="primary" disabled={aBusy} onClick={doAssign}>{aBusy ? "배정 중…" : "배정"}</Button>
        </>}>
        <div className="col" style={{ gap: 12 }}>
          <div className="muted small">이 문제집을 학생 이메일로 보냅니다. 학생은 그 이메일로 가입하면 '내 과제'에서 풀고 MCQ가 자동 채점됩니다.</div>
          <Field label="학생 이메일">
            <input className="input" type="email" value={sEmail}
              onChange={e => setSEmail(e.target.value)} placeholder="student@example.com" />
          </Field>
          <Field label="과제 제목">
            <input className="input" value={sTitle} onChange={e => setSTitle(e.target.value)} maxLength={80} />
          </Field>
          {aMsg && <Banner kind={aMsg.ok ? "ok" : "error"}>{aMsg.text}</Banner>}
        </div>
      </Modal>
      {open && (
        <div className="card-body col" style={{ gap: 12 }}>
          <div className="muted small">
            단원: {w.units || "-"} &nbsp;·&nbsp; 파일: <code>{w.file_name}</code>
          </div>

          <div>
            <Button size="sm" variant="ghost" onClick={() => setKeyOpen(!keyOpen)}>
              <Icon.Key /> 답 확인 {keyOpen ? <Icon.ChevDown /> : <Icon.ChevRight />}
            </Button>
            {keyOpen && <HistoryAnswers manifest={w.manifest} />}
          </div>
        </div>
      )}
    </div>
  );
}

function HistoryAnswers({ manifest }) {
  const items = (manifest && manifest.items) || [];
  const mcq = items.filter(it => it.qtype === "MCQ");
  const frq = items.filter(it => it.qtype === "FRQ");
  if (items.length === 0) return <div className="muted small" style={{ marginTop: 8 }}>(manifest 없음 — 이 기록은 답 재현 불가)</div>;
  return (
    <div className="col" style={{ gap: 12, marginTop: 8 }}>
      {mcq.length > 0 && (
        <div className="card" style={{ background: "var(--surface-2)" }}>
          <div className="card-body">
            <h4 style={{ margin: "0 0 8px 0" }}>MCQ 정답</h4>
            <table className="table">
              <thead><tr><th>문항</th><th>정답</th><th>출처</th></tr></thead>
              <tbody>
                {mcq.map(it => (
                  <tr key={it.n}>
                    <td className="mono">{it.n}</td>
                    <td><Badge kind="navy" mono>{it.answer || "?"}</Badge></td>
                    <td className="mono small muted">{it.pdf_id} Q{it.qnum}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}
      {frq.length > 0 && (
        <div className="card" style={{ background: "var(--surface-2)" }}>
          <div className="card-body">
            <h4 style={{ margin: "0 0 8px 0" }}>FRQ scoring guide</h4>
            <div className="col" style={{ gap: 8 }}>
              {frq.map(it => (
                <div key={it.n}>
                  <div className="muted small">FRQ {it.n} — {it.pdf_id} Q{it.qnum}</div>
                  <ScoringImgs pdfId={it.pdf_id} qnum={it.qnum} />
                </div>
              ))}
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// Lazily fetch a finished workbook's FRQ scoring-guide crops for "답 확인".
function ScoringImgs({ pdfId, qnum }) {
  const [urls, setUrls] = histUseState(null);
  React.useEffect(() => {
    let live = true;
    fetch(`/api/scoring/${encodeURIComponent(pdfId)}/${qnum}`, { credentials: "include" })
      .then(r => r.ok ? r.json() : { urls: [] })
      .then(d => { if (live) setUrls(d.urls || []); })
      .catch(() => { if (live) setUrls([]); });
    return () => { live = false; };
  }, [pdfId, qnum]);
  if (urls === null) return <div className="muted small">scoring 불러오는 중…</div>;
  if (urls.length === 0) return <div className="muted small">(scoring 크롭 없음)</div>;
  return (
    <div className="col" style={{ gap: 6, marginTop: 4 }}>
      {urls.map((u, i) => <CropImg key={i} src={u} kind="frq" label={`scoring ${i + 1}`} />)}
    </div>
  );
}

Object.assign(window, { HistoryPage, HistoryRow, HistoryAnswers });
