<script setup lang="ts">
import type { Component, HTMLAttributes } from 'vue'
import { computed, ref, onMounted, watch, nextTick } from 'vue'
import { cn } from '@/lib/utils'

export interface SlidingTabsOption {
  value: string
  icon?: Component
  label?: string
}

const props = defineProps<{
  modelValue: string
  options: SlidingTabsOption[]
  class?: HTMLAttributes['class']
}>()

const emit = defineEmits<{
  'update:modelValue': [value: string]
}>()

const buttonRefs = ref<HTMLDivElement[]>([])
const indicatorWidth = ref(0)
const indicatorOffset = ref(0)

const activeIndex = computed(() => props.options.findIndex((opt) => opt.value === props.modelValue))

function updateIndicator() {
  const index = activeIndex.value
  if (index < 0 || !buttonRefs.value[index]) return

  const button = buttonRefs.value[index]
  indicatorWidth.value = button.offsetWidth
  indicatorOffset.value = button.offsetLeft
}

const indicatorStyle = computed(() => ({
  width: `${indicatorWidth.value}px`,
  transform: `translateX(${indicatorOffset.value - 20}px)`,
}))

function selectOption(value: string) {
  if (value !== props.modelValue) {
    emit('update:modelValue', value)
  }
}

onMounted(() => {
  nextTick(updateIndicator)
})

watch(activeIndex, () => {
  nextTick(updateIndicator)
})
</script>

<template>
  <div :class="cn('relative flex rounded-md h-[48px] gap-[10px] px-[20px]', props.class)">
    <!-- Sliding Indicator -->
    <div
      class="absolute bottom-0 h-[2px] bg-primary transition-all duration-200 ease-out"
      :style="indicatorStyle"
    />

    <!-- Option Buttons -->
    <button
      v-for="(option, index) in options"
      :key="option.value"
      :ref="
        (el) => {
          if (el) buttonRefs[index] = el as HTMLDivElement
        }
      "
      type="button"
      :class="[
        'relative z-10 flex items-center justify-center gap-1 px-[8px] text-sm transition-colors border-b-2 border-transparent text-foreground/60',
        option.value === modelValue
          ? 'text-primary dark:text-white'
          : 'text-muted-foreground hover:text-primary/80 hover:text-foreground hover:border-primary/50 hover:text-foreground/80',
      ]"
      @click="selectOption(option.value)"
    >
      <component :is="option.icon" v-if="option.icon" class="h-4 w-4 shrink-0" />
      <span v-if="option.label">{{ option.label }}</span>
    </button>
  </div>
</template>
