<script>
  /**
   * /study/sources — 자료 학습 hub.
   *
   * 자료실(/library) 의 자료를 학습용 인터페이스로 노출:
   *   - 좌측: 카테고리 트리 (회독 안 본 카운트 포함)
   *   - 우측: 자료 카드 목록 (회독 배지 + 클릭 시 detail 진입)
   *   - 상단 toggle: "안 본 자료만"
   *
   * 자료실 페이지(/library)의 자료 관리 (CRUD/업로드/facet/승인 대기) 기능은 제외.
   * 순수 학습 인터페이스. 자료 추가는 /library 에서 진행.
   */
  import { onMount } from 'svelte';
  import { page } from '$app/stores';
  import { goto } from '$app/navigation';
  import { api } from '$lib/api';
  import { addToast } from '$lib/stores/toast';
  import {
    ChevronRight, ChevronDown, FolderOpen, BookOpen, ArrowLeft, FolderTree, X,
  } from 'lucide-svelte';
  import DocumentCard from '$lib/components/DocumentCard.svelte';
  import EmptyState from '$lib/components/ui/EmptyState.svelte';
  import Skeleton from '$lib/components/ui/Skeleton.svelte';

  // ─── 상태 ───
  let tree = $state([]);
  let treeLoading = $state(true);
  let expanded = $state({});

  let docs = $state([]);
  let docsLoading = $state(false);
  let total = $state(0);

  let activePath = $derived($page.url.searchParams.get('path'));
  let activeSort = $derived($page.url.searchParams.get('sort') || 'updated_desc');
  let activeUnread = $derived($page.url.searchParams.get('unread') === 'true');
  let activePage = $derived(Number($page.url.searchParams.get('page')) || 1);

  const SORT_OPTIONS = [
    { value: 'updated_desc', label: '최근 수정순' },
    { value: 'title_asc', label: '제목순' },
    { value: 'created_desc', label: '등록순' },
  ];

  // ─── 데이터 로드 ───
  async function loadTree() {
    treeLoading = true;
    try {
      tree = await api('/library/tree');
    } catch {
      addToast('error', '자료 트리 로딩 실패');
    } finally {
      treeLoading = false;
    }
  }

  async function loadDocs() {
    docsLoading = true;
    try {
      const params = new URLSearchParams();
      if (activePath) params.set('path', activePath);
      if (activeSort) params.set('sort', activeSort);
      if (activeUnread) params.set('unread', 'true');
      params.set('page', String(activePage));
      params.set('page_size', '20');
      const result = await api(`/documents/library?${params}`);
      docs = result.items;
      total = result.total;
    } catch {
      addToast('error', '자료 목록 로딩 실패');
    } finally {
      docsLoading = false;
    }
  }

  onMount(loadTree);

  $effect(() => {
    void activePath; void activeSort; void activeUnread; void activePage;
    loadDocs();
  });

  // 활성 경로의 부모 자동 펼치기
  $effect(() => {
    if (activePath) {
      const parts = activePath.split('/');
      let p = '';
      for (const part of parts) {
        p = p ? `${p}/${part}` : part;
        expanded[p] = true;
      }
    }
  });

  // 회독·진도 통계 (트리 전체 합산)
  let totalCount = $derived(tree.reduce((s, n) => s + n.count, 0));
  let totalUnread = $derived(tree.reduce((s, n) => s + (n.unread_count ?? 0), 0));

  // ─── 네비게이션 ───
  function navigate(path) {
    const params = new URLSearchParams($page.url.searchParams);
    params.delete('page');
    if (path) params.set('path', path); else params.delete('path');
    goto(`/study/sources?${params}`, { noScroll: true });
  }
  function setSort(sort) {
    const params = new URLSearchParams($page.url.searchParams);
    params.set('sort', sort);
    params.delete('page');
    goto(`/study/sources?${params}`, { noScroll: true });
  }
  function toggleUnread() {
    const params = new URLSearchParams($page.url.searchParams);
    if (activeUnread) params.delete('unread');
    else params.set('unread', 'true');
    params.delete('page');
    goto(`/study/sources?${params}`, { noScroll: true });
  }
  function setPage(p) {
    const params = new URLSearchParams($page.url.searchParams);
    params.set('page', String(p));
    goto(`/study/sources?${params}`, { noScroll: true });
  }
  function toggleExpand(path) {
    expanded[path] = !expanded[path];
  }

  // 모바일 트리 drawer
  let mobileTreeOpen = $state(false);
  function openTree() { mobileTreeOpen = true; }
  function closeTree() { mobileTreeOpen = false; }
  // 카테고리 선택 시 drawer 자동 닫기 (모바일)
  function navigateAndClose(path) {
    navigate(path);
    mobileTreeOpen = false;
  }

  // 현재 경로 breadcrumb 분해
  let crumbs = $derived(activePath ? activePath.split('/') : []);
