<script lang="ts">
  import { tick } from 'svelte';

  interface Props {
    open: boolean;
    onClose: () => void;
  }

  let { open, onClose }: Props = $props();

  interface Command {
    id: string;
    label: string;
    description?: string;
    shortcut?: string;
    action: () => void;
  }

  const COMMANDS: Command[] = [
    { id: 'new-terminal', label: 'New Terminal Tab',      shortcut: 'Ctrl+`',    action: () => {} },
    { id: 'settings',     label: 'Open Settings',         shortcut: 'Ctrl+,',    action: () => {} },
    { id: 'search',       label: 'Search Messages',       shortcut: 'Ctrl+F',    action: () => {} },
    { id: 'new-project',  label: 'Add Project',           description: 'Open a project directory', action: () => {} },
    { id: 'clear-agent',  label: 'Clear Agent Context',   description: 'Reset agent session', action: () => {} },
    { id: 'copy-cost',    label: 'Copy Session Cost',     action: () => {} },
    { id: 'docs',         label: 'Open Documentation',    shortcut: 'F1',        action: () => {} },
    { id: 'theme',        label: 'Change Theme',          description: 'Currently: Catppuccin Mocha', action: () => {} },
    { id: 'split-h',      label: 'Split Horizontally',    shortcut: 'Ctrl+\\',   action: () => {} },
    { id: 'split-v',      label: 'Split Vertically',      shortcut: 'Ctrl+Shift+\\', action: () => {} },
  ];

  let query = $state('');
  let selectedIdx = $state(0);
  let inputEl = $state<HTMLInputElement | undefined>(undefined);

  let filtered = $derived(
    query.trim() === ''
      ? COMMANDS
      : COMMANDS.filter(c =>
          c.label.toLowerCase().includes(query.toLowerCase()) ||
          c.description?.toLowerCase().includes(query.toLowerCase())
        )
  );

  $effect(() => {
    if (open) {
      query = '';
      selectedIdx = 0;
      tick().then(() => inputEl?.focus());
    }
  });

  // Clamp selection when filtered list changes
  $effect(() => {
    const len = filtered.length;
    if (selectedIdx >= len) selectedIdx = Math.max(0, len - 1);
  });

  function handleKeydown(e: KeyboardEvent) {
    if (e.key === 'Escape') { onClose(); return; }
    if (e.key === 'ArrowDown') { e.preventDefault(); selectedIdx = Math.min(selectedIdx + 1, filtered.length - 1); return; }
    if (e.key === 'ArrowUp')   { e.preventDefault(); selectedIdx = Math.max(selectedIdx - 1, 0); return; }
    if (e.key === 'Enter' && filtered[selectedIdx]) {
      filtered[selectedIdx].action();
      onClose();
    }
  }

  function executeCommand(cmd: Command) {
    cmd.action();
    onClose();
  }

  function handleBackdropClick(e: MouseEvent) {
    if (e.target === e.currentTarget) onClose();
  }
</script>

