<script>
  import { getGroups, addGroup, updateGroup, deleteGroup, moveEntryToGroup, ensureTrashGroup } from '../lib/storage/db.js'
  import { createGroup, validateGroup, isTrashGroup, TRASH_GROUP_NAME, TRASH_GROUP_COLOR, GROUP_COLORS } from '../lib/models/schema.js'
  import { search as searchStore } from '../lib/stores/search.svelte.js'
  import { autofocus } from '../lib/autofocus.js'

  let groups = $state([])

  // Group management state
  let showGroupForm = $state(false)
  let editingGroupId = $state(null)
  let groupName = $state('')
  let groupColor = $state('#6c63ff')
  let groupError = $state('')
  let showDeleteGroupConfirm = $state(null) // groupId being confirmed for deletion
  let deletingGroup = $derived(groups.find(g => g.id === showDeleteGroupConfirm))

  // Drag-and-drop state
  let dragOverGroupId = $state(null)
  let droppedGroupId = $state(null)

  async function handleDrop(groupId, entryId) {
    try {
      await moveEntryToGroup(entryId, groupId)
      droppedGroupId = groupId
      setTimeout(() => { droppedGroupId = null }, 600)
      await loadData()
      searchStore.refresh()
    } catch (e) {
      // silent fail
    }
  }

  function canDrop(groupId) {
    return groupId !== searchStore.activeGroupId && !isTrashGroup(groupId)
  }

  async function loadData() {
    await ensureTrashGroup()
    groups = await getGroups()
  }

  // Initial load + refresh after import/export
  $effect(() => {
    searchStore.refreshTrigger
    loadData()
  })

  function openGroupForm(group = null) {
    if (group) {
      editingGroupId = group.id
      groupName = group.name
      groupColor = group.color || '#6c63ff'
    } else {
      editingGroupId = null
      groupName = ''
      groupColor = GROUP_COLORS[Math.floor(Math.random() * GROUP_COLORS.length)]
    }
    groupError = ''
    showGroupForm = true
  }

  async function saveGroup() {
    groupError = ''
    const validation = validateGroup(groupName)
    if (!validation.valid) {
      groupError = validation.errors[0]
      return
    }

    try {
      if (editingGroupId) {
        const existing = groups.find(g => g.id === editingGroupId)
        const updated = { ...existing, name: groupName.trim(), color: groupColor }
        await updateGroup(updated)
      } else {
        const group = createGroup(groupName, groupColor)
        await addGroup(group)
      }
      showGroupForm = false
      await loadData()
    } catch (e) {
      groupError = 'Failed to save group: ' + e.message
    }
  }

  async function confirmDeleteGroup(groupId) {
    try {
      await deleteGroup(groupId)
      if (searchStore.activeGroupId === groupId) {
        searchStore.activeGroupId = 'all'
      }
      showDeleteGroupConfirm = null
      await loadData()
    } catch (e) {
      groupError = 'Failed to delete group: ' + e.message
    }
  }
</script>

