/**
 * Composable para personalización del color principal del tema
 * Guarda la preferencia en localStorage y aplica los gradientes dinámicamente
 */

interface ColorHSL {
  h: number
  s: number
  l: number
}

/**
 * Convierte un color hex a HSL
 */
function hexToHSL(hex: string): ColorHSL {
  // Remover el # si existe
  hex = hex.replace('#', '')

  // Convertir a RGB
  const r = parseInt(hex.substring(0, 2), 16) / 255
  const g = parseInt(hex.substring(2, 4), 16) / 255
  const b = parseInt(hex.substring(4, 6), 16) / 255

  const max = Math.max(r, g, b)
  const min = Math.min(r, g, b)
  let h = 0
  let s = 0
  const l = (max + min) / 2

  if (max !== min) {
    const d = max - min
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min)

    switch (max) {
      case r:
        h = ((g - b) / d + (g < b ? 6 : 0)) / 6
        break
      case g:
        h = ((b - r) / d + 2) / 6
        break
      case b:
        h = ((r - g) / d + 4) / 6
        break
    }
  }

  return {
    h: Math.round(h * 360),
    s: Math.round(s * 100),
    l: Math.round(l * 100),
  }
}

/**
 * Genera una paleta de colores basada en el color base
 */
function generateColorPalette(baseColor: string): Record<string, string> {
  const hsl = hexToHSL(baseColor)

  // Generar escala de luminosidad
  const palette: Record<string, string> = {
    50: `${hsl.h} ${Math.min(100, hsl.s + 20)}% 95%`,
    100: `${hsl.h} ${Math.min(100, hsl.s + 15)}% 90%`,
    200: `${hsl.h} ${Math.min(100, hsl.s + 10)}% 80%`,
    300: `${hsl.h} ${hsl.s}% 70%`,
    400: `${hsl.h} ${hsl.s}% 60%`,
    500: `${hsl.h} ${hsl.s}% ${hsl.l}%`, // Base
    600: `${hsl.h} ${Math.max(0, hsl.s - 5)}% ${Math.max(0, hsl.l - 10)}%`,
    700: `${hsl.h} ${Math.max(0, hsl.s - 10)}% ${Math.max(0, hsl.l - 20)}%`,
    800: `${hsl.h} ${Math.max(0, hsl.s - 15)}% ${Math.max(0, hsl.l - 30)}%`,
    900: `${hsl.h} ${Math.max(0, hsl.s - 20)}% ${Math.max(0, hsl.l - 40)}%`,
    950: `${hsl.h} ${Math.max(0, hsl.s - 25)}% ${Math.max(0, hsl.l - 45)}%`,
  }

  return palette
}

/**
 * Convierte HSL a HEX
 */
function hslToHex(h: number, s: number, l: number): string {
  const sDecimal = s / 100
  const lDecimal = l / 100

  const c = (1 - Math.abs(2 * lDecimal - 1)) * sDecimal
  const x = c * (1 - Math.abs((h / 60) % 2 - 1))
  const m = lDecimal - c / 2
  let r = 0
  let g = 0
  let b = 0

  if (h >= 0 && h < 60) {
    r = c; g = x; b = 0
  } else if (h >= 60 && h < 120) {
    r = x; g = c; b = 0
  } else if (h >= 120 && h < 180) {
    r = 0; g = c; b = x
  } else if (h >= 180 && h < 240) {
    r = 0; g = x; b = c
  } else if (h >= 240 && h < 300) {
    r = x; g = 0; b = c
  } else if (h >= 300 && h < 360) {
    r = c; g = 0; b = x
  }

  const toHex = (value: number) => {
    const hex = Math.round((value + m) * 255).toString(16)
    return hex.length === 1 ? '0' + hex : hex
  }

  return `#${toHex(r)}${toHex(g)}${toHex(b)}`
}

/**
 * Aplica los colores personalizados a las variables CSS
 */
function applyCustomColors(primary?: string, foreground?: string, background?: string) {
  if (import.meta.server) return

  // Aplicar color principal si se proporciona
  if (primary) {
    const hsl = hexToHSL(primary)

    document.documentElement.style.setProperty('--cata-primary', primary)

    // Generar variantes light y dark
    const lightHsl = { ...hsl, l: Math.min(hsl.l + 15, 95) }
    const darkHsl = { ...hsl, l: Math.max(hsl.l - 15, 10) }

    const lightColor = hslToHex(lightHsl.h, lightHsl.s, lightHsl.l)
    const darkColor = hslToHex(darkHsl.h, darkHsl.s, darkHsl.l)

    document.documentElement.style.setProperty('--cata-primary-light', lightColor)
    document.documentElement.style.setProperty('--cata-primary-dark', darkColor)

    // Aplicar paleta completa para Nuxt UI (en formato HSL)
    const palette = generateColorPalette(primary)
    Object.entries(palette).forEach(([key, value]) => {
      document.documentElement.style.setProperty(`--color-primary-${key}`, value)
    })
  }

  // Aplicar color de fuente si se proporciona
  if (foreground) {
    document.documentElement.style.setProperty('--cata-fg', foreground)
  }

  // Aplicar color de background si se proporciona
  if (background) {
    document.documentElement.style.setProperty('--cata-bg', background)
  }
}

interface ThemeColors {
  primary: string | null
  foreground: string | null
  background: string | null
}

/**
 * Colores por defecto según el tema
 */
const DEFAULT_COLORS = {
  light: {
    primary: '#4682B4',
    foreground: '#000000',
    background: '#ffffff',
  },
  dark: {
    primary: '#00FF00',
    foreground: '#00FF00',
    background: '#000000',
  },
}

