/**
 * Theme Store — Dark mode toggle with system preference detection.
 *
 * Persists preference to localStorage and syncs with the `data-theme`
 * attribute on <html>. Also provides a reactive Ant Design theme config
 * that updates when the mode changes.
 */

import { ref, computed, watchEffect } from 'vue'
import { defineStore } from 'pinia'
import { theme } from 'ant-design-vue'
import type { ThemeConfig } from 'ant-design-vue/es/config-provider/context'

export type ThemeMode = 'light' | 'dark' | 'system'

const STORAGE_KEY = 'agentkit-theme-mode'

const VALID_MODES: ThemeMode[] = ['light', 'dark', 'system']

function readToken(varName: string, fallback: string): string {
  if (typeof document === 'undefined') return fallback
  const val = getComputedStyle(document.documentElement).getPropertyValue(varName).trim()
  return val || fallback
}

function getSystemPreference(): 'light' | 'dark' {
  if (typeof window === 'undefined') return 'light'
  return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}

function getStoredMode(): ThemeMode {
  try {
    if (typeof localStorage === 'undefined') return 'system'
    const raw = localStorage.getItem(STORAGE_KEY)
    return VALID_MODES.includes(raw as ThemeMode) ? (raw as ThemeMode) : 'system'
  } catch {
    return 'system'
  }
}

function applyTheme(resolved: 'light' | 'dark') {
  if (typeof document === 'undefined') return
  document.documentElement.setAttribute('data-theme', resolved)
}

export const useThemeStore = defineStore('theme', () => {
  const mode = ref<ThemeMode>(getStoredMode())

  // Separate reactive ref for system preference — allows matchMedia changes
  // to trigger Vue reactivity in resolvedMode computed
  const systemPreference = ref<'light' | 'dark'>(getSystemPreference())

  const resolvedMode = computed<'light' | 'dark'>(() => {
    if (mode.value === 'system') return systemPreference.value
    return mode.value
  })

  function setMode(newMode: ThemeMode) {
    mode.value = newMode
    try {
      localStorage.setItem(STORAGE_KEY, newMode)
    } catch {
      // localStorage unavailable (private browsing, quota exceeded) — ignore
    }
  }

  function toggle() {
    if (resolvedMode.value === 'light') {
      setMode('dark')
    } else {
      setMode('light')
    }
  }

  // Apply theme whenever resolvedMode changes
  watchEffect(() => {
    applyTheme(resolvedMode.value)
  })

  // Listen for system preference changes — update reactive ref
  if (typeof window !== 'undefined') {
    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
      systemPreference.value = e.matches ? 'dark' : 'light'
    })
  }

  // Ant Design Vue theme config — reactive to dark mode
  const antThemeConfig = computed<ThemeConfig>(() => {
    const isDark = resolvedMode.value === 'dark'

    return {
      algorithm: isDark ? theme.darkAlgorithm : theme.defaultAlgorithm,
      token: {
        colorPrimary: readToken('--color-primary', isDark ? '#818cf8' : '#6366f1'),
        colorInfo: readToken('--color-primary', isDark ? '#818cf8' : '#6366f1'),
        colorSuccess: readToken('--color-success', isDark ? '#4ade80' : '#22c55e'),
        colorWarning: readToken('--color-warning', isDark ? '#fbbf24' : '#f59e0b'),
        colorError: readToken('--color-error', isDark ? '#f87171' : '#ef4444'),
        colorText: readToken('--text-primary', isDark ? '#fbfbfa' : '#1a1a1a'),
        colorTextSecondary: readToken('--text-secondary', isDark ? '#cececd' : '#4a4a4a'),
        colorTextTertiary: readToken('--text-tertiary', isDark ? '#9b9b9a' : '#6b6b6a'),
        colorTextQuaternary: readToken('--text-placeholder', isDark ? '#6b6b6a' : '#9b9b9a'),
        // Text rendered ON top of ``colorPrimary`` (primary buttons, active
        // tab indicators, etc.). Ant Design hardcodes this to #fff in both
        // light and dark themes, which clashes with our design: in dark
        // mode ``--color-primary`` is a near-white pill (#fbfbfa) and we
        // want dark text on it. Source the value from --text-inverse so
        // light and dark themes stay consistent with the rest of the
        // design tokens.
        colorTextLightSolid: readToken('--text-inverse', isDark ? '#1a1a1a' : '#ffffff'),
        colorBgContainer: readToken('--bg-primary', isDark ? '#1a1a1a' : '#ffffff'),
        colorBgLayout: readToken('--bg-secondary', isDark ? '#1f1f1f' : '#fbfbfa'),
        colorBgElevated: readToken('--bg-elevated', isDark ? '#252525' : '#ffffff'),
        colorBorder: readToken('--border-color', isDark ? '#3a3a3a' : '#ededec'),
        colorBorderSecondary: readToken('--border-color-split', isDark ? '#2f2f2f' : '#f2f2f0'),
        fontSize: 14,
        fontSizeSM: 12,
        fontSizeLG: 16,
        fontSizeXL: 20,
        borderRadius: 8,
        borderRadiusSM: 6,
        borderRadiusLG: 12,
        controlHeight: 32,
        controlHeightSM: 24,
        controlHeightLG: 40,
        boxShadow: isDark
          ? '0 1px 2px rgba(0, 0, 0, 0.2)'
          : '0 1px 2px rgba(0, 0, 0, 0.04)',
        boxShadowSecondary: isDark
          ? '0 2px 8px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.15)'
          : '0 2px 8px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04)',
      },
      components: {
        Menu: {
          itemSelectedBg: readToken('--color-primary-light', isDark ? '#1e1b4b' : '#eef2ff'),
          itemSelectedColor: readToken('--color-primary', isDark ? '#818cf8' : '#6366f1'),
          itemHoverBg: isDark ? '#1e1b4b' : '#f5f3ff',
          itemHoverColor: readToken('--color-primary', isDark ? '#818cf8' : '#6366f1'),
          itemColor: readToken('--text-secondary', isDark ? '#cececd' : '#4a4a4a'),
        } as Record<string, unknown>,
        Tabs: {
          itemSelectedColor: readToken('--color-primary', isDark ? '#818cf8' : '#6366f1'),
          itemHoverColor: readToken('--color-primary-hover', isDark ? '#6366f1' : '#4f46e5'),
        } as Record<string, unknown>,
        Select: {
          colorPrimary: readToken('--color-primary', isDark ? '#818cf8' : '#6366f1'),
          colorPrimaryHover: readToken('--color-primary-hover', isDark ? '#6366f1' : '#4f46e5'),
        } as Record<string, unknown>,
        Button: { borderRadius: 8, controlHeight: 32 } as Record<string, unknown>,
        Card: { borderRadiusLG: 10 } as Record<string, unknown>,
        Input: { borderRadius: 8 } as Record<string, unknown>,
        Modal: { borderRadiusLG: 12 } as Record<string, unknown>,
      },
    }
  })

  return {
    mode,
    resolvedMode,
    antThemeConfig,
    setMode,
    toggle,
  }
})