</script>

<svelte:head><title>자료 학습 — 공부</title></svelte:head>

<div class="h-full flex flex-col">
  <!-- 헤더 -->
  <div class="flex items-center justify-between gap-2 px-3 md:px-4 py-2 md:py-3 border-b border-default bg-surface shrink-0">
    <div class="flex items-center gap-2 text-xs md:text-sm min-w-0">
      <a href="/study" class="text-dim hover:text-text flex items-center gap-1 shrink-0">
        <ArrowLeft size={14} /> 공부
      </a>
      <span class="text-faint shrink-0">/</span>
      <span class="text-text font-medium flex items-center gap-1.5 shrink-0">
        <BookOpen size={14} class="text-accent" /> 자료 학습
      </span>
    </div>
    <div class="text-[10px] md:text-xs text-dim shrink-0">
      총 {totalCount} · <span class="text-text">안 본 {totalUnread}</span>
    </div>
  </div>

  <!-- 모바일 전용: 카테고리 진입 + breadcrumb -->
  <div class="md:hidden flex items-center gap-2 px-3 py-2 border-b border-default bg-surface shrink-0 overflow-x-auto">
    <button
      type="button"
      onclick={openTree}
      style="touch-action: manipulation; user-select: none; -webkit-tap-highlight-color: transparent;"
      class="flex items-center gap-1 px-3 py-1.5 rounded text-xs bg-accent/10 text-accent border border-accent/30 shrink-0"
      aria-label="카테고리 선택"
    >
      <FolderTree size={14} /> 카테고리
    </button>
    {#if crumbs.length > 0}
      <button
        type="button"
        onclick={() => navigate(null)}
        class="text-xs text-dim hover:text-text shrink-0"
      >전체</button>
      {#each crumbs as part, i}
        <span class="text-faint shrink-0">/</span>
        <button
          type="button"
          onclick={() => navigate(crumbs.slice(0, i + 1).join('/'))}
          class="text-xs whitespace-nowrap shrink-0
            {i === crumbs.length - 1 ? 'text-accent font-medium' : 'text-dim hover:text-text'}"
        >{part}</button>
      {/each}
    {:else}
      <span class="text-xs text-dim shrink-0">전체 자료</span>
    {/if}
  </div>

  <div class="flex-1 min-h-0 grid grid-cols-1 md:grid-cols-[260px_1fr] gap-0 relative">
    <!-- 좌측 트리 (데스크톱 normal, 모바일 drawer overlay) -->
    {#if mobileTreeOpen}
      <button
        type="button"
        aria-label="카테고리 닫기"
        onclick={closeTree}
        class="md:hidden fixed inset-0 z-40 bg-black/40"
      ></button>
    {/if}
    <aside
      class="border-r border-default overflow-y-auto p-2
        {mobileTreeOpen ? 'fixed left-0 top-0 bottom-0 w-72 max-w-[85vw] z-50 bg-surface shadow-2xl md:static md:shadow-none md:w-auto md:bg-transparent' : 'hidden md:block'}"
    >
      <div class="md:hidden flex items-center justify-between mb-2 px-1">
        <span class="text-sm font-semibold text-text">카테고리</span>
        <button
          type="button"
          onclick={closeTree}
          class="p-1 rounded hover:bg-bg text-dim"
          aria-label="닫기"
        ><X size={16} /></button>
      </div>
      <button
        type="button"
        onclick={() => navigateAndClose(null)}
        style="touch-action: manipulation; user-select: none; -webkit-tap-highlight-color: transparent;"
        class="w-full flex items-center justify-between gap-2 px-2 py-1.5 rounded text-sm transition-colors
          {!activePath ? 'bg-accent/15 text-accent' : 'text-text hover:bg-surface'}"
      >
        <span class="flex items-center gap-2"><FolderOpen size={14} /> 전체 자료</span>
        <span class="text-xs text-dim">{totalCount}</span>
      </button>

      {#if treeLoading}
        <div class="space-y-1 mt-2">
          {#each Array(4) as _}<Skeleton h="h-8" rounded="md" />{/each}
        </div>
      {:else}
        {#snippet treeNode(n, depth)}
          {@const isActive = activePath === n.path}
          {@const isParent = activePath?.startsWith(n.path + '/')}
          {@const hasChildren = (n.children?.length ?? 0) > 0}
          {@const isExpanded = expanded[n.path]}

          <div class="flex items-center" style="padding-left: {depth * 12}px">
            {#if hasChildren}
              <button
                type="button"
                onclick={() => toggleExpand(n.path)}
                class="p-0.5 rounded hover:bg-surface text-dim shrink-0"
                aria-label={isExpanded ? '접기' : '펼치기'}
              >
                {#if isExpanded}<ChevronDown size={12} />{:else}<ChevronRight size={12} />{/if}
              </button>
            {:else}
              <span class="w-4 shrink-0"></span>
            {/if}

            <button
              type="button"
              onclick={() => navigateAndClose(n.path)}
              style="touch-action: manipulation; user-select: none; -webkit-tap-highlight-color: transparent;"
              class="flex-1 flex items-center justify-between gap-2 px-2 py-1 rounded text-xs transition-colors text-left
                {isActive ? 'bg-accent/15 text-accent' : isParent ? 'text-text' : 'text-dim hover:bg-surface hover:text-text'}"
              aria-current={isActive ? 'page' : undefined}
            >
              <span class="truncate">{n.name}</span>
              <span class="text-[10px] text-dim shrink-0">
                {#if (n.unread_count ?? 0) > 0}
                  <span class="text-accent">{n.unread_count}</span> / {n.count}
                {:else}
                  {n.count}
                {/if}
              </span>
            </button>
          </div>

          {#if hasChildren && isExpanded}
            {#each n.children as c}
              {@render treeNode(c, depth + 1)}
            {/each}
          {/if}
        {/snippet}

        {#each tree as n}
          {@render treeNode(n, 0)}
        {/each}

        {#if tree.length === 0}
          <div class="text-xs text-dim p-3">자료실에 자료를 먼저 업로드하세요.</div>
        {/if}
      {/if}
    </aside>

    <!-- 우측 본문 -->
    <section class="overflow-y-auto p-3 md:p-4">
      <!-- 컨트롤 -->
      <div class="flex items-center gap-2 mb-3 flex-wrap">
        {#if activePath}
          <span class="text-xs text-dim">
            현재: <span class="text-text">{activePath}</span>
          </span>
        {/if}

        <select
          value={activeSort}
          onchange={(e) => setSort(e.target.value)}
          class="px-2 py-1.5 bg-surface border border-default rounded text-xs text-text outline-none focus:border-accent"
        >
          {#each SORT_OPTIONS as opt}
            <option value={opt.value}>{opt.label}</option>
          {/each}
        </select>

        <button
          type="button"
          onclick={toggleUnread}
          style="touch-action: manipulation; user-select: none; -webkit-tap-highlight-color: transparent;"
          class="px-2 py-1.5 rounded text-xs border transition-colors
            {activeUnread ? 'bg-accent/15 text-accent border-accent/40' : 'bg-surface text-dim border-default hover:text-text'}"
          aria-pressed={activeUnread}
        >
          {activeUnread ? '✓ 안 본 자료만' : '안 본 자료만'}
        </button>

        <span class="text-xs text-dim ml-auto">{total}건</span>
      </div>

      <!-- 자료 목록 -->
      {#if docsLoading}
        <div class="space-y-2">
          {#each Array(5) as _}<Skeleton h="h-20" rounded="lg" />{/each}
        </div>
      {:else if docs.length === 0}
        <EmptyState
          icon={BookOpen}
          title={activeUnread ? '안 본 자료 없음' : '자료 없음'}
          description={activeUnread ? '모든 자료를 1회 이상 보셨습니다.' : '자료실에 자료를 업로드하면 여기서 학습할 수 있습니다.'}
        />
      {:else}
        <div class="space-y-2">
          {#each docs as doc (doc.id)}
            <DocumentCard {doc} showDomain={false} />
          {/each}
        </div>

        <!-- 페이지네이션 -->
        {#if total > 20}
          <div class="flex items-center justify-center gap-2 mt-4 text-xs">
            <button
              type="button"
              disabled={activePage <= 1}
              onclick={() => setPage(activePage - 1)}
              class="px-3 py-1.5 rounded border border-default text-dim hover:text-text disabled:opacity-40"
            >이전</button>
            <span class="text-dim">{activePage} / {Math.ceil(total / 20)}</span>
            <button
              type="button"
              disabled={activePage >= Math.ceil(total / 20)}
              onclick={() => setPage(activePage + 1)}
              class="px-3 py-1.5 rounded border border-default text-dim hover:text-text disabled:opacity-40"
            >다음</button>
          </div>
        {/if}
      {/if}
    </section>
  </div>
</div>