const STORAGE_KEY = 'riocata-custom-colors'

export const useColorCustomization = () => {
  const colorMode = useColorMode()
  const isDark = computed(() => colorMode.value === 'dark')

  // Estado reactivo de los colores personalizados
  const customColors = useState<{ light: ThemeColors; dark: ThemeColors }>(
    'custom-colors',
    () => ({
      light: { primary: null, foreground: null, background: null },
      dark: { primary: null, foreground: null, background: null },
    })
  )

  /**
   * Carga los colores personalizados desde localStorage
   */
  const loadCustomColors = () => {
    if (import.meta.server) return

    try {
      const stored = localStorage.getItem(STORAGE_KEY)
      if (stored) {
        const colors = JSON.parse(stored)

        // Validar estructura de datos
        if (
          colors &&
          typeof colors === 'object' &&
          colors.light &&
          typeof colors.light === 'object' &&
          colors.dark &&
          typeof colors.dark === 'object'
        ) {
          customColors.value = colors
        } else {
          // Datos corruptos o formato antiguo, resetear
          console.warn('Formato de colores incompatible, reseteando...')
          localStorage.removeItem(STORAGE_KEY)
        }
      }
    } catch (error) {
      console.error('Error al cargar colores personalizados:', error)
      // En caso de error, limpiar localStorage
      localStorage.removeItem(STORAGE_KEY)
    }
  }

  /**
   * Guarda los colores personalizados en localStorage
   */
  const saveCustomColors = () => {
    if (import.meta.server) return

    try {
      localStorage.setItem(STORAGE_KEY, JSON.stringify(customColors.value))
    } catch (error) {
      console.error('Error al guardar colores personalizados:', error)
    }
  }

  /**
   * Establece colores personalizados para el tema actual
   */
  const setCustomColors = (primary?: string, foreground?: string, background?: string) => {
    if (import.meta.server) return

    const theme = isDark.value ? 'dark' : 'light'

    // Asegurar que la estructura existe
    if (!customColors.value[theme] || typeof customColors.value[theme] !== 'object') {
      customColors.value[theme] = { primary: null, foreground: null, background: null }
    }

    if (primary !== undefined) customColors.value[theme].primary = primary
    if (foreground !== undefined) customColors.value[theme].foreground = foreground
    if (background !== undefined) customColors.value[theme].background = background

    saveCustomColors()
    applyCustomColors(primary, foreground, background)
  }

  /**
   * Resetea los colores al valor por defecto del tema actual
   */
  const resetColors = () => {
    if (import.meta.server) return

    const theme = isDark.value ? 'dark' : 'light'
    customColors.value[theme] = { primary: null, foreground: null, background: null }
    saveCustomColors()

    // Limpiar las variables CSS personalizadas para que vuelvan a los valores del CSS
    document.documentElement.style.removeProperty('--cata-primary')
    document.documentElement.style.removeProperty('--cata-primary-light')
    document.documentElement.style.removeProperty('--cata-primary-dark')
    document.documentElement.style.removeProperty('--cata-fg')
    document.documentElement.style.removeProperty('--cata-bg')

    // Limpiar paleta de Nuxt UI
    for (let i = 50; i <= 950; i += (i < 100 ? 50 : 100)) {
      document.documentElement.style.removeProperty(`--color-primary-${i}`)
    }
  }

  /**
   * Obtiene los colores actuales (personalizados o por defecto)
   */
  const getCurrentColors = computed(() => {
    const theme = isDark.value ? 'dark' : 'light'
    const colors = customColors.value[theme]

    // Validar que la estructura existe
    if (!colors || typeof colors !== 'object') {
      return DEFAULT_COLORS[theme]
    }

    return {
      primary: colors.primary || DEFAULT_COLORS[theme].primary,
      foreground: colors.foreground || DEFAULT_COLORS[theme].foreground,
      background: colors.background || DEFAULT_COLORS[theme].background,
    }
  })

  /**
   * Verifica si hay colores personalizados para el tema actual
   */
  const hasCustomColors = computed(() => {
    const theme = isDark.value ? 'dark' : 'light'
    const colors = customColors.value[theme]

    // Validar que la estructura existe
    if (!colors || typeof colors !== 'object') {
      return false
    }

    return colors.primary !== null || colors.foreground !== null || colors.background !== null
  })

  /**
   * Inicializa el composable
   */
  const inicializar = () => {
    if (import.meta.server) return

    loadCustomColors()

    // Solo aplicar colores si hay colores personalizados guardados
    const theme = isDark.value ? 'dark' : 'light'
    const colors = customColors.value[theme]
    if (colors && typeof colors === 'object' && (colors.primary || colors.foreground || colors.background)) {
      applyCustomColors(
        colors.primary || undefined,
        colors.foreground || undefined,
        colors.background || undefined
      )
    }

    // Observar cambios en el modo de color
    watch(isDark, (newIsDark) => {
      const theme = newIsDark ? 'dark' : 'light'
      const colors = customColors.value[theme]
      // Solo aplicar si hay colores personalizados para este tema
      if (colors && typeof colors === 'object' && (colors.primary || colors.foreground || colors.background)) {
        applyCustomColors(
          colors.primary || undefined,
          colors.foreground || undefined,
          colors.background || undefined
        )
      }
    })
  }

  return {
    customColors: readonly(customColors),
    getCurrentColors,
    hasCustomColors,
    setCustomColors,
    resetColors,
    inicializar,
  }
}
