<script lang="ts">
  import { onMount } from "svelte";
  import { snippetsStore, type Snippet } from "$lib/stores/snippets";

  interface Props {
    onClose: () => void;
    onInsert: (content: string) => void;
  }

  const { onClose, onInsert }: Props = $props();

  let editingSnippet = $state<Snippet | null>(null);
  let isCreating = $state(false);
  let showDeleteConfirm = $state<string | null>(null);

  let editName = $state("");
  let editContent = $state("");
  let editCategory = $state("");
  let newCategoryInput = $state("");
  let showNewCategoryInput = $state(false);

  const snippets = $derived(snippetsStore.filteredSnippets);
  const categories = $derived(snippetsStore.categories);
  const selectedCategory = $derived(snippetsStore.selectedCategory);
  const isLoading = $derived(snippetsStore.isLoading);

  onMount(() => {
    snippetsStore.loadSnippets();
  });

  function handleSelectCategory(category: string | null): void {
    snippetsStore.setSelectedCategory(category);
  }

  function handleInsert(snippet: Snippet): void {
    onInsert(snippet.content);
    onClose();
  }

  function handleStartCreate(): void {
    isCreating = true;
    editingSnippet = null;
    editName = "";
    editContent = "";
    editCategory = $categories.length > 0 ? $categories[0] : "Custom";
    showNewCategoryInput = false;
    newCategoryInput = "";
  }

  function handleStartEdit(snippet: Snippet): void {
    editingSnippet = snippet;
    isCreating = false;
    editName = snippet.name;
    editContent = snippet.content;
    editCategory = snippet.category;
    showNewCategoryInput = false;
    newCategoryInput = "";
  }

  function handleCancelEdit(): void {
    editingSnippet = null;
    isCreating = false;
    showNewCategoryInput = false;
    newCategoryInput = "";
  }

  async function handleSave(): Promise<void> {
    const finalCategory =
      showNewCategoryInput && newCategoryInput.trim() ? newCategoryInput.trim() : editCategory;

    if (!editName.trim() || !editContent.trim() || !finalCategory) {
      return;
    }

    if (isCreating) {
      await snippetsStore.createSnippet(editName.trim(), editContent.trim(), finalCategory);
    } else if (editingSnippet) {
      await snippetsStore.updateSnippet(
        editingSnippet.id,
        editName.trim(),
        editContent.trim(),
        finalCategory
      );
    }

    handleCancelEdit();
  }

  async function handleDelete(snippetId: string): Promise<void> {
    await snippetsStore.deleteSnippet(snippetId);
    showDeleteConfirm = null;
  }

  function toggleNewCategory(): void {
    showNewCategoryInput = !showNewCategoryInput;
    if (showNewCategoryInput) {
      newCategoryInput = "";
    }
  }
</script>

<div
  class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4"
  onclick={onClose}
  role="button"
  tabindex="0"
  onkeydown={(e) => e.key === "Escape" && onClose()}
