<template>
  <div class="route-dropdown" ref="dropdown">
    <button
        ref="trigger"
        class="route-dropdown-trigger"
        :class="{ 'route-dropdown-trigger--open': isOpen}"
        @click="toggleDropdown"
        @keydown="handleTriggerKeydown"
        :disabled="disabled"
    >
      <span class="route-dropdown-trigger-content">
        <component
            v-if="selectedIcon"
            :is="selectedIcon"
            :size="16"
            class="route-icon"
        />
        <span class="route-dropdown-trigger-text">
          {{ selectedDisplayText }}
        </span>
      </span>
      <span class="route-dropdown-trigger-warning"><ph-warning-circle v-if="warnD2D" weight="fill"
                                                                      size="16"></ph-warning-circle></span>
      <svg
          class="route-dropdown-trigger-icon"
          :class="{ 'route-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="route-dropdown-fade">
      <ul
          v-if="isOpen"
          ref="menu"
          class="route-dropdown-menu"
          @keydown="handleMenuKeydown"
          tabindex="-1"
      >
        <!-- D2D Routing Option -->
        <li
            class="route-dropdown-option"
            :class="{
              'route-dropdown-option--selected': isD2DSelected,
              'route-dropdown-option--focused': focusedIndex === -1
            }"
            @click="selectD2D"
            @mouseenter="focusedIndex = -1"
        >
          <ph-shipping-container :size="16" class="route-icon"/>
          <span>D2D routing</span>
        </li>

        <!-- Divider -->
        <li v-if="options.length > 0" class="route-dropdown-divider"></li>

        <!-- Regular Route Options -->
        <li
            v-for="(option, index) in options"
            :key="option[valueKey]"
            class="route-dropdown-option"
            :class="{
              'route-dropdown-option--selected': isSelected(option),
              'route-dropdown-option--focused': focusedIndex === index
            }"
            @click="selectOption(option, $event)"
            @mouseenter="focusedIndex = index"
        >
          <component
              :is="getIconForType(option.type)"
              :size="16"
              class="route-icon"
          />
          <span>{{ option[displayKey] }}</span>
        </li>

        <li v-if="options.length === 0" class="route-dropdown-option route-dropdown-option--empty">
          {{ emptyText }}
        </li>
      </ul>
    </transition>
  </div>
</template>

<script>
import {PhTruck, PhBoat, PhTrain, PhShippingContainer, PhWarningCircle} from '@phosphor-icons/vue'

