<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { UiIcon } from '@/components/UiIcon';
import { useUiAutocompleteContext } from './context';
import type { UiAutocompleteItemProps } from './types';

defineOptions({
  name: 'UiAutocompleteItem',
});

const props = withDefaults(defineProps<UiAutocompleteItemProps>(), {
  disabled: false,
  textValue: undefined,
});

const emit = defineEmits<{
  /** Emitted when the item is selected. */
  select: [event: Event];
}>();

const ctx = useUiAutocompleteContext();
const labelEl = ref<HTMLElement | null>(null);

function readLabel() {
  return labelEl.value?.textContent?.trim() || props.textValue || props.value;
}

function syncLabel() {
  ctx.itemLabels.value.set(props.value, readLabel());
}

onMounted(syncLabel);

watch(
  () => props.value,
  (next, prev) => {
    if (prev !== undefined && prev !== next) {
      ctx.itemLabels.value.delete(prev);
    }
    ctx.itemLabels.value.set(next, readLabel());
  },
);

watch(() => props.textValue, syncLabel);

onBeforeUnmount(() => {
  ctx.itemLabels.value.delete(props.value);
});
</script>

<template>
  <div
    role="option"
    :aria-selected="ctx.isSelected(props.value)"
    :aria-disabled="props.disabled || undefined"
    :data-disabled="props.disabled ? '' : undefined"
    :data-autocomplete-value="props.value"
    :data-highlighted="
      ctx.highlightedValue.value === props.value ? '' : undefined
    "
    :data-state="ctx.isSelected(props.value) ? 'checked' : 'unchecked'"
    tabindex="-1"
    class="hover-layer hover-layer-default focus:text-foreground data-[highlighted]:bg-background-surface-muted-subtle data-[highlighted]:text-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-12 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
    @pointermove="ctx.highlightOption(props.value)"
    @click="
      if (!props.disabled) {
        ctx.selectOption(props.value);
        emit('select', $event);
      }
    "
    @keydown.enter.prevent="
      if (!props.disabled) {
        ctx.selectOption(props.value);
        emit('select', $event);
      }
    "
    @keydown.space.prevent="
      if (!props.disabled) {
        ctx.selectOption(props.value);
        emit('select', $event);
      }
    "
  >
    <span ref="labelEl" class="min-w-0 flex-1 truncate">
      <slot />
    </span>
    <span
      class="!absolute right-2 flex items-center justify-center"
      data-slot="autocomplete-item-end"
    >
      <span v-if="ctx.isSelected(props.value)">
        <slot name="indicator-icon">
          <UiIcon name="check" :size="16" />
        </slot>
      </span>
    </span>
  </div>
</template>
