import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react'
import type { AppConfig } from '../types'
import { defaultConfig } from '../types'
import { saveConfig } from '../utils/storage'
import { S2AClient } from '../api/s2a'

interface ConfigContextValue {
  config: AppConfig
  updateConfig: (updates: Partial<AppConfig>) => void
  updateS2AConfig: (updates: Partial<AppConfig['s2a']>) => void
  updatePoolingConfig: (updates: Partial<AppConfig['pooling']>) => void
  updateCheckConfig: (updates: Partial<AppConfig['check']>) => void
  updateEmailConfig: (updates: Partial<AppConfig['email']>) => void
  isConnected: boolean
  testConnection: () => Promise<boolean>
  s2aClient: S2AClient | null
  refreshConfig: () => Promise<void>
  siteName: string
}

const ConfigContext = createContext<ConfigContextValue | null>(null)

export function ConfigProvider({ children }: { children: ReactNode }) {
  const [config, setConfig] = useState<AppConfig>(defaultConfig)
  const [isConnected, setIsConnected] = useState(false)
  const [s2aClient, setS2aClient] = useState<S2AClient | null>(null)
  const [siteName, setSiteName] = useState('Codex Pool')

  // Load config from server on mount
  const refreshConfig = useCallback(async () => {
    try {
      const res = await fetch('/api/config')
      const data = await res.json()
      if (data.code === 0 && data.data) {
        const serverConfig = data.data
        setConfig(prev => ({
          ...prev,
          s2a: {
            ...prev.s2a,
            apiBase: serverConfig.s2a_api_base || '',
            adminKey: serverConfig.s2a_admin_key || '',
          },
          pooling: {
            ...prev.pooling,
            concurrency: serverConfig.concurrency || 2,
            priority: serverConfig.priority || 0,
            groupIds: serverConfig.group_ids || [],
          },
        }))
        // 更新站点名称
        if (serverConfig.site_name) {
          setSiteName(serverConfig.site_name)
        }
      }
    } catch (error) {
      console.error('Failed to load config from server:', error)
    }
  }, [])

  useEffect(() => {
    refreshConfig()
  }, [refreshConfig])

  // Update S2A client when config changes and auto-test connection
  useEffect(() => {
    if (config.s2a.apiBase && config.s2a.adminKey) {
      const client = new S2AClient({
        baseUrl: config.s2a.apiBase,
        apiKey: config.s2a.adminKey,
      })
      setS2aClient(client)

      // 自动测试连接
      fetch('/api/s2a/test')
        .then(res => res.json())
        .then(data => {
          setIsConnected(data.code === 0)
        })
        .catch(() => {
          setIsConnected(false)
        })
    } else {
      setS2aClient(null)
      setIsConnected(false)
    }
  }, [config.s2a.apiBase, config.s2a.adminKey])

  const updateConfig = useCallback((updates: Partial<AppConfig>) => {
    setConfig((prev) => {
      const newConfig = { ...prev, ...updates }
      saveConfig(newConfig)
      return newConfig
    })
  }, [])

  const updateS2AConfig = useCallback((updates: Partial<AppConfig['s2a']>) => {
    setConfig((prev) => {
      const newConfig = {
        ...prev,
        s2a: { ...prev.s2a, ...updates },
      }
      saveConfig(newConfig)
      return newConfig
    })
  }, [])

  const updatePoolingConfig = useCallback((updates: Partial<AppConfig['pooling']>) => {
    setConfig((prev) => {
      const newConfig = {
        ...prev,
        pooling: { ...prev.pooling, ...updates },
      }
      saveConfig(newConfig)
      return newConfig
    })
  }, [])

  const updateCheckConfig = useCallback((updates: Partial<AppConfig['check']>) => {
    setConfig((prev) => {
      const newConfig = {
        ...prev,
        check: { ...prev.check, ...updates },
      }
      saveConfig(newConfig)
      return newConfig
    })
  }, [])

  const updateEmailConfig = useCallback((updates: Partial<AppConfig['email']>) => {
    setConfig((prev) => {
      const newConfig = {
        ...prev,
        email: { ...prev.email, ...updates },
      }
      saveConfig(newConfig)
      return newConfig
    })
  }, [])

  const testConnection = useCallback(async (): Promise<boolean> => {
    try {
      // 使用后端代理 API 来测试 S2A 连接（避免 CORS 问题）
      const res = await fetch('/api/s2a/test')
      const data = await res.json()
      const connected = data.code === 0
      setIsConnected(connected)
      return connected
    } catch {
      setIsConnected(false)
      return false
    }
  }, [])

  return (
    <ConfigContext.Provider
      value={{
        config,
        updateConfig,
        updateS2AConfig,
        updatePoolingConfig,
        updateCheckConfig,
        updateEmailConfig,
        isConnected,
        testConnection,
        s2aClient,
        refreshConfig,
        siteName,
      }}
    >
      {children}
    </ConfigContext.Provider>
  )
}

export function useConfigContext(): ConfigContextValue {
  const context = useContext(ConfigContext)
  if (!context) {
    throw new Error('useConfigContext must be used within a ConfigProvider')
  }
  return context
}
