<script>
  import { page } from '$app/stores';
  import { goto } from '$app/navigation';
  import { api } from '$lib/api';
  import { addToast } from '$lib/stores/ui';
  import { Info } from 'lucide-svelte';
  import DocumentCard from '$lib/components/DocumentCard.svelte';
  import PreviewPanel from '$lib/components/PreviewPanel.svelte';
  import DocumentViewer from '$lib/components/DocumentViewer.svelte';
  import UploadDropzone from '$lib/components/UploadDropzone.svelte';

  let documents = $state([]);
  let total = $state(0);
  let loading = $state(true);
  let searchQuery = $state('');
  let searchMode = $state('hybrid');
  let searchResults = $state(null);
  let selectedDoc = $state(null);
  let infoPanelOpen = $state(false);
  let debounceTimer;

  // URL params → filter
  let currentPage = $derived(parseInt($page.url.searchParams.get('page') || '1'));
  let filterDomain = $derived($page.url.searchParams.get('domain') || '');
  let filterSubGroup = $derived($page.url.searchParams.get('sub_group') || '');

  $effect(() => {
    const _p = currentPage;
    const _d = filterDomain;
    const _s = filterSubGroup;
    const urlQ = $page.url.searchParams.get('q') || '';
    const urlMode = $page.url.searchParams.get('mode') || 'hybrid';

    searchQuery = urlQ;
    searchMode = urlMode;
    selectedDoc = null;
    infoPanelOpen = false;

    if (urlQ) {
      doSearch(urlQ, urlMode);
    } else {
      loadDocuments();
    }
  });

  async function loadDocuments() {
    loading = true;
    searchResults = null;
    try {
      const params = new URLSearchParams();
      params.set('page', String(currentPage));
      params.set('page_size', '20');
      if (filterDomain) params.set('domain', filterDomain);
      if (filterSubGroup) params.set('sub_group', filterSubGroup);

      const data = await api(`/documents/?${params}`);
      documents = data.items;
      total = data.total;
    } catch (err) {
      addToast('error', '문서 목록 로딩 실패');
    } finally {
      loading = false;
    }
  }

  function handleSearchInput() {
    clearTimeout(debounceTimer);
    debounceTimer = setTimeout(() => {
      const params = new URLSearchParams($page.url.searchParams);
      params.delete('page');
      if (searchQuery.trim()) {
        params.set('q', searchQuery.trim());
      } else {
        params.delete('q');
      }
      if (searchMode !== 'hybrid') {
        params.set('mode', searchMode);
      } else {
        params.delete('mode');
      }
      for (const [key, val] of [...params.entries()]) {
        if (!val) params.delete(key);
      }
      const qs = params.toString();
      goto(`/documents${qs ? '?' + qs : ''}`, { noScroll: true });
    }, 300);
  }

  async function doSearch(q, mode) {
    loading = true;
    try {
      const data = await api(`/search/?q=${encodeURIComponent(q)}&mode=${mode}&limit=50`);
      searchResults = data.results;
      total = data.total;
    } catch (err) {
      addToast('error', '검색 실패');
      searchResults = [];
    } finally {
      loading = false;
    }
  }

  function changePage(p) {
    const params = new URLSearchParams($page.url.searchParams);
    if (p > 1) {
      params.set('page', String(p));
    } else {
      params.delete('page');
    }
    const qs = params.toString();
    goto(`/documents${qs ? '?' + qs : ''}`, { noScroll: true });
  }

  function clearAllFilters() {
    goto('/documents', { noScroll: true });
    searchQuery = '';
  }

  function selectDoc(doc) {
    selectedDoc = selectedDoc?.id === doc.id ? null : doc;
  }

  function handleKeydown(e) {
    if (e.key === 'Escape' && infoPanelOpen) {
      infoPanelOpen = false;
    }
  }

  let totalPages = $derived(Math.ceil(total / 20));
  let items = $derived(searchResults || documents);
  let hasActiveFilters = $derived(!!filterDomain || !!filterSubGroup || !!searchQuery);
</script>

<svelte:window on:keydown={handleKeydown} />

