<script lang="ts">
  // v0.2 Phase 5 primitive — single-select dropdown over Bits UI Select.
  // High-level API: `value` (bindable) + `options` ([{value, label}]).
  // For multiselect, a separate LumotiaMultiSelect primitive can land
  // later — keeping the v0.2 surface narrow.
  import { Select } from "bits-ui";
  import { Check, ChevronDown } from "lucide-svelte";

  type Option = { value: string; label: string; disabled?: boolean };

  interface Props {
    value: string;
    options: Option[];
    placeholder?: string;
    disabled?: boolean;
    label?: string;
    name?: string;            // hidden form input for native form submit
    onValueChange?: (value: string) => void;
    triggerClass?: string;
  }

  let {
    value = $bindable(""),
    options,
    placeholder = "Select…",
    disabled = false,
    label,
    name,
    onValueChange,
    triggerClass = "",
  }: Props = $props();

  const selectedLabel = $derived(
    options.find((o) => o.value === value)?.label ?? placeholder,
  );
</script>

<Select.Root type="single" bind:value {disabled} onValueChange={onValueChange} {name}>
  <Select.Trigger
    class="lumotia-select-trigger inline-flex items-center justify-between gap-2 rounded-md bg-bg-input border border-border-subtle px-3 py-2 text-[13px] text-text min-w-[160px] focus:outline-none focus:border-accent disabled:opacity-50 {triggerClass}"
    aria-label={label}
  >
    <span class="truncate">{selectedLabel}</span>
    <ChevronDown size={14} class="text-text-tertiary shrink-0" aria-hidden="true" />
  </Select.Trigger>
  <Select.Portal>
    <Select.Content
      class="z-50 rounded-md bg-bg-card border border-border-subtle shadow-xl py-1 min-w-[160px] max-h-[280px] overflow-auto"
      sideOffset={4}
    >
      {#each options as opt (opt.value)}
        <Select.Item
          value={opt.value}
          label={opt.label}
          disabled={opt.disabled}
          class="px-3 py-1.5 text-[13px] text-text data-[highlighted]:bg-hover data-[disabled]:opacity-50 cursor-pointer flex items-center gap-2"
        >
          {#snippet children({ selected })}
            <span class="size-4 flex items-center justify-center shrink-0">
              {#if selected}<Check size={14} class="text-accent" />{/if}
            </span>
            <span class="truncate">{opt.label}</span>
          {/snippet}
        </Select.Item>
      {/each}
    </Select.Content>
  </Select.Portal>
</Select.Root>
