<template>
  <div :class="containerClasses">
    <!-- Button variant -->
    <button
      v-if="variant === 'button'"
      type="button"
      :class="buttonClasses"
      @click="toggleTheme"
      :aria-label="currentTheme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'"
    >
      <!-- Sun icon (light mode) -->
      <svg
        v-if="currentTheme === 'dark'"
        :class="iconClasses"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
      >
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          stroke-width="2"
          d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
        />
      </svg>

      <!-- Moon icon (dark mode) -->
      <svg v-else :class="iconClasses" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          stroke-width="2"
          d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
        />
      </svg>

      <span v-if="showText" :class="textClasses">
        {{ currentTheme === 'dark' ? 'Light' : 'Dark' }}
      </span>
    </button>

    <!-- Dropdown variant -->
    <div v-else-if="variant === 'dropdown'" class="relative">
      <button
        type="button"
        :class="dropdownButtonClasses"
        @click="dropdownOpen = !dropdownOpen"
        @blur="handleBlur"
        :aria-expanded="dropdownOpen"
        aria-haspopup="true"
      >
        <!-- Current theme icon -->
        <svg
          v-if="currentTheme === 'dark'"
          :class="iconClasses"
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
        >
          <path
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="2"
            d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
          />
        </svg>
        <svg
          v-else-if="currentTheme === 'light'"
          :class="iconClasses"
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
        >
          <path
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="2"
            d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
          />
        </svg>
        <svg v-else :class="iconClasses" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="2"
            d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
          />
        </svg>

        <span v-if="showText" :class="textClasses">
          {{ currentTheme === 'dark' ? 'Dark' : currentTheme === 'light' ? 'Light' : 'Auto' }}
        </span>

        <!-- Dropdown arrow -->
        <svg
          v-if="showDropdown"
          class="ml-2 h-4 w-4 transition-transform"
          :class="{ 'rotate-180': dropdownOpen }"
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
        >
          <path
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="2"
            d="M19 9l-7 7-7-7"
          />
        </svg>
      </button>

      <!-- Dropdown menu -->
      <Transition
        enter-active-class="transition duration-100 ease-out"
        enter-from-class="transform scale-95 opacity-0"
        enter-to-class="transform scale-100 opacity-100"
        leave-active-class="transition duration-75 ease-in"
        leave-from-class="transform scale-100 opacity-100"
        leave-to-class="transform scale-95 opacity-0"
      >
        <div
          v-if="dropdownOpen"
          :class="dropdownMenuClasses"
          role="menu"
          aria-orientation="vertical"
        >
          <!-- Light mode option -->
          <button
            type="button"
            :class="dropdownItemClasses(currentTheme === 'light')"
            @click="setTheme('light')"
            role="menuitem"
          >
            <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
              />
            </svg>
            Light
          </button>

          <!-- Dark mode option -->
          <button
            type="button"
            :class="dropdownItemClasses(currentTheme === 'dark')"
            @click="setTheme('dark')"
            role="menuitem"
          >
            <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
              />
            </svg>
            Dark
          </button>

          <!-- System mode option -->
          <button
            type="button"
            :class="dropdownItemClasses(currentTheme === 'system')"
            @click="setTheme('system')"
            role="menuitem"
          >
            <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
              />
            </svg>
            System
          </button>
        </div>
      </Transition>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'

interface ThemeControllerProps {
  variant?: 'button' | 'dropdown'
  size?: 'sm' | 'md' | 'lg'
  showText?: boolean
  showDropdown?: boolean
  position?: 'fixed' | 'relative'
}

const props = withDefaults(defineProps<ThemeControllerProps>(), {
  variant: 'button',
  size: 'md',
  showText: false,
  showDropdown: true,
  position: 'relative',
})

// State
const currentTheme = ref<'light' | 'dark' | 'system'>('system')
const dropdownOpen = ref(false)

// Computed classes
const containerClasses = computed(() => {
  return props.position === 'fixed' ? 'fixed top-4 right-4 z-50' : 'relative'
})

