<template>
  <div class="animated-select" ref="selectRef">
    <button
      @click="toggleSelect"
      class="animated-select__trigger"
      :class="{ 'animated-select__trigger--open': isOpen }"
    >
      <div class="animated-select__display">
        <Transition name="slide-fade" mode="out-in">
          <span 
            v-if="!selectedOption" 
            key="placeholder"
            class="animated-select__placeholder"
          >
            {{ placeholder }}
          </span>
          <div 
            v-else 
            key="selected"
            class="animated-select__selected"
          >
            <Icon 
              v-if="selectedOption.icon" 
              :name="selectedOption.icon" 
              class="animated-select__icon"
            />
            <span>{{ selectedOption.label }}</span>
          </div>
        </Transition>
      </div>
      
      <div class="animated-select__arrow">
        <svg
          class="animated-select__arrow-icon"
          :class="{ 'animated-select__arrow-icon--rotate': isOpen }"
          width="20"
          height="20"
          viewBox="0 0 20 20"
          fill="currentColor"
        >
          <path
            fill-rule="evenodd"
            d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
            clip-rule="evenodd"
          />
        </svg>
      </div>
    </button>

    <Teleport to="body">
      <Transition name="select-dropdown">
        <div
          v-if="isOpen"
          class="animated-select__dropdown"
          :style="dropdownStyle"
          @click.stop
        >
          <div class="animated-select__options">
            <TransitionGroup name="option-list">
              <div
                v-for="(option, index) in options"
                :key="option.value"
                class="animated-select__option"
                :class="{
                  'animated-select__option--selected': modelValue === option.value,
                  'animated-select__option--highlighted': highlightedIndex === index,
                  'animated-select__option--disabled': option.disabled
                }"
                :style="{ '--delay': `${index * 30}ms` }"
                @click="!option.disabled && selectOption(option)"
                @mouseenter="highlightedIndex = index"
                @mouseleave="highlightedIndex = -1"
              >
                <div class="animated-select__option-content">
                  <Icon 
                    v-if="option.icon" 
                    :name="option.icon" 
                    class="animated-select__option-icon"
                  />
                  <span class="animated-select__option-label">
                    {{ option.label }}
                  </span>
                  <span 
                    v-if="option.description" 
                    class="animated-select__option-description"
                  >
                    {{ option.description }}
                  </span>
                </div>
                
                <Transition name="check">
                  <Icon 
                    v-if="modelValue === option.value" 
                    name="check" 
                    class="animated-select__option-check"
                  />
                </Transition>
              </div>
            </TransitionGroup>
          </div>
        </div>
      </Transition>
    </Teleport>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
import Icon from '~/components/ui/Icon.vue'

interface SelectOption {
  label: string
  value: string | number
  icon?: string
  description?: string
  disabled?: boolean
}

interface Props {
  modelValue?: string | number | null
  options: SelectOption[]
  placeholder?: string
  searchable?: boolean
  multiple?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: 'Select an option',
  searchable: false,
  multiple: false
})

const emit = defineEmits<{
  'update:modelValue': [value: string | number | null]
  'change': [value: string | number | null]
  'open': []
  'close': []
}>()

const selectRef = ref<HTMLElement>()
const isOpen = ref(false)
const highlightedIndex = ref(-1)
const dropdownStyle = ref({})

const selectedOption = computed(() => {
  return props.options.find(opt => opt.value === props.modelValue)
})

const toggleSelect = () => {
  isOpen.value = !isOpen.value
  if (isOpen.value) {
    emit('open')
    nextTick(() => updateDropdownPosition())
  } else {
    emit('close')
    highlightedIndex.value = -1
  }
}

const selectOption = (option: SelectOption) => {
  emit('update:modelValue', option.value)
  emit('change', option.value)
  isOpen.value = false
  highlightedIndex.value = -1
  emit('close')
}

const updateDropdownPosition = () => {
  if (!selectRef.value) return
  
  const rect = selectRef.value.getBoundingClientRect()
  const spaceBelow = window.innerHeight - rect.bottom
  const spaceAbove = rect.top
  const dropdownHeight = 300 // Approximate max height
  
  let top = rect.bottom + 8
  if (spaceBelow < dropdownHeight && spaceAbove > spaceBelow) {
    top = rect.top - dropdownHeight - 8
  }
  
  dropdownStyle.value = {
    position: 'fixed',
    top: `${top}px`,
    left: `${rect.left}px`,
    width: `${rect.width}px`,
    zIndex: 9999
  }
}

const handleClickOutside = (event: MouseEvent) => {
  if (selectRef.value && !selectRef.value.contains(event.target as Node)) {
    isOpen.value = false
    highlightedIndex.value = -1
    emit('close')
  }
}

const handleEscape = (event: KeyboardEvent) => {
  if (event.key === 'Escape' && isOpen.value) {
    isOpen.value = false
    highlightedIndex.value = -1
    emit('close')
  }
}

const handleKeyNavigation = (event: KeyboardEvent) => {
  if (!isOpen.value) return
  
  switch (event.key) {
    case 'ArrowDown':
      event.preventDefault()
      highlightedIndex.value = Math.min(
        highlightedIndex.value + 1,
        props.options.length - 1
      )
      break
    case 'ArrowUp':
      event.preventDefault()
      highlightedIndex.value = Math.max(highlightedIndex.value - 1, 0)
      break
    case 'Enter':
      event.preventDefault()
      if (highlightedIndex.value >= 0) {
        const option = props.options[highlightedIndex.value]
        if (!option.disabled) {
          selectOption(option)
        }
      }
      break
  }
}

