import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import {
  getLLMProviders,
  getLLMConfig,
  updateLLMConfig,
  testLLM,
  type LLMProviderInfo,
  type LLMConfig,
  type LLMConfigUpdate,
  type LLMTestResult
} from '@/api/llm'

export const useLLMStore = defineStore('llm', () => {
  const providers = ref<LLMProviderInfo[]>([])
  const currentConfig = ref<LLMConfig>({
    provider: '',
    config: {}
  })
  const loading = ref(false)
  const providersLoading = ref(false)
  const testResult = ref<LLMTestResult | null>(null)
  const testLoading = ref(false)

  const currentProvider = computed(() => {
    return providers.value.find(p => p.name === currentConfig.value.provider)
  })

  const configSchema = computed(() => {
    return currentProvider.value?.config_schema || { properties: {} }
  })

  const loadProviders = async () => {
    providersLoading.value = true
    try {
      const res: any = await getLLMProviders()
      providers.value = res?.providers || res?.data?.providers || []
    } catch (error) {
      console.error('Failed to load LLM providers:', error)
      throw error
    } finally {
      providersLoading.value = false
    }
  }

  const loadConfig = async () => {
    loading.value = true
    try {
      const res: any = await getLLMConfig()
      const config = res?.data || res
      if (config) {
        currentConfig.value = {
          provider: config.provider || '',
          config: config.config || {},
          updated_at: config.updated_at
        }
      }
    } catch (error) {
      console.error('Failed to load LLM config:', error)
      throw error
    } finally {
      loading.value = false
    }
  }

  const saveCurrentConfig = async () => {
    loading.value = true
    try {
      const updateData: LLMConfigUpdate = {
        provider: currentConfig.value.provider,
        config: currentConfig.value.config
      }
      await updateLLMConfig(updateData)
    } catch (error) {
      console.error('Failed to save LLM config:', error)
      throw error
    } finally {
      loading.value = false
    }
  }

  const runTest = async (testPrompt?: string): Promise<LLMTestResult> => {
    testLoading.value = true
    testResult.value = null
    try {
      const result = await testLLM({
        test_prompt: testPrompt,
        provider: currentConfig.value.provider,
        config: currentConfig.value.config
      })
      testResult.value = result
      return result
    } catch (error: any) {
      const errorResult: LLMTestResult = {
        success: false,
        error: error?.message || '连接测试失败'
      }
      testResult.value = errorResult
      return errorResult
    } finally {
      testLoading.value = false
    }
  }

  const setProvider = (providerName: string) => {
    currentConfig.value.provider = providerName
    const provider = providers.value.find(p => p.name === providerName)
    if (provider?.config_schema?.properties) {
      const newConfig: Record<string, any> = {}
      Object.entries(provider.config_schema.properties).forEach(([key, field]: [string, any]) => {
        if (field.default !== undefined) {
          newConfig[key] = field.default
        } else {
          switch (field.type) {
            case 'string':
              newConfig[key] = ''
              break
            case 'integer':
            case 'number':
              newConfig[key] = field.minimum ?? 0
              break
            case 'boolean':
              newConfig[key] = false
              break
            default:
              newConfig[key] = null
          }
        }
      })
      currentConfig.value.config = newConfig
    } else {
      currentConfig.value.config = {}
    }
  }

  const updateConfigValue = (key: string, value: any) => {
    currentConfig.value.config[key] = value
  }

  const clearTestResult = () => {
    testResult.value = null
  }

  return {
    providers,
    currentConfig,
    loading,
    providersLoading,
    testResult,
    testLoading,
    currentProvider,
    configSchema,
    loadProviders,
    loadConfig,
    saveCurrentConfig,
    runTest,
    setProvider,
    updateConfigValue,
    clearTestResult
  }
})
