/* blueyetutor — /assignments  (role-aware)
 *
 *  student : 내 과제 목록 → PDF 인라인 보기 + 다운로드 + MCQ 선택형 제출
 *            + FRQ 사진/파일 업로드 (점수는 학생에게 비공개)
 *  teacher : 배정 현황 (학생별 제출/MCQ 점수/FRQ 채점 상태) + 채점 UI
 *
 *  GET  /api/assignments              → 역할별 목록
 *  GET  /api/assignments/{id}/pdf     → 문제집 PDF (inline; iframe·blob 둘 다)
 *  POST /api/assignments/{id}/submit  → { mcq:{n:answer} } → MCQ 자동채점
 *  POST /api/assignments/{id}/frq     → multipart files (이미지·PDF 혼합 허용)
 */
const { useState: asUseState, useEffect: asUseEffect } = React;
const _MCQ_OPTIONS = ["A", "B", "C", "D", "E"];
const _isPdfName = n => /\.pdf$/i.test(n || "");

function AssignmentsPage() {
  const store = useStore();
  const role = (store.user && store.user.role) || "teacher";
  asUseEffect(() => { window.storeActions.fetchAssignments(); }, []);
  const list = store.assignments || [];

  return (
    <div className="page col" style={{ gap: 20 }}>
      <div className="page-header">
        <div className="eyebrow">Assignments</div>
        <h1>{role === "student" ? "내 과제" : "배정 현황"}</h1>
      </div>

      {list.length === 0 ? (
        <EmptyState
          title={role === "student" ? "배정된 과제가 없습니다" : "배정한 과제가 없습니다"}
          hint={role === "student"
            ? "선생님이 과제를 배정하면 여기에 표시됩니다."
            : "History 탭에서 만든 문제집을 학생 이메일로 배정하세요."}
        />
      ) : (
        <div className="col" style={{ gap: 12 }}>
          {list.map(a => role === "student"
            ? <StudentAssignment key={a.id} a={a} />
            : <TeacherAssignmentRow key={a.id} a={a} />)}
        </div>
      )}
    </div>
  );
}