export default {
  name: 'RouteDropdown',
  components: {
    PhWarningCircle,
    PhTruck,
    PhBoat,
    PhTrain,
    PhShippingContainer
  },
  props: {
    options: {
      type: Array,
      default: () => []
    },
    modelValue: {
      type: [String, Number, Object],
      default: null
    },
    placeholder: {
      type: String,
      default: 'Select a route'
    },
    displayKey: {
      type: String,
      default: 'routeDisplayString'
    },
    valueKey: {
      type: String,
      default: 'routeCompareString'
    },
    emptyText: {
      type: String,
      default: 'No routes available'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    showD2dWarn: {
      type: Boolean,
      default: false
    }
  },
  emits: ['update:modelValue', 'change'],
  data() {
    return {
      isOpen: false,
      focusedIndex: -1,
      D2D_VALUE: 'D2D_ROUTING'
    }
  },
  computed: {
    warnD2D() {
      return this.isD2DSelected && this.showD2dWarn;
    },
    selectedOption() {
      if (!this.modelValue || this.modelValue === this.D2D_VALUE) return null
      return this.options?.find(option =>
          option[this.valueKey] === this.modelValue
      ) ?? null
    },
    isD2DSelected() {
      return this.modelValue === this.D2D_VALUE
    },
    selectedDisplayText() {
      if (this.isD2DSelected) return 'D2D routing'
      if (this.selectedOption) return this.selectedOption[this.displayKey]
      return this.placeholder
    },
    selectedIcon() {
      if (this.isD2DSelected) return 'ph-shipping-container'
      if (this.selectedOption) return this.getIconForType(this.selectedOption.type)
      return null
    }
  },
  watch: {
    isOpen(newVal) {
      if (newVal) {
        // Warte einen Tick, damit das Menü gerendert ist
        this.$nextTick(() => {
          document.addEventListener('click', this.handleClickOutside, true)
        })
      } else {
        document.removeEventListener('click', this.handleClickOutside, true)
      }
    }
  },
  beforeUnmount() {
    document.removeEventListener('click', this.handleClickOutside, true)
  },
  methods: {
    getIconForType(type) {
      const iconMap = {
        'ROAD': 'ph-truck',
        'SEA': 'ph-boat',
        'RAIL': 'ph-train'
      }
      return iconMap[type] || null
    },
    toggleDropdown(event) {
      if (this.disabled) return

      event.stopPropagation()
      this.isOpen = !this.isOpen

      if (this.isOpen) {
        this.$nextTick(() => {
          this.$refs.menu?.focus()

          if (this.isD2DSelected) {
            this.focusedIndex = -1
          } else if (this.selectedOption) {
            this.focusedIndex = this.options.findIndex(option =>
                option[this.valueKey] === this.modelValue
            )
          } else {
            this.focusedIndex = -1
          }
        })
      } else {
        this.focusedIndex = -1
      }
    },
    selectD2D(event) {
      event.stopPropagation()
      this.$emit('update:modelValue', this.D2D_VALUE)
      this.$emit('change', {type: 'D2D', value: this.D2D_VALUE})
      this.closeDropdown()
      this.$refs.trigger.focus()
    },
    selectOption(option, event) {
      event.stopPropagation()
      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(event)
          }
          break
        case 'ArrowUp':
          event.preventDefault()
          if (!this.isOpen) {
            this.toggleDropdown(event)
          }
          break
        case 'Escape':
          if (this.isOpen) {
            event.preventDefault()
            this.closeDropdown()
          }
          break
      }
    },
    handleMenuKeydown(event) {
      const totalOptions = this.options.length

      switch (event.key) {
        case 'ArrowDown':
          event.preventDefault()
          if (this.focusedIndex === -1) {
            this.focusedIndex = totalOptions > 0 ? 0 : -1
          } else {
            this.focusedIndex = Math.min(this.focusedIndex + 1, totalOptions - 1)
          }
          break
        case 'ArrowUp':
          event.preventDefault()
          if (this.focusedIndex === 0) {
            this.focusedIndex = -1
          } else if (this.focusedIndex === -1) {
            this.focusedIndex = -1
          } else {
            this.focusedIndex = Math.max(this.focusedIndex - 1, 0)
          }
          break
        case 'Enter':
          event.preventDefault()
          if (this.focusedIndex === -1) {
            this.selectD2D(event)
          } else if (this.focusedIndex >= 0 && this.options[this.focusedIndex]) {
            this.selectOption(this.options[this.focusedIndex], event)
          }
          break
        case 'Escape':
          event.preventDefault()
          this.closeDropdown()
          this.$refs.trigger.focus()
          break
        case 'Tab':
          this.closeDropdown()
          break
      }
    }
  }
}
</script>

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

.route-dropdown-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: white;
  border-radius: 0.4rem;
  padding: 0.6rem 1.2rem;
  border: 0.2rem solid #E3EDFF;
  transition: all 0.1s ease;
  flex: 1 0 auto;
  font: inherit;
  cursor: pointer;
}

.route-dropdown-trigger:hover {
  background: #EEF4FF;
  border: 0.2rem solid #8DB3FE;
  transform: scale(1.01);
}

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

.route-dropdown-trigger-content {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex: 1;
}

.route-dropdown-trigger-text {
  color: #2d3748;
  font: inherit;
  letter-spacing: -0.05em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.route-dropdown-trigger-warning {
  display: flex;
  align-items: center;
  color: #BC2B72;
}

.route-icon {
  color: #6b7280;
  flex-shrink: 0;
}

.route-dropdown-trigger-icon {
  transition: transform 0.2s ease;
  color: #718096;
  flex-shrink: 0;
  margin-left: 0.8rem;
}

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

.route-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;
}

.route-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;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  letter-spacing: -0.05em;
}


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

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

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

.route-dropdown-option--empty {
  color: #001D33;
  cursor: default;
  justify-content: center;
}

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

.route-dropdown-divider {
  height: 0.1rem;
  background-color: #e5e7eb;

  border-bottom: none; /* Diese Zeile hinzufügen */
}

.route-dropdown-option:has(+ .route-dropdown-divider) {
  border-bottom: none;
}

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

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

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

/* Disabled state */
.route-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);
}

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

.route-dropdown-trigger:disabled .route-dropdown-trigger-text {
  color: rgba(0, 47, 84, 0.5);
}

.route-dropdown-trigger:disabled .route-dropdown-trigger-icon,
.route-dropdown-trigger:disabled .route-icon {
  color: rgba(113, 128, 150, 0.5);
}

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

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