<template>
  <div class="dropdown" ref="dropdown">
    <button
        ref="trigger"
        class="dropdown-trigger"
        :class="{ 'dropdown-trigger--open': isOpen}"
        @click.stop="toggleDropdown"
        @keydown="handleTriggerKeydown"
        :disabled="disabled"
    >
      <span class="dropdown-trigger-text">
        {{ selectedOption ? selectedOption[displayKey] : placeholder }}
      </span>
      <svg
          class="dropdown-trigger-icon"
          :class="{ 'dropdown-trigger-icon--rotated': isOpen }"
          xmlns="http://www.w3.org/2000/svg"
          width="20"
          height="20"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          stroke-linecap="round"
          stroke-linejoin="round"
      >
        <polyline points="6,9 12,15 18,9"></polyline>
      </svg>
    </button>

    <transition name="dropdown-fade">
      <ul
          v-if="isOpen"
          ref="menu"
          class="dropdown-menu"
          @keydown="handleMenuKeydown"
          tabindex="-1"
      >
        <li
            v-for="(option, index) in options"
            :key="option[valueKey]"
            class="dropdown-option"
            :class="{
            'dropdown-option--selected': isSelected(option),
            'dropdown-option--focused': focusedIndex === index
          }"
            @click="selectOption(option)"
            @mouseenter="focusedIndex = index"
        >
          {{ option[displayKey] }}
        </li>
        <li v-if="options.length === 0" class="dropdown-option dropdown-option--empty">
          {{ emptyText }}
        </li>
      </ul>
    </transition>
  </div>
</template>

