<script setup lang="ts">
import { CheckIcon } from '@lucide/vue'
import type { HTMLAttributes } from 'vue'
import { computed, inject, onMounted, ref } from 'vue'
import { cn } from '@/lib/utils'
import { SelectContextKey } from './context'
import SelectItemText from './SelectItemText.vue'

const props = defineProps<{
  value: string
  disabled?: boolean
  class?: HTMLAttributes['class']
}>()

const context = inject(SelectContextKey)!
const itemRef = ref<HTMLElement | null>(null)

const isSelected = computed(() => context.modelValue.value === props.value)

function select() {
  if (props.disabled) return
  context.modelValue.value = props.value
  context.open.value = false
}

function onPointerMove() {
  if (props.disabled) return
  itemRef.value?.focus()
}

onMounted(() => {
  context.registerLabel(props.value, itemRef.value?.textContent?.trim() ?? '')
})
</script>

<template>
  <div
    ref="itemRef"
    data-slot="select-item"
    role="option"
    :data-value="value"
    :aria-selected="isSelected"
    :data-disabled="disabled ? '' : undefined"
    tabindex="-1"
    :class="
      cn(
        'focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*=size-])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 transition-colors',
        props.class,
      )
    "
    @click="select"
    @pointermove="onPointerMove"
  >
    <span class="pointer-events-none absolute right-2 flex size-4 items-center justify-center">
      <slot v-if="isSelected" name="indicator-icon">
        <CheckIcon class="pointer-events-none" />
      </slot>
    </span>

    <SelectItemText>
      <slot />
    </SelectItemText>
  </div>
</template>