{#if open}
  <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
  <div
    class="palette-backdrop"
    onclick={handleBackdropClick}
    onkeydown={handleKeydown}
    role="dialog"
    aria-modal="true"
    aria-label="Command Palette"
    tabindex="-1"
  >
    <div class="palette-panel">
      <div class="palette-input-row">
        <svg class="palette-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
          <circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
        </svg>
        <input
          class="palette-input"
          type="text"
          role="combobox"
          placeholder="Type a command..."
          bind:this={inputEl}
          bind:value={query}
          onkeydown={handleKeydown}
          aria-label="Command search"
          aria-autocomplete="list"
          aria-expanded="true"
          aria-controls="palette-list"
          aria-activedescendant={filtered[selectedIdx] ? `cmd-${filtered[selectedIdx].id}` : undefined}
          autocomplete="off"
          spellcheck="false"
        />
        <kbd class="palette-esc-hint">Esc</kbd>
      </div>

      <ul
        id="palette-list"
        class="palette-list"
        role="listbox"
        aria-label="Commands"
      >
        {#each filtered as cmd, i (cmd.id)}
          <!-- svelte-ignore a11y_click_events_have_key_events -->
          <li
            id="cmd-{cmd.id}"
            class="palette-item"
            class:selected={i === selectedIdx}
            role="option"
            aria-selected={i === selectedIdx}
            onclick={() => executeCommand(cmd)}
            onmouseenter={() => selectedIdx = i}
          >
            <span class="cmd-label">{cmd.label}</span>
            {#if cmd.description}
              <span class="cmd-desc">{cmd.description}</span>
            {/if}
            {#if cmd.shortcut}
              <kbd class="cmd-shortcut">{cmd.shortcut}</kbd>
            {/if}
          </li>
        {/each}
        {#if filtered.length === 0}
          <li class="palette-empty" role="option" aria-selected="false">No commands found</li>
        {/if}
      </ul>
    </div>
  </div>
{/if}

<style>
  .palette-backdrop {
    position: fixed;
    inset: 0;
    z-index: 300;
    background: color-mix(in srgb, var(--ctp-crust) 70%, transparent);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 6rem;
  }

  .palette-panel {
    width: 36rem;
    max-width: 92vw;
    background: var(--ctp-mantle);
    border: 1px solid var(--ctp-surface1);
    border-radius: 0.625rem;
    overflow: hidden;
    box-shadow: 0 1.25rem 3rem color-mix(in srgb, var(--ctp-crust) 60%, transparent);
    animation: palette-appear 0.12s ease-out;
  }

  @keyframes palette-appear {
    from { transform: translateY(-0.5rem) scale(0.98); opacity: 0; }
    to   { transform: translateY(0) scale(1); opacity: 1; }
  }

  /* Input row */
  .palette-input-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0 0.75rem;
    border-bottom: 1px solid var(--ctp-surface0);
    height: 3rem;
  }

  .palette-icon {
    width: 1rem;
    height: 1rem;
    color: var(--ctp-overlay1);
    flex-shrink: 0;
  }

  .palette-input {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: var(--ctp-text);
    font-family: var(--ui-font-family);
    font-size: 0.9375rem;
    caret-color: var(--ctp-mauve);
  }

  .palette-input::placeholder { color: var(--ctp-overlay0); }

  .palette-esc-hint {
    padding: 0.15rem 0.35rem;
    background: var(--ctp-surface0);
    border: 1px solid var(--ctp-surface1);
    border-radius: 0.25rem;
    font-size: 0.6875rem;
    color: var(--ctp-overlay1);
    font-family: var(--ui-font-family);
    white-space: nowrap;
  }

  /* Command list */
  .palette-list {
    list-style: none;
    margin: 0;
    padding: 0.375rem;
    max-height: 22rem;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 0.0625rem;
  }

  .palette-list::-webkit-scrollbar { width: 0.375rem; }
  .palette-list::-webkit-scrollbar-track { background: transparent; }
  .palette-list::-webkit-scrollbar-thumb { background: var(--ctp-surface1); border-radius: 0.25rem; }

  .palette-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.625rem;
    border-radius: 0.375rem;
    cursor: pointer;
    transition: background 0.08s;
  }

  .palette-item.selected {
    background: var(--ctp-surface0);
  }

  .palette-item:hover {
    background: var(--ctp-surface0);
  }

  .cmd-label {
    flex: 1;
    font-size: 0.875rem;
    color: var(--ctp-text);
  }

  .cmd-desc {
    font-size: 0.75rem;
    color: var(--ctp-subtext0);
    max-width: 12rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .cmd-shortcut {
    padding: 0.1rem 0.3rem;
    background: var(--ctp-surface1);
    border: 1px solid var(--ctp-surface2);
    border-radius: 0.2rem;
    font-size: 0.6875rem;
    color: var(--ctp-subtext0);
    font-family: var(--ui-font-family);
    white-space: nowrap;
    flex-shrink: 0;
  }

  .palette-empty {
    padding: 1.5rem;
    text-align: center;
    font-size: 0.875rem;
    color: var(--ctp-overlay0);
    font-style: italic;
  }
</style>