<div class="sidebar-content">
  <div class="sidebar-header">
    <h2>🔐 Vault</h2>
  </div>

  <div class="search-box">
    <input
      type="text"
      placeholder="Search entries..."
      value={searchStore.query}
      oninput={(e) => searchStore.setSearchQuery(e.target.value)}
    />
  </div>

  <nav class="groups-nav">
    <button
      class="group-item {searchStore.activeGroupId === 'all' ? 'active' : ''}"
      onclick={() => searchStore.activeGroupId = 'all'}
    >
      <span class="group-icon">📋</span>
      <span class="group-name">All Entries</span>
    </button>

    {#each groups as group}
      {#if !isTrashGroup(group.id)}
        <div class="group-row">
          <button
            class="group-item {searchStore.activeGroupId === group.id ? 'active' : ''} {dragOverGroupId === group.id ? 'drag-over' : ''} {droppedGroupId === group.id ? 'dropped' : ''}"
            onclick={() => searchStore.activeGroupId = group.id}
            ondragover={(e) => { if (canDrop(group.id)) { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; dragOverGroupId = group.id; } }}
            ondragleave={() => { if (dragOverGroupId === group.id) dragOverGroupId = null; }}
            ondrop={(e) => { e.preventDefault(); dragOverGroupId = null; if (canDrop(group.id)) { const entryId = e.dataTransfer.getData('text/plain'); if (entryId) handleDrop(group.id, entryId); } }}
          >
            <span class="group-color" style="background-color: {group.color || '#6c63ff'}"></span>
            <span class="group-name">{group.name}</span>
            <span class="drop-icon">📥</span>
          </button>
          <div class="group-actions">
            <button class="group-action-btn" onclick={() => openGroupForm(group)} title="Edit group">✏️</button>
            <button class="group-action-btn" onclick={() => showDeleteGroupConfirm = group.id} title="Delete group">🗑</button>
          </div>
        </div>
      {/if}
    {/each}
  </nav>

  <!-- Trash pinned to bottom -->
  <div class="trash-section">
    <button
      class="group-item {searchStore.activeGroupId === 'trash' ? 'active' : ''}"
      onclick={() => searchStore.activeGroupId = 'trash'}
    >
      <span class="group-color" style="background-color: {TRASH_GROUP_COLOR}"></span>
      <span class="group-name">{TRASH_GROUP_NAME}</span>
    </button>
  </div>

  <div class="sidebar-footer">
    <button class="btn btn-ghost btn-sm w-full" onclick={() => openGroupForm(null)}>+ New Group</button>
  </div>

  <!-- Group form modal -->
  {#if showGroupForm}
    <div class="modal-overlay" role="presentation" onclick={() => showGroupForm = false}>
      <!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
      <div class="modal" role="dialog" aria-modal="true" aria-label="Group settings" tabindex="-1" onclick={(e) => e.stopPropagation()}>
        <h3>{editingGroupId ? 'Edit Group' : 'New Group'}</h3>

        {#if groupError}
          <div class="error-banner">{groupError}</div>
        {/if}

        <div class="form-group">
          <label for="group-name">Group Name</label>
          <input id="group-name" type="text" bind:value={groupName} placeholder="e.g. Work, Personal" use:autofocus={!editingGroupId} />
        </div>

        <div class="form-group">
          <span class="field-label">Color</span>
          <div class="color-picker">
            {#each GROUP_COLORS as color}
              <button
                class="color-swatch {groupColor === color ? 'selected' : ''}"
                style="background-color: {color}"
                onclick={() => groupColor = color}
                title={color}
              ></button>
            {/each}
          </div>
        </div>

        <div class="modal-actions">
          <button class="btn btn-primary" onclick={saveGroup}>
            {editingGroupId ? 'Update' : 'Create'}
          </button>
          <button class="btn btn-ghost" onclick={() => showGroupForm = false}>Cancel</button>
        </div>
      </div>
    </div>
  {/if}

  <!-- Delete group confirmation -->
  {#if deletingGroup}
    <div class="modal-overlay" role="presentation" onclick={() => showDeleteGroupConfirm = null}>
      <!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
      <div class="modal" role="dialog" aria-modal="true" aria-label="Delete group confirmation" tabindex="-1" onclick={(e) => e.stopPropagation()}>
        <h3>Delete Group</h3>
        <p>Delete "<strong>{deletingGroup.name}</strong>"? Entries in this group will become ungrouped.</p>
        <div class="modal-actions">
          <button class="btn btn-danger" onclick={() => confirmDeleteGroup(deletingGroup.id)}>Yes, delete</button>
          <button class="btn btn-ghost" onclick={() => showDeleteGroupConfirm = null}>Cancel</button>
        </div>
      </div>
    </div>
  {/if}
</div>

<style>
  .sidebar-content {
    display: flex;
    flex-direction: column;
    height: 100%;
  }

  .sidebar-header {
    padding: 16px;
    border-bottom: 1px solid var(--color-border);
  }

  .sidebar-header h2 {
    font-size: 1rem;
    font-weight: 600;
  }

  .search-box {
    padding: 12px 16px;
  }

  .search-box input {
    padding: 8px 10px;
    font-size: 0.85rem;
  }

  .groups-nav {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
  }

  .group-row {
    display: flex;
    align-items: center;
  }

  .group-item {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
    padding: 8px 12px;
    border: none;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--color-text-muted);
    font-size: 0.875rem;
    cursor: pointer;
    transition: background-color 150ms, color 150ms;
    text-align: left;
  }

  .group-item:hover {
    background: var(--color-surface-hover);
    color: var(--color-text);
  }

  .group-item.active {
    background: rgba(108, 99, 255, 0.15);
    color: var(--color-primary);
  }

  .group-item.drag-over {
    background: rgba(108, 99, 255, 0.2);
    border: 2px dashed var(--color-primary);
    outline: 2px solid rgba(108, 99, 255, 0.25);
    outline-offset: -4px;
    transform: scale(1.02);
  }

  .group-item.drag-over .drop-icon {
    opacity: 1;
    transform: scale(1.2);
  }

  .group-item.dropped {
    animation: dropFlash 600ms ease;
  }

  @keyframes dropFlash {
    0% { background: rgba(52, 211, 153, 0.35); }
    100% { background: transparent; }
  }

  .drop-icon {
    opacity: 0;
    font-size: 0.85rem;
    transition: opacity 150ms, transform 150ms;
    flex-shrink: 0;
  }

  .group-icon {
    font-size: 1rem;
  }

  .group-color {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
  }

  .group-name {
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .group-actions {
    display: flex;
    gap: 2px;
    padding-right: 4px;
    opacity: 0;
    transition: opacity 150ms;
  }

  .group-row:hover .group-actions {
    opacity: 1;
  }

  .trash-section {
    padding: 8px;
    border-top: 1px solid var(--color-border);
  }

  .group-action-btn {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.75rem;
    padding: 4px;
    border-radius: var(--radius-sm);
    transition: background-color 150ms;
  }

  .group-action-btn:hover {
    background: var(--color-surface-hover);
  }

  .sidebar-footer {
    padding: 12px 16px;
    border-top: 1px solid var(--color-border);
  }

  /* Modal */
  .modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 200;
    padding: 1rem;
  }

  .modal {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 24px;
    max-width: 380px;
    width: 100%;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
  }

  .modal h3 {
    margin-bottom: 16px;
  }

  .modal p {
    color: var(--color-text-muted);
    font-size: 0.9rem;
    margin-bottom: 20px;
  }

  .modal-actions {
    display: flex;
    gap: 8px;
  }

  .error-banner {
    padding: 8px 12px;
    background: rgba(229, 72, 77, 0.15);
    border: 1px solid rgba(229, 72, 77, 0.4);
    border-radius: var(--radius-md);
    color: var(--color-danger);
    font-size: 0.85rem;
    margin-bottom: 12px;
  }

  /* Color picker */
  .color-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }

  .color-swatch {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 2px solid transparent;
    cursor: pointer;
    transition: transform 150ms, border-color 150ms;
  }

  .color-swatch:hover {
    transform: scale(1.15);
  }

  .color-swatch.selected {
    border-color: #fff;
    transform: scale(1.15);
  }
</style>
