<svelte:options customElement="ui-drop-down" />

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

  export let value = '';
  export let name = '';
  export let placeholder = 'Select...';
  export let disabled = false;

  let rootEl: HTMLElement;
  let host: HTMLElement;
  let hiddenInput: HTMLInputElement;
  let open = false;

  type OptionItem = { value: string; label: string };
  let options: OptionItem[] = [];

  function loadOptions() {
    options = Array.from(host.querySelectorAll('option')).map((opt) => ({
      value: opt.value,
      label: opt.textContent?.trim() || opt.value
    }));

    if (!value) {
      const selected = host.querySelector('option[selected]') as HTMLOptionElement | null;
      if (selected) value = selected.value;
    }
  }

  function selectedLabel() {
    if (!value) return placeholder;
    return options.find((o) => o.value === value)?.label || placeholder;
  }

  function selectOption(nextValue: string) {
    value = nextValue;
    open = false;
    syncHiddenInput();

    host.dispatchEvent(new Event('change', { bubbles: true }));
    host.dispatchEvent(
      new CustomEvent('ui:change', {
        detail: { value },
        bubbles: true,
        composed: true
      })
    );
  }

  function syncHiddenInput() {
    if (!hiddenInput) return;
    hiddenInput.name = name;
    hiddenInput.value = value;
    hiddenInput.disabled = disabled || !name;
  }

  onMount(() => {
    host = (rootEl.getRootNode() as ShadowRoot).host as HTMLElement;
    if (!host) return;

    hiddenInput = host.querySelector('input[data-ui-dropdown-hidden="true"]') as HTMLInputElement;
    if (!hiddenInput) {
      hiddenInput = document.createElement('input');
      hiddenInput.type = 'hidden';
      hiddenInput.setAttribute('data-ui-dropdown-hidden', 'true');
      host.appendChild(hiddenInput);
    }

    loadOptions();
    syncHiddenInput();

    const observer = new MutationObserver(() => {
      loadOptions();
      syncHiddenInput();
    });
    observer.observe(host, { childList: true, subtree: true, attributes: true });

    return () => observer.disconnect();
  });
</script>

<div class="dropdown" bind:this={rootEl}>
  <button type="button" class="trigger" disabled={disabled} on:click={() => (open = !open)}>
    <span>{selectedLabel()}</span>
    <span aria-hidden="true">▾</span>
  </button>

  {#if open}
    <div class="menu" role="listbox">
      {#if options.length === 0}
        <div class="empty">No options</div>
      {:else}
        {#each options as opt}
          <button type="button" class="item" on:click={() => selectOption(opt.value)}>
            {opt.label}
          </button>
        {/each}
      {/if}
    </div>
  {/if}
</div>

<style>
  .dropdown {
    position: relative;
    display: inline-block;
    min-width: 180px;
  }

  .trigger {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 12px;
    border: 1px solid var(--ui-border);
    border-radius: 8px;
    background: var(--ui-bg);
    cursor: pointer;
  }

  .menu {
    position: absolute;
    z-index: 30;
    left: 0;
    right: 0;
    margin-top: 6px;
    border: 1px solid var(--ui-border);
    background: var(--ui-bg);
    border-radius: 8px;
    box-shadow: var(--ui-shadow);
    overflow: hidden;
  }

  .item {
    width: 100%;
    text-align: left;
    border: 0;
    background: transparent;
    padding: 10px 12px;
    cursor: pointer;
  }

  .item:hover {
    background: #f3f4f6;
  }

  .empty {
    padding: 10px 12px;
    color: var(--ui-muted);
  }
</style>
