<script>
  /**
   * /study/cards-review — 암기카드 검수 (공부 암기노트 Phase 1).
   *
   * needs_review=true 카드를 '출처 문제별 그룹'으로 보고 채택(승인)/수정/폐기.
   * backend: GET /study-cards?needs_review=true (그룹) · /study-cards/needs-review/count
   *          PATCH /study-cards/{id}(승인/수정) · DELETE /study-cards/{id} · POST /approve-batch
   * 전체 일괄승인 없음 — 문제 단위 승인만(품질 관찰 우선).
   */
  import { onMount } from 'svelte';
  import { goto } from '$app/navigation';
  import { api } from '$lib/api';
  import { addToast } from '$lib/stores/toast';
  import {
    ArrowLeft, Check, Pencil, Trash2, X, CheckCheck, FileText, Repeat,
  } from 'lucide-svelte';
  import Button from '$lib/components/ui/Button.svelte';
  import Skeleton from '$lib/components/ui/Skeleton.svelte';
  import EmptyState from '$lib/components/ui/EmptyState.svelte';
  import { renderMathMarkdown, renderMathMarkdownInline } from '$lib/utils/mathMarkdown';

  let loading = $state(true);
  let groups = $state([]); // [{ source_question_id, question_text, correct_choice, cards: [...] }]
  let total = $state(0);
  let fmtFilter = $state(''); // '' | 'cloze' | 'qa'
  let editing = $state(null); // card id 편집 중
  let draft = $state({ cue: '', fact: '', cloze_text: '' });

  let shownGroups = $derived(
    fmtFilter
      ? groups
          .map((g) => ({ ...g, cards: g.cards.filter((c) => c.format === fmtFilter) }))
          .filter((g) => g.cards.length > 0)
      : groups,
  );

  async function load() {
    loading = true;
    try {
      const q = fmtFilter ? `&format=${fmtFilter}` : '';
      groups = (await api(`/study-cards?needs_review=true${q}`)) ?? [];
      const c = await api('/study-cards/needs-review/count');
      total = c?.count ?? 0;
    } catch (err) {
      addToast('error', err?.detail || '카드 조회 실패');
      groups = [];
    } finally {
      loading = false;
    }
  }

  // 로컬 상태에서 카드 제거 (승인/삭제 후 큐에서 사라짐)
  function removeCard(qid, cardId) {
    groups = groups
      .map((g) =>
        g.source_question_id === qid
          ? { ...g, cards: g.cards.filter((c) => c.id !== cardId) }
          : g,
      )
      .filter((g) => g.cards.length > 0);
    total = Math.max(0, total - 1);
  }

  function removeGroup(qid, n) {
    groups = groups.filter((g) => g.source_question_id !== qid);
    total = Math.max(0, total - n);
  }

  async function approve(qid, cardId) {
    try {
      await api(`/study-cards/${cardId}`, { method: 'PATCH', body: JSON.stringify({ needs_review: false }) });
      removeCard(qid, cardId);
      addToast('success', '승인됨');
    } catch (err) {
      addToast('error', err?.detail || '승인 실패');
    }
  }

  async function remove(qid, cardId) {
    if (!confirm('이 카드를 폐기할까요? (되돌릴 수 없음)')) return;
    try {
      await api(`/study-cards/${cardId}`, { method: 'DELETE' });
      removeCard(qid, cardId);
      addToast('success', '폐기됨');
    } catch (err) {
      addToast('error', err?.detail || '삭제 실패');
    }
  }

  async function approveGroup(qid, n) {
    try {
      const r = await api('/study-cards/approve-batch', {
        method: 'POST', body: JSON.stringify({ source_question_id: qid }),
      });
      removeGroup(qid, n);
      addToast('success', `${r?.approved ?? n}장 승인됨`);
    } catch (err) {
      addToast('error', err?.detail || '일괄 승인 실패');
    }
  }

  function startEdit(card) {
    editing = card.id;
    draft = { cue: card.cue, fact: card.fact, cloze_text: card.cloze_text ?? '' };
  }
  function cancelEdit() { editing = null; }

  async function saveEdit(qid, cardId) {
    try {
      const body = { cue: draft.cue, fact: draft.fact, cloze_text: draft.cloze_text || null };
      await api(`/study-cards/${cardId}`, { method: 'PATCH', body: JSON.stringify(body) });
      editing = null;
      // 수정 = 검수 완료 → 큐에서 제거
      removeCard(qid, cardId);
      addToast('success', '수정 후 승인됨');
    } catch (err) {
      addToast('error', err?.detail || '수정 실패');
    }
  }

  function setFilter(f) {
    if (fmtFilter === f) return;
    fmtFilter = f;
  }

  onMount(load);