onMounted(() => {
  document.addEventListener('click', handleClickOutside)
  document.addEventListener('keydown', handleEscape)
  document.addEventListener('keydown', handleKeyNavigation)
  window.addEventListener('resize', updateDropdownPosition)
  window.addEventListener('scroll', updateDropdownPosition)
})

onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside)
  document.removeEventListener('keydown', handleEscape)
  document.removeEventListener('keydown', handleKeyNavigation)
  window.removeEventListener('resize', updateDropdownPosition)
  window.removeEventListener('scroll', updateDropdownPosition)
})

watch(isOpen, (newVal) => {
  if (newVal) {
    nextTick(() => updateDropdownPosition())
  }
})
</script>

<style scoped lang="scss">
.animated-select {
  position: relative;
  width: 100%;
  
  &__trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 0.75rem 1rem;
    background: rgba(255, 255, 255, 0.7);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 2px solid transparent;
    border-radius: 16px;
    cursor: pointer;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    outline: none;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
    
    &:hover {
      background: rgba(255, 255, 255, 0.8);
      border-color: rgba(220, 38, 38, 0.2);
      box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08);
      transform: translateY(-1px);
    }
    
    &:focus {
      border-color: #dc2626;
      box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1);
    }
    
    &--open {
      border-color: #dc2626;
      background: rgba(255, 255, 255, 0.9);
      box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1);
    }
  }
  
  &__display {
    flex: 1;
    min-height: 1.5rem;
  }
  
  &__placeholder {
    color: #71717a;
    font-size: 0.9375rem;
  }
  
  &__selected {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: #27272a;
    font-weight: 500;
  }
  
  &__icon {
    width: 1.25rem;
    height: 1.25rem;
    color: #dc2626;
  }
  
  &__arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
  }
  
  &__arrow-icon {
    color: #dc2626;
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    
    &--rotate {
      transform: rotate(180deg);
    }
  }
  
  &__dropdown {
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(30px);
    -webkit-backdrop-filter: blur(30px);
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: 16px;
    box-shadow: 
      0 20px 40px rgba(0, 0, 0, 0.1),
      0 0 0 1px rgba(220, 38, 38, 0.05);
    overflow: hidden;
    max-height: 300px;
    overflow-y: auto;
    
    &::-webkit-scrollbar {
      width: 8px;
    }
    
    &::-webkit-scrollbar-track {
      background: transparent;
    }
    
    &::-webkit-scrollbar-thumb {
      background: rgba(220, 38, 38, 0.2);
      border-radius: 4px;
      
      &:hover {
        background: rgba(220, 38, 38, 0.3);
      }
    }
  }
  
  &__options {
    padding: 0.25rem;
  }
  
  &__option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
    margin: 0.125rem 0;
    border-radius: 12px;
    cursor: pointer;
    transition: all 0.2s ease;
    animation: slideIn 0.3s cubic-bezier(0.4, 0, 0.2, 1) both;
    animation-delay: var(--delay);
    
    &:hover:not(&--disabled) {
      background: linear-gradient(135deg, 
        rgba(220, 38, 38, 0.05) 0%, 
        rgba(220, 38, 38, 0.1) 100%);
      transform: translateX(4px);
    }
    
    &--highlighted {
      background: rgba(220, 38, 38, 0.05);
    }
    
    &--selected {
      background: linear-gradient(135deg, 
        rgba(220, 38, 38, 0.1) 0%, 
        rgba(220, 38, 38, 0.15) 100%);
      color: #dc2626;
      font-weight: 600;
    }
    
    &--disabled {
      opacity: 0.4;
      cursor: not-allowed;
    }
  }
  
  &__option-content {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex: 1;
  }
  
  &__option-icon {
    width: 1.25rem;
    height: 1.25rem;
    color: #dc2626;
  }
  
  &__option-label {
    font-size: 0.9375rem;
    color: inherit;
  }
  
  &__option-description {
    font-size: 0.75rem;
    color: #71717a;
    margin-left: auto;
    margin-right: 1rem;
  }
  
  &__option-check {
    width: 1.25rem;
    height: 1.25rem;
    color: #dc2626;
  }
}

// Animations
@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateX(-10px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.slide-fade-enter-active,
.slide-fade-leave-active {
  transition: all 0.2s ease;
}

.slide-fade-enter-from {
  opacity: 0;
  transform: translateY(-4px);
}

.slide-fade-leave-to {
  opacity: 0;
  transform: translateY(4px);
}

.select-dropdown-enter-active,
.select-dropdown-leave-active {
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.select-dropdown-enter-from {
  opacity: 0;
  transform: scale(0.95) translateY(-10px);
  filter: blur(4px);
}

.select-dropdown-leave-to {
  opacity: 0;
  transform: scale(0.95) translateY(-10px);
  filter: blur(4px);
}

.option-list-enter-active,
.option-list-leave-active {
  transition: all 0.3s ease;
}

.option-list-enter-from {
  opacity: 0;
  transform: translateX(-20px);
}

.option-list-leave-to {
  opacity: 0;
  transform: translateX(20px);
}

.check-enter-active,
.check-leave-active {
  transition: all 0.2s ease;
}

.check-enter-from,
.check-leave-to {
  opacity: 0;
  transform: scale(0.5);
}
</style>