<script lang="ts">
  import { Search, X } from 'lucide-svelte';

  // Debounced text input for client-side list filtering. Two-way bound
  // `value` is updated 120ms after the last keystroke so consumers can
  // drive a $derived filtered list without triggering on every char.
  //
  // The input is intentionally type="search" so the global `/` shortcut
  // focuses the page's top-bar input (first match in DOM order), not
  // this one — different semantics: site-search vs in-tab filter.

  let {
    value = $bindable(''),
    placeholder = 'Filter…'
  }: {
    value?: string;
    placeholder?: string;
  } = $props();

  let raw = $state(value);
  let timer: ReturnType<typeof setTimeout> | null = null;

  function flush(next: string) {
    if (timer) { clearTimeout(timer); timer = null; }
    timer = setTimeout(() => { value = next; timer = null; }, 120);
  }

  function onInput(e: Event) {
    raw = (e.currentTarget as HTMLInputElement).value;
    flush(raw);
  }

  function onClear() {
    raw = '';
    if (timer) { clearTimeout(timer); timer = null; }
    value = '';
  }

  function onKey(e: KeyboardEvent) {
    if (e.key === 'Escape' && raw !== '') {
      e.preventDefault();
      onClear();
    }
  }
</script>

<label class="relative block w-full max-w-xs">
  <Search
    size={14}
    strokeWidth={1.5}
    class="pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 text-text-secondary"
  />
  <input
    type="search"
    {placeholder}
    aria-label={placeholder}
    value={raw}
    oninput={onInput}
    onkeydown={onKey}
    class="w-full rounded border border-border bg-surface pl-7 pr-7 py-1 text-sm
           focus-visible:outline focus-visible:outline-2 focus-visible:outline-accent"
  />
  {#if raw}
    <button
      type="button"
      onclick={onClear}
      aria-label="Clear filter"
      title="Clear"
      class="absolute right-1 top-1/2 -translate-y-1/2 rounded p-1 text-text-secondary
             hover:text-text-primary"
    >
      <X size={12} strokeWidth={1.5} />
    </button>
  {/if}
</label>