// ---------- teacher: read-only status row ----------
function TeacherAssignmentRow({ a }) {
  const s = a.submission || {};
  const [open, setOpen] = asUseState(false);
  const gradable = a.n_frq > 0 && s.submitted;
  const [score, setScore] = asUseState(s.frq_score != null ? String(s.frq_score) : "");
  const [smax, setSmax] = asUseState(s.frq_max != null ? String(s.frq_max) : String(a.n_frq || ""));
  const [fb, setFb] = asUseState(s.feedback || "");
  const [busy, setBusy] = asUseState(false);
  const [msg, setMsg] = asUseState("");

  const save = async () => {
    setBusy(true); setMsg("");
    const r = await window.storeActions.gradeFrq(a.id, parseFloat(score) || 0,
      parseFloat(smax) || 0, fb.trim());
    setBusy(false);
    setMsg(r && r.ok ? "채점 저장됨" : "저장 실패: " + ((r && r.message) || ""));
  };

  return (
    <Card>
      <div className="card-header" style={{ cursor: "pointer" }} onClick={() => setOpen(!open)}>
        {open ? <Icon.ChevDown /> : <Icon.ChevRight />}
        <Icon.Notebook />
        <strong>{a.title}</strong>
        <Badge>{a.subject || "—"}</Badge>
        <span className="muted small mono">{a.student_email}</span>
        <span className="muted small">MCQ {a.n_mcq} · FRQ {a.n_frq}</span>
        <div className="spacer" />
        {!s.submitted ? <Badge kind="warn">미제출</Badge> : (
          <>
            <Badge kind="ok">MCQ {s.mcq_correct}/{s.mcq_total}</Badge>
            {a.n_frq > 0 && (s.graded
              ? <Badge kind="ok">FRQ {s.frq_score}/{s.frq_max}</Badge>
              : <Badge kind="warn">FRQ 채점 대기{s.frq_count ? ` · 첨부 ${s.frq_count}` : " · 첨부 없음"}</Badge>)}
          </>
        )}
      </div>

      {open && (
        <div className="card-body col" style={{ gap: 14 }}>
          {!gradable ? (
            <div className="muted small">
              {a.n_frq === 0 ? "FRQ 없는 과제입니다 (MCQ 자동채점만)."
                             : "학생이 아직 제출하지 않았습니다."}
            </div>
          ) : (
            <>
              {s.frq_count > 0 ? (
                <div>
                  <div style={{ fontSize: 12, fontWeight: 600, color: "var(--text-2)", marginBottom: 6 }}>
                    학생 FRQ 첨부 ({s.frq_count}개)
                  </div>
                  <div style={{ display: "grid", gap: 8, gridTemplateColumns: "repeat(auto-fill, minmax(160px, 1fr))" }}>
                    {(s.frq_files || Array.from({ length: s.frq_count }, () => "")).map((nm, i) => {
                      const href = `/api/assignments/${a.id}/frq/${i}`;
                      const pdf = _isPdfName(nm);
                      return (
                        <a key={i} href={href} target="_blank" rel="noopener noreferrer"
                           title={nm || `첨부 ${i + 1}`}
                           style={{ textDecoration: "none", color: "inherit" }}>
                          {pdf ? (
                            <div style={{
                              display: "flex", alignItems: "center", gap: 8,
                              padding: "12px 10px", borderRadius: 6,
                              border: "1px solid var(--border)", background: "var(--bg-1)",
                            }}>
                              <Icon.File />
                              <span className="small" style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                                {nm || `FRQ ${i + 1}.pdf`}
                              </span>
                            </div>
                          ) : (
                            <img src={href} alt={`FRQ ${i + 1}`}
                              style={{ width: "100%", borderRadius: 6, border: "1px solid var(--border)" }} />
                          )}
                        </a>
                      );
                    })}
                  </div>
                </div>
              ) : (
                <Banner kind="warn">학생이 아직 FRQ 답안을 올리지 않았습니다.</Banner>
              )}
              <FrqAiAssistPlaceholder />

              <div className="row" style={{ gap: 12, flexWrap: "wrap", alignItems: "flex-end" }}>
                <Field label="FRQ 점수">
                  <input className="input" type="number" step="0.5" value={score}
                    onChange={e => setScore(e.target.value)} style={{ width: 90 }} />
                </Field>
                <Field label="만점">
                  <input className="input" type="number" step="0.5" value={smax}
                    onChange={e => setSmax(e.target.value)} style={{ width: 90 }} />
                </Field>
                <Field label="피드백 (선택)" className="grow">
                  <input className="input" value={fb} onChange={e => setFb(e.target.value)}
                    placeholder="학생에게 보일 코멘트" />
                </Field>
                <Button variant="primary" disabled={busy} onClick={save}>
                  {busy ? "저장 중…" : "채점 저장"}
                </Button>
              </div>
              {msg && <div className="muted small">{msg}</div>}
            </>
          )}
        </div>
      )}
    </Card>
  );
}

// AI grading helpers — buttons only, wiring lands later. v1 = transcription
// (손글씨 → LaTeX/평문), v2 = rubric-based draft 채점 (선생님 override).
function FrqAiAssistPlaceholder() {
  return (
    <div style={{
      border: "1px dashed var(--border)", borderRadius: 8,
      padding: 12, background: "var(--bg-1, #f8f8fa)", opacity: 0.9,
    }}>
      <div className="row" style={{ gap: 8, alignItems: "center", marginBottom: 6 }}>
        <Icon.Wand />
        <strong>AI 채점 보조</strong>
        <Badge kind="warn">준비 중</Badge>
      </div>
      <div className="muted small" style={{ marginBottom: 8, lineHeight: 1.55 }}>
        학생이 손으로 푼 풀이 사진을 AI가 텍스트로 옮겨주거나, rubric 기준
        채점 초안을 제시합니다. 선생님은 그대로 저장하거나 수정해서 확정합니다.
      </div>
      <div className="cluster">
        <Button disabled><Icon.Edit /> 손글씨 → 텍스트 변환</Button>
        <Button variant="ghost" disabled><Icon.Target /> AI 채점 초안 받기</Button>
      </div>
    </div>
  );
}

