<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue';
import { ChevronDown, Check } from 'lucide-vue-next';

interface Option {
  value: string;
  label?: string;
}

const props = defineProps<{
  modelValue: string;
  options: (string | Option)[];
  placeholder?: string;
  fullWidth?: boolean;
  triggerClass?: string;
}>();

const emit = defineEmits(['update:modelValue']);

const isOpen = ref(false);
const containerRef = ref<HTMLElement | null>(null);

const normalizedOptions = computed(() => {
  return props.options.map(opt => {
    if (typeof opt === 'string') {
      return { value: opt, label: opt };
    }
    return opt;
  });
});

const selectedLabel = computed(() => {
  const found = normalizedOptions.value.find(o => o.value === props.modelValue);
      return found ? (found.label || found.value) : (props.modelValue || props.placeholder || '');
  });
  
  const toggle = () => {  isOpen.value = !isOpen.value;
};

const select = (value: string) => {
  emit('update:modelValue', value);
  isOpen.value = false;
};

const handleClickOutside = (event: MouseEvent) => {
  if (containerRef.value && !containerRef.value.contains(event.target as Node)) {
    isOpen.value = false;
  }
};

onMounted(() => {
  document.addEventListener('click', handleClickOutside);
});

onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside);
});
</script>

<template>
  <div 
    ref="containerRef" 
    class="relative text-sm"
    :class="{ 'w-full': fullWidth }"
  >
    <!-- Trigger -->
    <button
      type="button"
      @click="toggle"
      class="flex items-center justify-between gap-2 px-3 py-2 transition-colors text-slate-200 focus:outline-none"
      :class="[
        triggerClass ? triggerClass : 'bg-slate-950 border border-slate-800 rounded-lg hover:border-slate-700 focus:ring-1 focus:ring-indigo-500/50',
        { 'w-full': fullWidth, 'border-indigo-500 ring-1 ring-indigo-500/50': isOpen && !triggerClass }
      ]"
    >
      <span class="truncate font-bold">{{ selectedLabel }}</span>
      <ChevronDown class="w-4 h-4 text-slate-500 transition-transform duration-200" :class="{ 'rotate-180': isOpen }" />
    </button>

    <!-- Dropdown Menu -->
    <transition
      enter-active-class="transition duration-100 ease-out"
      enter-from-class="transform scale-95 opacity-0"
      enter-to-class="transform scale-100 opacity-100"
      leave-active-class="transition duration-75 ease-in"
      leave-from-class="transform scale-100 opacity-100"
      leave-to-class="transform scale-95 opacity-0"
    >
      <div 
        v-if="isOpen"
        class="absolute top-full left-0 mt-1 w-full min-w-[120px] max-h-60 overflow-y-auto bg-slate-900 border border-slate-800 rounded-lg shadow-xl z-50 py-1"
      >
        <button
          v-for="opt in normalizedOptions"
          :key="opt.value"
          @click="select(opt.value)"
          class="w-full text-left px-3 py-2 text-sm flex items-center justify-between group hover:bg-slate-800 transition-colors"
          :class="modelValue === opt.value ? 'text-indigo-400 bg-indigo-500/10' : 'text-slate-300'"
        >
          <span class="truncate font-medium">{{ opt.label || opt.value }}</span>
          <Check v-if="modelValue === opt.value" class="w-3.5 h-3.5 text-indigo-500" />
        </button>
      </div>
    </transition>
  </div>
</template>