>
  <div
    class="bg-[var(--bg-primary)] border border-[var(--border-color)] rounded-lg shadow-xl max-w-4xl w-full max-h-[80vh] overflow-hidden flex flex-col"
    onclick={(e) => e.stopPropagation()}
    onkeydown={(e) => e.stopPropagation()}
    role="dialog"
    aria-labelledby="snippet-library-title"
    tabindex="-1"
  >
    <div class="flex items-center justify-between p-6 pb-4 border-b border-[var(--border-color)]">
      <div class="flex items-center gap-3">
        {#if editingSnippet || isCreating}
          <button
            onclick={handleCancelEdit}
            class="p-1 text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors"
            aria-label="Back to list"
          >
            <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M15 19l-7-7 7-7"
              />
            </svg>
          </button>
        {/if}
        <h2 id="snippet-library-title" class="text-xl font-semibold text-[var(--text-primary)]">
          {#if isCreating}
            Create Snippet
          {:else if editingSnippet}
            Edit Snippet
          {:else}
            Snippet Library
          {/if}
        </h2>
      </div>
      <div class="flex items-center gap-2">
        {#if !editingSnippet && !isCreating}
          <button
            onclick={handleStartCreate}
            class="btn-trans-gradient px-3 py-1.5 text-sm font-medium rounded flex items-center gap-2"
          >
            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M12 4v16m8-8H4"
              />
            </svg>
            New Snippet
          </button>
        {/if}
        <button
          onclick={onClose}
          class="p-1 text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors"
          aria-label="Close"
        >
          <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path
              stroke-linecap="round"
              stroke-linejoin="round"
              stroke-width="2"
              d="M6 18L18 6M6 6l12 12"
            />
          </svg>
        </button>
      </div>
    </div>

    {#if editingSnippet || isCreating}
      <div class="p-6 flex-1 overflow-y-auto">
        <div class="space-y-4">
          <div>
            <label
              for="snippet-name"
              class="block text-sm font-medium text-[var(--text-secondary)] mb-1"
            >
              Name
            </label>
            <input
              id="snippet-name"
              type="text"
              bind:value={editName}
              placeholder="Enter snippet name..."
              class="w-full px-4 py-2 bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-lg text-[var(--text-primary)] placeholder-[var(--text-tertiary)] focus:outline-none focus:border-[var(--accent-primary)]"
            />
          </div>

          <div>
            <label
              for="snippet-category"
              class="block text-sm font-medium text-[var(--text-secondary)] mb-1"
            >
              Category
            </label>
            <div class="flex items-center gap-2">
              {#if showNewCategoryInput}
                <input
                  type="text"
                  bind:value={newCategoryInput}
                  placeholder="Enter new category..."
                  class="flex-1 px-4 py-2 bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-lg text-[var(--text-primary)] placeholder-[var(--text-tertiary)] focus:outline-none focus:border-[var(--accent-primary)]"
                />
              {:else}
                <select
                  id="snippet-category"
                  bind:value={editCategory}
                  class="flex-1 px-4 py-2 bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-lg text-[var(--text-primary)] focus:outline-none focus:border-[var(--accent-primary)]"
                >
                  {#each $categories as category (category)}
                    <option value={category}>{category}</option>
                  {/each}
                  <option value="Custom">Custom</option>
                </select>
              {/if}
              <button
                onclick={toggleNewCategory}
                class="px-3 py-2 text-sm font-medium bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-lg text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors"
              >
                {showNewCategoryInput ? "Use Existing" : "New Category"}
              </button>
            </div>
          </div>

          <div>
            <label
              for="snippet-content"
              class="block text-sm font-medium text-[var(--text-secondary)] mb-1"
            >
              Content
            </label>
            <textarea
              id="snippet-content"
              bind:value={editContent}
              placeholder="Enter your prompt snippet..."
              rows="8"
              class="w-full px-4 py-3 bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-lg text-[var(--text-primary)] placeholder-[var(--text-tertiary)] focus:outline-none focus:border-[var(--accent-primary)] resize-none font-mono text-sm"
            ></textarea>
          </div>

          <div class="flex justify-end gap-2 pt-4">
            <button
              onclick={handleCancelEdit}
              class="px-4 py-2 text-sm font-medium bg-[var(--bg-secondary)] text-[var(--text-secondary)] rounded-lg hover:bg-[var(--bg-tertiary)] transition-colors"
            >
              Cancel
            </button>
            <button
              onclick={handleSave}
              disabled={!editName.trim() || !editContent.trim()}
              class="btn-trans-gradient px-4 py-2 text-sm font-medium rounded-lg"
            >
              {isCreating ? "Create" : "Save"}
            </button>
          </div>
        </div>
      </div>
    {:else}
      <div class="flex flex-1 overflow-hidden">
        <div class="w-48 border-r border-[var(--border-color)] p-4 overflow-y-auto">
          <h3
            class="text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider mb-3"
          >
            Categories
          </h3>
          <div class="space-y-1">
            <button
              onclick={() => handleSelectCategory(null)}
              class="w-full text-left px-3 py-2 rounded-lg text-sm transition-colors {$selectedCategory ===
              null
                ? 'bg-[var(--accent-primary)]/10 text-[var(--accent-primary)]'
                : 'text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)]'}"
            >
              All Snippets
            </button>
            {#each $categories as category (category)}
              <button
                onclick={() => handleSelectCategory(category)}
                class="w-full text-left px-3 py-2 rounded-lg text-sm transition-colors {$selectedCategory ===
                category
                  ? 'bg-[var(--accent-primary)]/10 text-[var(--accent-primary)]'
                  : 'text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)]'}"
              >
                {category}
              </button>
            {/each}
          </div>
        </div>

        <div class="flex-1 overflow-y-auto">
          {#if $isLoading}
            <div class="flex items-center justify-center p-8">
              <div class="text-[var(--text-tertiary)]">Loading snippets...</div>
            </div>
          {:else if $snippets.length === 0}
            <div class="flex flex-col items-center justify-center p-8 text-center">
              <svg
                class="w-16 h-16 text-[var(--text-tertiary)] mb-4"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path
                  stroke-linecap="round"
                  stroke-linejoin="round"
                  stroke-width="1.5"
                  d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
                />
              </svg>
              <p class="text-[var(--text-secondary)]">No snippets in this category</p>
              <button
                onclick={handleStartCreate}
                class="btn-trans-gradient mt-4 px-4 py-2 text-sm font-medium rounded-lg"
              >
                Create your first snippet
              </button>
            </div>
          {:else}
            <div class="divide-y divide-[var(--border-color)]">
              {#each $snippets as snippet (snippet.id)}
                <div class="p-4 hover:bg-[var(--bg-secondary)] transition-colors group">
                  <div class="flex items-start justify-between gap-4">
                    <div class="flex-1 min-w-0">
                      <div class="flex items-center gap-2 mb-1">
                        <h3 class="font-medium text-[var(--text-primary)]">{snippet.name}</h3>
                        {#if snippet.is_default}
                          <span
                            class="px-2 py-0.5 text-xs font-medium bg-[var(--accent-primary)]/10 text-[var(--accent-primary)] rounded"
                          >
                            Default
                          </span>
                        {/if}
                        <span class="text-xs text-[var(--text-tertiary)]">{snippet.category}</span>
                      </div>
                      <p class="text-sm text-[var(--text-secondary)] line-clamp-2 font-mono">
                        {snippet.content}
                      </p>
                    </div>
                    <div
                      class="flex items-center gap-2 opacity-0 group-hover:opacity-100 transition-opacity"
                    >
                      <button
                        onclick={() => handleInsert(snippet)}
                        class="btn-trans-gradient px-3 py-1.5 text-xs font-medium rounded"
                        title="Insert this snippet"
                      >
                        Insert
                      </button>
                      <button
                        onclick={() => handleStartEdit(snippet)}
                        class="p-1.5 text-[var(--text-tertiary)] hover:text-[var(--text-primary)] transition-colors"
                        title="Edit snippet"
                      >
                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path
                            stroke-linecap="round"
                            stroke-linejoin="round"
                            stroke-width="2"
                            d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
                          />
                        </svg>
                      </button>
                      {#if !snippet.is_default}
                        {#if showDeleteConfirm === snippet.id}
                          <div class="flex items-center gap-1">
                            <button
                              onclick={() => handleDelete(snippet.id)}
                              class="px-2 py-1 text-xs font-medium bg-red-500 text-white rounded hover:bg-red-600 transition-colors"
                            >
                              Confirm
                            </button>
                            <button
                              onclick={() => (showDeleteConfirm = null)}
                              class="px-2 py-1 text-xs font-medium bg-[var(--bg-tertiary)] text-[var(--text-secondary)] rounded hover:bg-[var(--bg-secondary)] transition-colors"
                            >
                              Cancel
                            </button>
                          </div>
                        {:else}
                          <button
                            onclick={() => (showDeleteConfirm = snippet.id)}
                            class="p-1.5 text-[var(--text-tertiary)] hover:text-red-400 transition-colors"
                            title="Delete snippet"
                          >
                            <svg
                              class="w-4 h-4"
                              fill="none"
                              stroke="currentColor"
                              viewBox="0 0 24 24"
                            >
                              <path
                                stroke-linecap="round"
                                stroke-linejoin="round"
                                stroke-width="2"
                                d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
                              />
                            </svg>
                          </button>
                        {/if}
                      {/if}
                    </div>
                  </div>
                </div>
              {/each}
            </div>
          {/if}
        </div>
      </div>
    {/if}
  </div>
</div>

<style>
  [role="dialog"] {
    animation: slideIn 0.2s ease-out;
  }

  @keyframes slideIn {
    from {
      opacity: 0;
      transform: scale(0.95) translateY(10px);
    }
    to {
      opacity: 1;
      transform: scale(1) translateY(0);
    }
  }

  .overflow-y-auto {
    scrollbar-width: thin;
    scrollbar-color: var(--border-color) transparent;
  }

  .overflow-y-auto::-webkit-scrollbar {
    width: 8px;
  }

  .overflow-y-auto::-webkit-scrollbar-track {
    background: transparent;
  }

  .overflow-y-auto::-webkit-scrollbar-thumb {
    background-color: var(--border-color);
    border-radius: 4px;
  }

  .overflow-y-auto::-webkit-scrollbar-thumb:hover {
    background-color: var(--accent-primary);
  }

  .line-clamp-2 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
</style>