// ---------- student: solve + submit ----------
// MCQ answers are stored client-side as { [qnum]: Set<letter> }; the wire
// format stays "B" or "B,D" so the existing backend grader (which already
// splits on comma + normalises) doesn't change.
function StudentAssignment({ a }) {
  const sub = a.submission || {};
  const [open, setOpen] = asUseState(!sub.submitted);
  const [ans, setAns] = asUseState({});            // { q: Set<letter> }
  const [busy, setBusy] = asUseState(false);
  const [err, setErr] = asUseState("");
  // Track *whether* it's been submitted; the actual MCQ score is intentionally
  // hidden from the student per teacher request.
  const [submitted, setSubmitted] = asUseState(!!sub.submitted);
  const [showPdf, setShowPdf] = asUseState(false);

  const n = a.n_mcq || 0;
  const fileRef = React.useRef(null);
  const camRef = React.useRef(null);
  const [frqBusy, setFrqBusy] = asUseState(false);
  const [frqMsg, setFrqMsg] = asUseState("");

  const toggleLetter = (q, L) => setAns(prev => {
    const cur = new Set(prev[q] || []);
    if (cur.has(L)) cur.delete(L); else cur.add(L);
    return { ...prev, [q]: cur };
  });
  const _wireMcq = () => {
    const out = {};
    for (const q of Object.keys(ans)) {
      const arr = [...(ans[q] || [])].sort();   // canonical "B,D"
      if (arr.length) out[q] = arr.join(",");
    }
    return out;
  };

  const submit = async () => {
    setBusy(true); setErr("");
    const r = await window.storeActions.submitMcq(a.id, _wireMcq());
    setBusy(false);
    if (!r || !r.ok) { setErr((r && r.message) || "제출에 실패했습니다."); return; }
    setSubmitted(true);
  };
  const uploadFrq = async e => {
    const files = Array.from(e.target.files || []);
    if (!files.length) return;
    setFrqBusy(true); setFrqMsg("");
    const r = await window.storeActions.uploadFrq(a.id, files);
    setFrqBusy(false);
    if (fileRef.current) fileRef.current.value = "";
    if (camRef.current) camRef.current.value = "";
    setFrqMsg(r && r.ok ? `${r.count}개 업로드 완료 — 선생님이 채점합니다.`
                        : "업로드 실패: " + ((r && r.message) || ""));
  };

  const dlName = a.title ? `${a.title}.pdf` : "assignment.pdf";

  return (
    <Card>
      <div className="card-header" style={{ cursor: "pointer" }} onClick={() => setOpen(!open)}>
        {open ? <Icon.ChevDown /> : <Icon.ChevRight />}
        <Icon.Notebook />
        <strong>{a.title}</strong>
        <Badge>{a.subject || "—"}</Badge>
        <span className="muted small">MCQ {a.n_mcq}{a.n_frq ? ` · FRQ ${a.n_frq}` : ""}</span>
        <div className="spacer" />
        {submitted
          ? <Badge kind="ok">제출 완료</Badge>
          : <Badge kind="warn">미제출</Badge>}
      </div>

      {open && (
        <div className="card-body col" style={{ gap: 16 }}>
          <div className="row" style={{ gap: 10, flexWrap: "wrap", alignItems: "center" }}>
            <Button onClick={() => setShowPdf(s => !s)}>
              <Icon.Expand /> {showPdf ? "문제집 접기" : "문제집 펼쳐 보기"}
            </Button>
            <Button variant="ghost"
              onClick={() => window.storeActions.downloadAssignmentPdf(a.id, dlName)}>
              <Icon.Download /> 다운로드
            </Button>
            <a className="btn" href={`/api/assignments/${a.id}/pdf`}
               target="_blank" rel="noopener noreferrer">
              새 탭에서 열기
            </a>
          </div>

          {showPdf && (
            <div style={{
              border: "1px solid var(--border)", borderRadius: 8,
              overflow: "hidden", background: "#222",
            }}>
              <iframe title={a.title || "assignment"}
                src={`/api/assignments/${a.id}/pdf#toolbar=1&navpanes=0&view=FitH`}
                style={{ width: "100%", height: "80vh", border: 0, display: "block" }} />
            </div>
          )}

          {n > 0 && (
            <div>
              <div style={{ fontSize: 12, fontWeight: 600, color: "var(--text-2)", marginBottom: 8 }}>
                MCQ ({n}문제) — 정답을 클릭해서 선택하세요. 복수정답 문제는 여러 개 클릭.
              </div>
              <div style={{ display: "grid", gap: 10, gridTemplateColumns: "repeat(auto-fill, minmax(260px, 1fr))" }}>
                {Array.from({ length: n }, (_, i) => String(i + 1)).map(q => {
                  const sel = ans[q] || new Set();
                  return (
                    <div key={q} className="row" style={{ gap: 8, alignItems: "center" }}>
                      <span className="muted small" style={{ width: 24, textAlign: "right", fontWeight: 600 }}>{q}.</span>
                      <div className="cluster" style={{ gap: 4, flexWrap: "nowrap" }}>
                        {_MCQ_OPTIONS.map(L => (
                          <button key={L} type="button"
                            className={"chip " + (sel.has(L) ? "active" : "")}
                            onClick={() => toggleLetter(q, L)}
                            style={{ minWidth: 34, padding: "4px 10px" }}>
                            {L}
                          </button>
                        ))}
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          )}

          {a.n_frq > 0 && (
            <div className="col" style={{ gap: 8 }}>
              <div style={{ fontSize: 12, fontWeight: 600, color: "var(--text-2)" }}>
                FRQ ({a.n_frq}문제) — 답안을 사진으로 찍거나, 파일(PDF·이미지)을 올리세요. 선생님이 채점합니다.
              </div>
              <div className="row" style={{ gap: 10, alignItems: "center", flexWrap: "wrap" }}>
                <Button disabled={frqBusy} onClick={() => camRef.current && camRef.current.click()}>
                  {frqBusy ? "업로드 중…" : "사진 찍어 올리기"}
                </Button>
                <Button variant="ghost" disabled={frqBusy}
                  onClick={() => fileRef.current && fileRef.current.click()}>
                  파일·갤러리에서 선택
                </Button>
                {/* Camera-only input: forces device camera on mobile. */}
                <input ref={camRef} type="file" accept="image/*" multiple capture="environment"
                  style={{ display: "none" }} onChange={uploadFrq} />
                {/* General picker: gallery + Files app + PDFs. */}
                <input ref={fileRef} type="file" accept="image/*,application/pdf" multiple
                  style={{ display: "none" }} onChange={uploadFrq} />
                {sub.frq_count > 0 && <Badge kind="ok">업로드됨 {sub.frq_count}개</Badge>}
              </div>
              {frqMsg && <div className="muted small">{frqMsg}</div>}
            </div>
          )}

          {submitted && (
            <Banner kind="ok" title="MCQ 답안 제출 완료">
              다시 제출하면 답안이 갱신됩니다. 점수는 선생님이 직접 확인해서 알려줘요.
            </Banner>
          )}
          {sub.graded && sub.feedback && (
            <Banner kind="ok" title="선생님 피드백">
              {sub.feedback}
            </Banner>
          )}
          {err && <Banner kind="error">{err}</Banner>}

          <div>
            <Button variant="primary" size="lg" disabled={busy || n === 0} onClick={submit}>
              {busy ? "제출 중…" : submitted ? "다시 제출" : "MCQ 답 제출"}
            </Button>
          </div>
        </div>
      )}
    </Card>
  );
}

Object.assign(window, { AssignmentsPage, TeacherAssignmentRow, StudentAssignment });
