<template>
  <div class="flex items-center gap-3">
    <!-- Toggle Switch -->
    <button
      type="button"
      :disabled="disabled"
      :class="switchClasses"
      role="switch"
      :aria-checked="modelValue"
      @click="handleToggle"
    >
      <!-- Track -->
      <span
        aria-hidden="true"
        :class="trackClasses"
      ></span>

      <!-- Thumb -->
      <span
        aria-hidden="true"
        :class="thumbClasses"
      ></span>
    </button>

    <!-- Label (optional) -->
    <label
      v-if="label"
      :class="labelClasses"
      @click="handleToggle"
    >
      {{ label }}
    </label>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'

interface Props {
  modelValue: boolean
  label?: string
  disabled?: boolean
  size?: 'sm' | 'md' | 'lg'
}

const props = withDefaults(defineProps<Props>(), {
  disabled: false,
  size: 'md',
})

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

const switchClasses = computed(() => {
  const base = 'relative inline-flex items-center flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed'

  // Size classes
  const sizeClasses = {
    sm: 'h-5 w-9',
    md: 'h-6 w-11',
    lg: 'h-7 w-14',
  }

  return `${base} ${sizeClasses[props.size]}`
})

const trackClasses = computed(() => {
  const base = 'pointer-events-none absolute h-full w-full rounded-full transition-colors duration-200'
  const color = props.modelValue
    ? 'bg-gradient-to-r from-green-500 to-green-600'
    : 'bg-gray-300 dark:bg-gray-600'

  return `${base} ${color}`
})

const thumbClasses = computed(() => {
  const base = 'pointer-events-none absolute bg-white rounded-full shadow-lg transform transition-transform duration-200 ease-in-out'

  // Size-specific dimensions and positions
  const sizeClasses = {
    sm: 'h-4 w-4',
    md: 'h-5 w-5',
    lg: 'h-6 w-6',
  }

  // Position based on state
  const translateClasses = {
    sm: props.modelValue ? 'translate-x-4' : 'translate-x-0.5',
    md: props.modelValue ? 'translate-x-5' : 'translate-x-0.5',
    lg: props.modelValue ? 'translate-x-7' : 'translate-x-0.5',
  }

  return `${base} ${sizeClasses[props.size]} ${translateClasses[props.size]}`
})

const labelClasses = computed(() => {
  const base = 'text-sm font-medium cursor-pointer select-none'
  const color = props.disabled
    ? 'text-gray-400 cursor-not-allowed'
    : 'text-gray-700 dark:text-gray-200'

  return `${base} ${color}`
})

const handleToggle = () => {
  if (!props.disabled) {
    emit('update:modelValue', !props.modelValue)
  }
}
</script>