</script>

<svelte:head><title>암기카드 검수</title></svelte:head>

<div class="mx-auto max-w-3xl px-4 py-6">
  <div class="mb-5 flex items-center gap-3">
    <Button variant="ghost" size="sm" icon={ArrowLeft} onclick={() => goto('/study')}>공부</Button>
    <h1 class="text-xl font-bold text-text">암기카드 검수</h1>
    {#if total > 0}
      <span class="rounded-full bg-accent px-2.5 py-0.5 text-xs font-bold text-white">대기 {total}</span>
    {/if}
    <div class="ml-auto flex items-center gap-1.5">
      <button class="rounded-full border px-2.5 py-1 text-xs font-semibold {fmtFilter === '' ? 'border-accent bg-accent text-white' : 'border-default bg-surface text-dim'}" onclick={() => setFilter('')}>전체</button>
      <button class="rounded-full border px-2.5 py-1 text-xs font-semibold {fmtFilter === 'cloze' ? 'border-accent bg-accent text-white' : 'border-default bg-surface text-dim'}" onclick={() => setFilter('cloze')}>cloze</button>
      <button class="rounded-full border px-2.5 py-1 text-xs font-semibold {fmtFilter === 'qa' ? 'border-accent bg-accent text-white' : 'border-default bg-surface text-dim'}" onclick={() => setFilter('qa')}>qa</button>
      <Button href="/study/cards-study" variant="secondary" size="sm" icon={Repeat}>학습</Button>
    </div>
  </div>

  <p class="mb-4 text-sm text-dim">
    AI가 추출한 암기카드를 확인하고 <b class="text-text">승인 / 수정 / 폐기</b>합니다. 승인된 카드만 학습에 쓰입니다.
  </p>

  {#if loading}
    <div class="space-y-3">{#each Array(4).fill(0) as _, i (i)}<Skeleton class="h-28 w-full" />{/each}</div>
  {:else if shownGroups.length === 0}
    <EmptyState title="검수할 카드가 없습니다" description="새 문제를 풀면 AI가 암기카드를 추출해 여기에 쌓입니다." icon={CheckCheck} />
  {:else}
    <div class="space-y-5">
      {#each shownGroups as g (g.source_question_id ?? g.question_text)}
        <div class="rounded-card border border-default bg-bg/40 p-3">
          <!-- 출처 문제 -->
          <div class="mb-3 flex items-start gap-2 rounded-lg border border-default bg-surface px-3 py-2">
            <FileText size={15} class="mt-0.5 shrink-0 text-faint" />
            <div class="min-w-0 flex-1">
              <div class="text-xs font-bold uppercase tracking-wide text-faint">출처 문제</div>
              <div class="text-sm text-text">{g.question_text}</div>
              {#if g.correct_choice}<div class="mt-0.5 text-xs text-accent">사용자 정답: {g.correct_choice}번</div>{/if}
            </div>
            {#if g.cards.length > 1 && g.source_question_id != null}
              <Button variant="secondary" size="sm" icon={CheckCheck} onclick={() => approveGroup(g.source_question_id, g.cards.length)}>{g.cards.length}장 승인</Button>
            {/if}
          </div>

          <!-- 카드들 -->
          <div class="space-y-2.5">
            {#each g.cards as c (c.id)}
              <div class="rounded-lg border border-default bg-surface p-3">
                <div class="mb-2 flex items-center gap-2">
                  <span class="rounded-full px-2 py-0.5 text-[10px] font-bold text-white {c.format === 'cloze' ? 'bg-accent' : 'bg-domain-engineering'}">{c.format}</span>
                  {#if c.flagged_by === 'source_changed' || c.flagged_by === 'source_deleted'}
                    <span class="text-[11px] text-warning">{c.flagged_by === 'source_changed' ? '문제 수정됨' : '문제 삭제됨'}</span>
                  {/if}
                </div>

                {#if editing === c.id}
                  <!-- 편집 모드 -->
                  <div class="space-y-2">
                    <label class="block text-[11px] font-semibold text-dim">앞 (단서/질문)
                      <textarea bind:value={draft.cue} rows="2" class="mt-1 w-full rounded-md border border-default bg-bg px-2 py-1.5 text-sm text-text"></textarea>
                    </label>
                    <label class="block text-[11px] font-semibold text-dim">정답 (fact)
                      <input bind:value={draft.fact} class="mt-1 w-full rounded-md border border-default bg-bg px-2 py-1.5 text-sm text-text" />
                    </label>
                    {#if c.format === 'cloze'}
                      <label class="block text-[11px] font-semibold text-dim">빈칸 문장 (cloze, [____] 포함)
                        <textarea bind:value={draft.cloze_text} rows="2" class="mt-1 w-full rounded-md border border-default bg-bg px-2 py-1.5 text-sm text-text"></textarea>
                      </label>
                    {/if}
                    <div class="flex gap-2">
                      <Button variant="primary" size="sm" icon={Check} onclick={() => saveEdit(g.source_question_id, c.id)}>저장 후 승인</Button>
                      <Button variant="ghost" size="sm" icon={X} onclick={cancelEdit}>취소</Button>
                    </div>
                  </div>
                {:else}
                  <!-- 보기 모드 -->
                  <div class="rounded-md border border-default bg-surface-active px-3 py-2 text-sm">
                    <div class="text-[10px] font-bold uppercase tracking-wide text-faint">앞</div>
                    <div class="math-area break-words">{@html renderMathMarkdownInline(c.cue)}</div>
                  </div>
                  <div class="mt-1.5 rounded-md border border-accent-ring bg-bg px-3 py-2 text-sm">
                    {#if c.format === 'cloze' && c.cloze_text}
                      <span class="math-area break-words">{@html renderMathMarkdownInline(c.cloze_text)}</span>
                      <div class="mt-1 text-xs text-accent">정답: <b class="math-area break-words">{@html renderMathMarkdownInline(c.fact)}</b></div>
                    {:else}
                      <b class="math-area break-words text-accent">{@html renderMathMarkdownInline(c.fact)}</b>
                    {/if}
                  </div>
                  {#if c.evidence?.length}
                    <div class="mt-2">
                      <span class="text-[10px] font-bold uppercase tracking-wide text-faint">근거</span>
                      <div class="markdown-body math-area mt-1 overflow-x-auto text-[11px] leading-relaxed text-dim">{@html renderMathMarkdown(c.evidence[0].snippet)}</div>
                    </div>
                  {:else if c.source_kind === 'manual'}
                    <div class="mt-2 text-[11px] text-faint">출처: 직접 추가 자료</div>
                  {:else}
                    <div class="mt-2 text-[11px] text-faint">근거: 확정 풀이(비정량 개념)</div>
                  {/if}
                  <div class="mt-2.5 flex gap-2">
                    <Button variant="primary" size="sm" icon={Check} onclick={() => approve(g.source_question_id, c.id)}>승인</Button>
                    <Button variant="ghost" size="sm" icon={Pencil} onclick={() => startEdit(c)}>수정</Button>
                    <Button variant="danger" size="sm" icon={Trash2} onclick={() => remove(g.source_question_id, c.id)}>삭제</Button>
                  </div>
                {/if}
              </div>
            {/each}
          </div>
        </div>
      {/each}
    </div>
  {/if}
</div>