<script>
export default {
  name: 'Dropdown',
  props: {
    options: {
      type: Array,
      default: () => []
    },
    modelValue: {
      type: [String, Number, Object],
      default: null
    },
    placeholder: {
      type: String,
      default: 'Select an option'
    },
    displayKey: {
      type: String,
      default: 'value'
    },
    valueKey: {
      type: String,
      default: 'id'
    },
    emptyText: {
      type: String,
      default: 'No options available'
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  emits: ['update:modelValue', 'change'],
  data() {
    return {
      isOpen: false,
      focusedIndex: -1,
      labelId: `dropdown-${Math.random().toString(36).substring(2, 9)}`
    }
  },
  computed: {
    selectedOption() {
      if (!this.modelValue) return null
      return this.options?.find(option =>
          option[this.valueKey] === this.modelValue
      ) ?? null;
    }
  },
  mounted() {
    document.addEventListener('click', this.handleClickOutside)
  },
  beforeUnmount() {
    document.removeEventListener('click', this.handleClickOutside)
  },
  methods: {
    toggleDropdown() {
      if (this.disabled) return

      this.isOpen = !this.isOpen

      if (this.isOpen) {
        this.$nextTick(() => {
          this.$refs.menu?.focus()
          this.focusedIndex = this.selectedOption ?
              this.options.findIndex(option => option[this.valueKey] === this.modelValue) :
              0
        })
      } else {
        this.focusedIndex = -1
      }
    },
    selectOption(option) {
      this.$emit('update:modelValue', option[this.valueKey])
      this.$emit('change', option)
      this.closeDropdown()
      this.$refs.trigger.focus()
    },
    closeDropdown() {
      this.isOpen = false
      this.focusedIndex = -1
    },
    isSelected(option) {
      return this.modelValue === option[this.valueKey]
    },
    handleClickOutside(event) {

      if (!this.$refs.dropdown?.contains(event.target)) {
        this.closeDropdown()
      }
    },
    handleTriggerKeydown(event) {
      switch (event.key) {
        case 'Enter':
        case ' ':
        case 'ArrowDown':
          event.preventDefault()
          if (!this.isOpen) {
            this.toggleDropdown()
          }
          break
        case 'ArrowUp':
          event.preventDefault()
          if (!this.isOpen) {
            this.toggleDropdown()
          }
          break
        case 'Escape':
          if (this.isOpen) {
            event.preventDefault()
            this.closeDropdown()
          }
          break
      }
    },
    handleMenuKeydown(event) {
      switch (event.key) {
        case 'ArrowDown':
          event.preventDefault()
          this.focusedIndex = Math.min(this.focusedIndex + 1, this.options.length - 1)
          break
        case 'ArrowUp':
          event.preventDefault()
          this.focusedIndex = Math.max(this.focusedIndex - 1, 0)
          break
        case 'Enter':
          event.preventDefault()
          if (this.focusedIndex >= 0 && this.options[this.focusedIndex]) {
            this.selectOption(this.options[this.focusedIndex])
          }
          break
        case 'Escape':
          event.preventDefault()
          this.closeDropdown()
          this.$refs.trigger.focus()
          break
        case 'Tab':
          this.closeDropdown()
          break
      }
    }
  }
}
</script>

<style scoped>
.dropdown {
  position: relative;
  display: flex;
  flex: 1 0 auto;
}

.dropdown-trigger {
  display: flex;
  align-items: center;
  background: white;
  border-radius: 0.4rem;
  padding: 0.6rem 1.2rem;
  /* box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);*/
  border: 0.2rem solid #E3EDFF;
  transition: all 0.1s ease;
  flex: 1 0 auto;
  font: inherit;
}

.dropdown-trigger:hover {
  background: #EEF4FF;
  border: 0.2rem solid #8DB3FE;
  /*transform: translateY(2px);*/
  transform: scale(1.01);
}


.dropdown-trigger--open {
  border: 0.2rem solid #8DB3FE;
  background: #EEF4FF;
}

.dropdown-trigger-text {
  flex: 1;
  text-align: left;
  color: #2d3748;
  font: inherit;
}

.dropdown-trigger-icon {
  transition: transform 0.2s ease;
  color: #718096;
}

.dropdown-trigger-icon--rotated {
  transform: rotate(180deg);
}

.dropdown-menu {
  font: inherit;
  outline: none;
  list-style: none;
  color: #2d3748;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  padding: 0;
  background: white;
  border: 0.1rem solid #E3EDFF;
  border-radius: 0.8rem;
  box-shadow: 0 0.4rem 0.6rem -0.1rem rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);
  z-index: 1000;
  max-height: 50rem;
  overflow-y: auto;
  margin-top: 0.4rem;
}

.dropdown-option {
  font: inherit;
  padding: 1.2rem 1.6rem;
  cursor: pointer;
  border-bottom: 0.16rem solid #f3f4f6;
  transition: background-color 0.2s ease;
  color: #2d3748;
  background: none;
}

.dropdown-option:last-child {
  border-bottom: none;
}

.dropdown-option:hover,
.dropdown-option--focused {
  background-color: rgba(107, 134, 156, 0.05);
}

.dropdown-option--selected {
  color: #2d3748;
  background: none;
}

.dropdown-option--selected:hover,
.dropdown-option--selected.dropdown-option--focused {
  color: #2d3748;
  background-color: rgba(107, 134, 156, 0.05);
}

.dropdown-option--empty {
  color: #001D33;
  cursor: default;
}

.dropdown-option--empty:hover {
  background-color: transparent;
}

/* Transition animations */
.dropdown-fade-enter-active,
.dropdown-fade-leave-active {
  transition: all 0.15s ease;
}

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

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

/* Disabled state */
.dropdown-trigger:disabled {
  background: white;
  cursor: not-allowed;
  border: 0.2rem solid rgba(227, 237, 255, 0.5);
  color: rgba(0, 47, 84, 0.3);
}

.dropdown-trigger:disabled:hover {
  border: 0.2rem solid rgba(227, 237, 255, 0.5);
  transform: none;
}


/* Add this CSS rule to your existing styles */
.dropdown-trigger:disabled .dropdown-trigger-text {
  color: rgba(0, 47, 84, 0.5);
}

/* You might also want to style the icon when disabled */
.dropdown-trigger:disabled .dropdown-trigger-icon {
  color: rgba(113, 128, 150, 0.5);
}

/* Responsive adjustments */
@media (max-width: 640px) {
  .dropdown-trigger {
    padding: 10px 12px;
    font-size: 14px;
  }

  .dropdown-option {
    padding: 10px 12px;
  }
}
</style>