const sizeClasses = computed(() => {
  const sizes = {
    sm: {
      button: 'h-8 px-2',
      icon: 'h-4 w-4',
      text: 'text-sm',
    },
    md: {
      button: 'h-10 px-3',
      icon: 'h-5 w-5',
      text: 'text-sm',
    },
    lg: {
      button: 'h-12 px-4',
      icon: 'h-6 w-6',
      text: 'text-base',
    },
  }
  return sizes[props.size]
})

const buttonClasses = computed(() => {
  return [
    'inline-flex items-center justify-center rounded-md border border-gray-300 bg-white text-gray-700 transition-colors',
    'hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2',
    'dark:border-gray-600 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700',
    sizeClasses.value.button,
  ].join(' ')
})

const dropdownButtonClasses = computed(() => {
  return [
    'inline-flex items-center justify-center rounded-md border border-gray-300 bg-white text-gray-700 transition-colors',
    'hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2',
    'dark:border-gray-600 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700',
    sizeClasses.value.button,
  ].join(' ')
})

const dropdownMenuClasses = computed(() => {
  return [
    'absolute right-0 mt-2 w-48 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5',
    'dark:bg-gray-800 dark:ring-gray-700',
    'focus:outline-none z-50',
  ].join(' ')
})

const iconClasses = computed(() => {
  let classes = sizeClasses.value.icon
  if (props.showText) classes += ' mr-2'
  return classes
})

const textClasses = computed(() => {
  return `${sizeClasses.value.text} font-medium`
})

// Dropdown item classes
const dropdownItemClasses = (isActive: boolean) => {
  const baseClasses = 'flex w-full items-center px-4 py-2 text-left text-sm transition-colors'
  const activeClasses = isActive
    ? 'bg-blue-50 text-blue-700 dark:bg-blue-900 dark:text-blue-200'
    : 'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700'

  return `${baseClasses} ${activeClasses}`
}

// Theme management
const applyTheme = (theme: 'light' | 'dark') => {
  if (theme === 'dark') {
    document.documentElement.classList.add('dark')
  } else {
    document.documentElement.classList.remove('dark')
  }
}

const getSystemTheme = (): 'light' | 'dark' => {
  return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}

const setTheme = (theme: 'light' | 'dark' | 'system') => {
  currentTheme.value = theme
  localStorage.setItem('theme', theme)

  if (theme === 'system') {
    applyTheme(getSystemTheme())
  } else {
    applyTheme(theme)
  }

  dropdownOpen.value = false
}

const toggleTheme = () => {
  if (currentTheme.value === 'light') {
    setTheme('dark')
  } else {
    setTheme('light')
  }
}

const handleBlur = (event: FocusEvent) => {
  // Close dropdown if focus moves outside
  const relatedTarget = event.relatedTarget as Element
  if (!relatedTarget || !relatedTarget.closest('[role="menu"]')) {
    dropdownOpen.value = false
  }
}

// Initialize theme
onMounted(() => {
  const savedTheme = localStorage.getItem('theme') as 'light' | 'dark' | 'system' | null

  if (savedTheme) {
    currentTheme.value = savedTheme
  } else {
    currentTheme.value = 'system'
  }

  if (currentTheme.value === 'system') {
    applyTheme(getSystemTheme())
  } else {
    applyTheme(currentTheme.value)
  }

  // Listen for system theme changes
  const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
  const handleSystemThemeChange = () => {
    if (currentTheme.value === 'system') {
      applyTheme(getSystemTheme())
    }
  }

  mediaQuery.addEventListener('change', handleSystemThemeChange)

  // Cleanup
  return () => {
    mediaQuery.removeEventListener('change', handleSystemThemeChange)
  }
})

// Watch for theme changes
watch(currentTheme, (newTheme) => {
  if (newTheme === 'system') {
    applyTheme(getSystemTheme())
  } else {
    applyTheme(newTheme)
  }
})
</script>