<div class="flex flex-col h-full">
  <!-- 상단: 문서 목록 (30% when viewer active, 100% otherwise) -->
  <div class="overflow-y-auto px-4 py-3 {selectedDoc ? 'h-[30%] shrink-0 border-b border-[var(--border)]' : 'flex-1'}">
    <!-- 업로드 드롭존 -->
    <UploadDropzone onupload={loadDocuments} />

    <!-- 검색바 + 정보 버튼 -->
    <div class="flex gap-2 mb-3">
      <input
        data-search-input
        type="text"
        bind:value={searchQuery}
        oninput={handleSearchInput}
        placeholder="검색어 입력... (/ 키로 포커스)"
        class="flex-1 px-3 py-1.5 bg-[var(--surface)] border border-[var(--border)] rounded-lg text-[var(--text)] text-sm focus:border-[var(--accent)] outline-none"
      />
      <select
        bind:value={searchMode}
        onchange={() => { if (searchQuery) handleSearchInput(); }}
        class="px-2 py-1.5 bg-[var(--surface)] border border-[var(--border)] rounded-lg text-[var(--text)] text-xs"
      >
        <option value="hybrid">하이브리드</option>
        <option value="fts">전문검색</option>
        <option value="trgm">부분매칭</option>
        <option value="vector">의미검색</option>
      </select>
      {#if selectedDoc}
        <button
          onclick={() => infoPanelOpen = !infoPanelOpen}
          class="p-1.5 rounded-lg border border-[var(--border)] hover:border-[var(--accent)] text-[var(--text-dim)] hover:text-[var(--accent)] transition-colors
            {infoPanelOpen ? 'bg-[var(--accent)]/10 border-[var(--accent)] text-[var(--accent)]' : ''}"
          aria-label="문서 정보"
          title="문서 정보"
        >
          <Info size={16} />
        </button>
      {/if}
    </div>

    <!-- 결과 헤더 -->
    {#if !loading}
      <div class="flex items-center justify-between mb-2">
        <div class="flex items-center gap-2">
          <span class="text-[10px] text-[var(--text-dim)]">{total}건</span>
          {#if filterDomain}
            <span class="text-[10px] text-[var(--accent)] bg-[var(--accent)]/10 px-1.5 py-0.5 rounded">
              {filterDomain.replace('Knowledge/', '')}{filterSubGroup ? ` / ${filterSubGroup}` : ''}
            </span>
          {/if}
        </div>
        {#if hasActiveFilters}
          <button
            onclick={clearAllFilters}
            class="text-[10px] text-[var(--text-dim)] hover:text-[var(--text)] px-1.5 py-0.5 rounded border border-[var(--border)]"
          >
            초기화
          </button>
        {/if}
      </div>
    {/if}

    <!-- 결과 -->
    {#if loading}
      <div class="space-y-1.5">
        {#each Array(5) as _}
          <div class="bg-[var(--surface)] rounded-lg p-3 border border-[var(--border)] animate-pulse h-14"></div>
        {/each}
      </div>
    {:else if items.length === 0}
      <div class="text-center py-12 text-[var(--text-dim)]">
        {#if searchQuery}
          <p class="text-sm mb-2">'{searchQuery}'에 대한 결과가 없습니다</p>
          <button onclick={clearAllFilters} class="text-xs text-[var(--accent)] hover:underline">필터 초기화</button>
        {:else if hasActiveFilters}
          <p class="text-sm mb-2">이 분류에 문서가 없습니다</p>
          <button onclick={clearAllFilters} class="text-xs text-[var(--accent)] hover:underline">필터 초기화</button>
        {:else}
          <p class="text-sm">등록된 문서가 없습니다</p>
        {/if}
      </div>
    {:else}
      <div class="space-y-1">
        {#each items as doc}
          <DocumentCard
            {doc}
            showDomain={!filterDomain}
            selected={selectedDoc?.id === doc.id}
            onselect={selectDoc}
          />
        {/each}
      </div>

      {#if !searchResults && totalPages > 1}
        <div class="flex justify-center gap-1 mt-4">
          {#each Array(totalPages) as _, i}
            <button
              onclick={() => changePage(i + 1)}
              class="px-2.5 py-0.5 rounded text-xs transition-colors
                {currentPage === i + 1 ? 'bg-[var(--accent)] text-white' : 'bg-[var(--surface)] text-[var(--text-dim)] hover:text-[var(--text)]'}"
            >
              {i + 1}
            </button>
          {/each}
        </div>
      {/if}
    {/if}
  </div>

  <!-- 하단: 뷰어 (70%, 전체 너비) -->
  {#if selectedDoc}
    <div class="flex-1 min-h-0">
      <DocumentViewer doc={selectedDoc} />
    </div>
  {/if}
</div>

<!-- 정보 패널: 우측 전체 높이 drawer -->
{#if infoPanelOpen && selectedDoc}
  <div class="fixed inset-0 z-40">
    <button
      onclick={() => infoPanelOpen = false}
      class="absolute inset-0 bg-black/40"
      aria-label="정보 패널 닫기"
    ></button>
    <div class="absolute right-0 top-0 bottom-0 z-50 w-[320px] shadow-xl">
      <PreviewPanel doc={selectedDoc} onclose={() => infoPanelOpen = false} />
    </div>
  </div>
{/if}
