<script lang="ts">
  import { goto } from '$app/navigation';
  import { loadCalculators, searchCalculators, type CalculatorDef } from '$lib/data/calculatorLoader';

  export let idPrefix = 'search';
  let query = '';
  let focused = false;
  let selectedIndex = -1;
  let lastQuery = '';
  let allCalcs: CalculatorDef[] = [];

  $: if (query.length >= 1 && allCalcs.length === 0) {
    loadCalculators().then(data => { allCalcs = data; });
  }

  $: results = (query.length >= 2 && allCalcs.length > 0) ? searchCalculators(allCalcs, query).slice(0, 8) : [];
  $: listboxId = `${idPrefix}-listbox`;
  $: inputId = `${idPrefix}-input`;
  $: isOpen = focused && results.length > 0;
  $: activeDescendant = selectedIndex >= 0 && isOpen ? `${idPrefix}-option-${selectedIndex}` : undefined;

  $: if (query !== lastQuery) {
    selectedIndex = -1;
    lastQuery = query;
  }

  $: if (selectedIndex >= results.length) {
    selectedIndex = results.length - 1;
  }

  function handleKeydown(e: KeyboardEvent) {
    if (e.key === 'ArrowDown') {
      e.preventDefault();
      selectedIndex = Math.min(selectedIndex + 1, results.length - 1);
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      selectedIndex = Math.max(selectedIndex - 1, -1);
    } else if (e.key === 'Enter' && selectedIndex >= 0 && results[selectedIndex]) {
      e.preventDefault();
      navigateTo(results[selectedIndex].slug);
    } else if (e.key === 'Escape') {
      query = '';
      focused = false;
      (e.target as HTMLInputElement)?.blur();
    }
  }

  function navigateTo(slug: string) {
    goto(`/${slug}`);
    query = '';
    focused = false;
    selectedIndex = -1;
  }
</script>

<div class="search-wrapper" class:active={isOpen}>
  <div class="search-input-wrap">
    <svg class="search-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
      <circle cx="11" cy="11" r="8" /><path d="m21 21-4.35-4.35" />
    </svg>
    <input
      id={inputId}
      type="text"
      bind:value={query}
      on:focus={() => (focused = true)}
      on:blur={() => setTimeout(() => (focused = false), 200)}
      on:keydown={handleKeydown}
      placeholder="Search conversions..."
      aria-label="Search conversions"
      role="combobox"
      aria-autocomplete="list"
      aria-haspopup="listbox"
      aria-expanded={isOpen ? 'true' : 'false'}
      aria-controls={listboxId}
      aria-activedescendant={activeDescendant}
    />
    {#if query}
      <button
        type="button"
        class="clear"
        on:click={() => {
          query = '';
          selectedIndex = -1;
        }}
        aria-label="Clear search"
      >
        ✕
      </button>
    {/if}
  </div>
  {#if isOpen}
    <ul class="results" id={listboxId} role="listbox" aria-label="Conversion suggestions">
      {#each results as result, i}
        <li>
          <button
            id={`${idPrefix}-option-${i}`}
            type="button"
            class="result-item"
            class:selected={i === selectedIndex}
            role="option"
            aria-selected={i === selectedIndex}
            on:mousedown|preventDefault={() => navigateTo(result.slug)}
          >
            <span class="result-name">{result.name}</span>
            <span class="result-cat">{result.category}</span>
          </button>
        </li>
      {/each}
    </ul>
  {/if}
</div>

<style>
  .search-wrapper {
    position: relative;
    width: 100%;
    max-width: 420px;
  }
  .search-input-wrap {
    display: flex;
    align-items: center;
    background: var(--input-bg);
    border: 2px solid var(--border);
    border-radius: 12px;
    padding: 0 0.75rem;
    transition: border-color 0.2s, box-shadow 0.2s;
  }
  .search-wrapper.active .search-input-wrap,
  .search-input-wrap:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-glow);
  }
  .search-icon {
    color: var(--text-muted);
    flex-shrink: 0;
  }
  input {
    flex: 1;
    border: none;
    background: none;
    padding: 0.65rem 0.5rem;
    font-size: 0.95rem;
    color: var(--text);
    outline: none;
    font-family: inherit;
  }
  input::placeholder {
    color: var(--text-muted);
    opacity: 0.6;
  }
  .clear {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 0.9rem;
    padding: 0.25rem;
  }

  .results {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.2);
    list-style: none;
    margin: 0;
    padding: 0.5rem 0;
    z-index: 200;
    overflow: hidden;
  }
  .result-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 0.6rem 1rem;
    border: none;
    background: none;
    cursor: pointer;
    font-size: 0.88rem;
    color: var(--text);
    text-align: left;
    transition: background 0.1s;
  }
  .result-item:hover,
  .result-item.selected {
    background: var(--hover-bg);
  }
  .result-item:focus-visible {
    outline: none;
    background: var(--hover-bg);
  }
  .result-name {
    font-weight: 500;
  }
  .result-cat {
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
  }
</style>
