import { useState, useEffect, useRef, useCallback, useMemo } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { ScrollArea } from '@/components/ui/scroll-area'

import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from '@/components/ui/alert-dialog'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from '@/components/ui/command'
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover'
import { Checkbox } from '@/components/ui/checkbox'
import { Badge } from '@/components/ui/badge'
import { Plus, Pencil, Trash2, Save, Eye, EyeOff, Copy, Search, Info, Power, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, Check, ChevronsUpDown, Zap, Loader2, CheckCircle2, XCircle, AlertCircle } from 'lucide-react'
import { getModelConfig, updateModelConfig, updateModelConfigSection, testProviderConnection, type TestConnectionResult } from '@/lib/config-api'
import { useToast } from '@/hooks/use-toast'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { HelpTooltip } from '@/components/ui/help-tooltip'
import { useTour } from '@/components/tour'
import { MODEL_ASSIGNMENT_TOUR_ID, modelAssignmentTourSteps, STEP_ROUTE_MAP } from '@/components/tour/tours/model-assignment-tour'
import { useNavigate } from '@tanstack/react-router'
import { RestartOverlay } from '@/components/restart-overlay'
import { RestartProvider, useRestart } from '@/lib/restart-context'
import { PROVIDER_TEMPLATES } from './providerTemplates'
import type { APIProvider, DeleteConfirmState, FormErrors } from './modelProvider/types'
import { cleanProviderData, validateProvider } from './modelProvider/utils'

// 主导出组件：包装 RestartProvider
export function ModelProviderConfigPage() {
  return (
    <RestartProvider>
      <ModelProviderConfigPageContent />
    </RestartProvider>
  )
}

// 内部实现组件
function ModelProviderConfigPageContent() {
  const [providers, setProviders] = useState<APIProvider[]>([])
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [autoSaving, setAutoSaving] = useState(false)
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false)
  const [editDialogOpen, setEditDialogOpen] = useState(false)
  const [editingProvider, setEditingProvider] = useState<APIProvider | null>(null)
  const [editingIndex, setEditingIndex] = useState<number | null>(null)
  const [selectedTemplate, setSelectedTemplate] = useState<string>('custom')
  const [templateComboboxOpen, setTemplateComboboxOpen] = useState(false)
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false)
  const [deletingIndex, setDeletingIndex] = useState<number | null>(null)
  const [showApiKey, setShowApiKey] = useState(false)
  const [searchQuery, setSearchQuery] = useState('')
  const [selectedProviders, setSelectedProviders] = useState<Set<number>>(new Set())
  const [batchDeleteDialogOpen, setBatchDeleteDialogOpen] = useState(false)
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(20)
  const [jumpToPage, setJumpToPage] = useState('')
  
  // 删除提供商确认对话框状态（合并为单个对象以减少状态变量）
  const [deleteConfirmState, setDeleteConfirmState] = useState<DeleteConfirmState>({
    isOpen: false,
    providersToDelete: [],
    affectedModels: [],
    pendingProviders: [],
    context: 'auto',
    oldProviders: [],
  })
  
  // 表单验证错误状态
  const [formErrors, setFormErrors] = useState<FormErrors>({})
  
  // 测试连接状态
  const [testingProviders, setTestingProviders] = useState<Set<string>>(new Set())
  const [testResults, setTestResults] = useState<Map<string, TestConnectionResult>>(new Map())
  
  const { toast } = useToast()
  const navigate = useNavigate()
  const { state: tourState, goToStep, registerTour } = useTour()
  const { triggerRestart, isRestarting } = useRestart()
  
  // 用于防抖的定时器
  const autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  const initialLoadRef = useRef(true)

  // 注册 Tour（确保跨页导航时 Tour 仍然可用）
  useEffect(() => {
    registerTour(MODEL_ASSIGNMENT_TOUR_ID, modelAssignmentTourSteps)
  }, [registerTour])

  // 监听 Tour 步骤变化，处理页面导航
  useEffect(() => {
    if (tourState.activeTourId === MODEL_ASSIGNMENT_TOUR_ID && tourState.isRunning) {
      const targetRoute = STEP_ROUTE_MAP[tourState.stepIndex]
      if (targetRoute && !window.location.pathname.endsWith(targetRoute.replace('/config/', ''))) {
        navigate({ to: targetRoute })
      }
    }
  }, [tourState.stepIndex, tourState.activeTourId, tourState.isRunning, navigate])

  // 监听 Tour 步骤变化，处理弹窗的打开和关闭
  // 提供商弹窗步骤: 3-9 (index 3-9)，弹窗外步骤: 0-2 (index 0-2) 和 10+ (index 10+)
  const prevTourStepRef = useRef(tourState.stepIndex)
  useEffect(() => {
    if (tourState.activeTourId === MODEL_ASSIGNMENT_TOUR_ID && tourState.isRunning) {
      const prevStep = prevTourStepRef.current
      const currentStep = tourState.stepIndex
      
      // 如果从弹窗内步骤 (3-9) 回退到弹窗外步骤 (0-2)，关闭弹窗
      if (prevStep >= 3 && prevStep <= 9 && currentStep < 3) {
        setEditDialogOpen(false)
      }
      
      // 如果从弹窗外步骤 (10+) 回退到弹窗内步骤 (3-9)，重新打开弹窗
      // 这处理了从模型管理页面第 11 步点击"上一步"回到提供商弹窗的情况
      if (prevStep >= 10 && currentStep >= 3 && currentStep <= 9) {
        // 需要打开空白弹窗以便 Tour 可以定位到弹窗内的元素
        setFormErrors({})
        setSelectedTemplate('custom')
        setEditingProvider({
          name: '',
          base_url: '',
          api_key: '',
          client_type: 'openai',
          max_retry: 2,
          timeout: 30,
          retry_interval: 10,
        })
        setEditingIndex(null)
        setShowApiKey(false)
        setEditDialogOpen(true)
      }
      
      prevTourStepRef.current = currentStep
    }
  }, [tourState.stepIndex, tourState.activeTourId, tourState.isRunning])

  // 处理 Tour 中需要用户点击才能继续的步骤
  useEffect(() => {
    if (tourState.activeTourId !== MODEL_ASSIGNMENT_TOUR_ID || !tourState.isRunning) return

    const handleTourClick = (e: MouseEvent) => {
      const target = e.target as HTMLElement
      const currentStep = tourState.stepIndex

      // Step 3 (index 2): 点击添加提供商按钮
      if (currentStep === 2 && target.closest('[data-tour="add-provider-button"]')) {
        setTimeout(() => goToStep(3), 300)
      }
      // Step 10 (index 9): 点击取消按钮（关闭提供商弹窗）
      else if (currentStep === 9 && target.closest('[data-tour="provider-cancel-button"]')) {
        setTimeout(() => goToStep(10), 300)
      }
    }

    document.addEventListener('click', handleTourClick, true)
    return () => document.removeEventListener('click', handleTourClick, true)
  }, [tourState, goToStep])

  // 加载配置
  useEffect(() => {
    loadConfig()
  }, [])

  const loadConfig = async () => {
    try {
      setLoading(true)
      const result = await getModelConfig()
      if (!result.success) {
        toast({
          title: '加载失败',
          description: result.error,
          variant: 'destructive',
        })
        setLoading(false)
        return
      }
      const config = result.data
      setProviders((config.api_providers as APIProvider[]) || [])
      setHasUnsavedChanges(false)
      initialLoadRef.current = false
    } catch (error) {
      console.error('加载配置失败:', error)
    } finally {
      setLoading(false)
    }
  }

  // 重启麦麦
  const handleRestart = async () => {
    await triggerRestart()
  }

  // 保存并重启
  const handleSaveAndRestart = async () => {
    try {
      setSaving(true)
      if (autoSaveTimerRef.current) {
        clearTimeout(autoSaveTimerRef.current)
      }
      
      // 清理 providers 数据：将 null 值转换为默认值
      const cleanedProviders = providers.map(provider => ({
        ...provider,
        max_retry: provider.max_retry ?? 2,
        timeout: provider.timeout ?? 30,
        retry_interval: provider.retry_interval ?? 10,
      }))
      
      // 检查删除提供商的影响
      const { shouldProceed } = await checkDeleteProviderImpact(cleanedProviders, 'restart')
      if (!shouldProceed) {
        // 需要用户确认，等待确认对话框
        setSaving(false)
        return
      }
      
      const resultGet = await getModelConfig()
      if (!resultGet.success) {
        toast({
          title: '保存失败',
          description: resultGet.error,
          variant: 'destructive',
        })
        setSaving(false)
        return
      }
      const config = resultGet.data
      
      // 获取所有有效的 provider 名称
      const validProviderNames = new Set(cleanedProviders.map(p => p.name))
      
      // 过滤掉引用已删除 provider 的模型
      const originalModels = (config.models as any[]) || []
      const filteredModels = originalModels.filter((model: any) => {
        return validProviderNames.has(model.api_provider)
      })
      
      config.api_providers = cleanedProviders
      config.models = filteredModels
      
      const resultUpdate = await updateModelConfig(config)
      if (!resultUpdate.success) {
        toast({
          title: '保存失败',
          description: resultUpdate.error,
          variant: 'destructive',
        })
        setSaving(false)
        return
      }
      setHasUnsavedChanges(false)
      toast({
        title: '保存成功',
        description: '正在重启麦麦...',
      })
      await handleRestart()
    } catch (error) {
      console.error('保存配置失败:', error)
      toast({
        title: '保存失败',
        description: (error as Error).message,
        variant: 'destructive',
      })
      setSaving(false)
    }
  }

  // 检查删除提供商的影响
  const checkDeleteProviderImpact = useCallback(async (
    newProviders: APIProvider[], 
    context: 'auto' | 'manual' | 'restart' = 'auto'
  ) => {
    try {
      const result = await getModelConfig()
      if (!result.success) {
        console.error('加载配置失败:', result.error)
        return { shouldProceed: true, providers: newProviders }
      }
      const config = result.data
      const oldProviderNames = new Set(providers.map(p => p.name))
      const newProviderNames = new Set(newProviders.map(p => p.name))
      
      // 找出被删除的提供商
      const deletedProviders = Array.from(oldProviderNames).filter(
        name => !newProviderNames.has(name)
      )
      
      if (deletedProviders.length === 0) {
        // 没有删除提供商，直接保存
        return { shouldProceed: true, providers: newProviders }
      }
      
      // 检查受影响的模型
      const models = (config.models as any[]) || []
      const affected = models.filter((m: any) => 
        deletedProviders.includes(m.api_provider)
      )
      
      if (affected.length === 0) {
        // 没有受影响的模型，直接删除
        return { shouldProceed: true, providers: newProviders }
      }
      
      // 有受影响的模型，需要用户确认
      setDeleteConfirmState({
        isOpen: true,
        providersToDelete: deletedProviders,
        affectedModels: affected,
        pendingProviders: newProviders,
        context,
        oldProviders: [...providers],
      })
      
      return { shouldProceed: false, providers: newProviders }
    } catch (error) {
      console.error('检查删除影响失败:', error)
      return { shouldProceed: true, providers: newProviders }
    }
  }, [providers])
  
  // 确认删除提供商及其关联的模型
  const handleConfirmDeleteProvider = async () => {
    try {
      const savingFlag = deleteConfirmState.context === 'auto' ? setAutoSaving : setSaving
      savingFlag(true)
      
      setDeleteConfirmState(prev => ({ ...prev, isOpen: false }))
      
      const resultGet = await getModelConfig()
      if (!resultGet.success) {
        toast({
          title: '加载失败',
          description: resultGet.error,
          variant: 'destructive',
        })
        savingFlag(false)
        return
      }
      const config = resultGet.data
      
      // 清理 providers 数据
      const cleanedProviders = deleteConfirmState.pendingProviders.map(cleanProviderData)
      
      // 获取有效的 provider 名称
      const validProviderNames = new Set(cleanedProviders.map(p => p.name))
      
      // 过滤掉引用已删除 provider 的模型
      const originalModels = (config.models as any[]) || []
      const filteredModels = originalModels.filter((model: any) => {
        return validProviderNames.has(model.api_provider)
      })
      
      // 获取被削除的模型名称
      const deletedModelNames = new Set(
        deleteConfirmState.affectedModels.map((m: any) => m.name)
      )
      
      // 从任务配置中移除这些模型
      const modelTaskConfig = config.model_task_config as any
      if (modelTaskConfig) {
        Object.keys(modelTaskConfig).forEach(taskName => {
          const task = modelTaskConfig[taskName]
          if (task && Array.isArray(task.model_list)) {
            task.model_list = task.model_list.filter(
              (modelName: string) => !deletedModelNames.has(modelName)
            )
          }
        })
      }
      
      // 更新配置
      config.api_providers = cleanedProviders
      config.models = filteredModels
      config.model_task_config = modelTaskConfig
      
      const resultUpdate = await updateModelConfig(config)
      if (!resultUpdate.success) {
        toast({
          title: '保存失败',
          description: resultUpdate.error,
          variant: 'destructive',
        })
        savingFlag(false)
        return
      }
      
      // 更新本地状态
      setProviders(deleteConfirmState.pendingProviders)
      setHasUnsavedChanges(false)
      
      toast({
        title: '删除成功',
        description: `已删除 ${deleteConfirmState.providersToDelete.length} 个提供商和 ${deleteConfirmState.affectedModels.length} 个关联模型`,
      })
      
      // 清理状态
      setDeleteConfirmState({
        isOpen: false,
        providersToDelete: [],
        affectedModels: [],
        pendingProviders: [],
        context: 'auto',
        oldProviders: [],
      })
      setSelectedProviders(new Set()) // 清除选中状态（批量删除时）
      
      // 根据上下文执行后续操作
      if (deleteConfirmState.context === 'restart') {
        // 如果是保存并重启，继续执行重启流程
        await handleRestart()
      }
    } catch (error) {
      console.error('删除失败:', error)
      toast({
        title: '删除失败',
        description: (error as Error).message,
        variant: 'destructive',
      })
    } finally {
      if (deleteConfirmState.context === 'auto') {
        setAutoSaving(false)
      } else {
        setSaving(false)
      }
    }
  }
  
  // 取消删除提供商
  const handleCancelDeleteProvider = () => {
    // 恢复到删除前的 providers 状态
    if (deleteConfirmState.oldProviders.length > 0) {
      setProviders(deleteConfirmState.oldProviders)
    }
    // 清理状态
    setDeleteConfirmState({
      isOpen: false,
      providersToDelete: [],
      affectedModels: [],
      pendingProviders: [],
      context: 'auto',
      oldProviders: [],
    })
    setHasUnsavedChanges(false)
  }
  
  // 自动保存函数（使用增量 API）
  const autoSaveProviders = useCallback(async (newProviders: APIProvider[]) => {
    if (initialLoadRef.current) return // 初始加载时不自动保存
    
    // 检查删除影响
    const { shouldProceed } = await checkDeleteProviderImpact(newProviders, 'auto')
    
    if (!shouldProceed) {
      // 需要用户确认，对话框已打开
      setHasUnsavedChanges(true)
      return
    }
    
    try {
      setAutoSaving(true)
      // 清理 providers 数据：将 null 值转换为默认值
      const cleanedProviders = newProviders.map(cleanProviderData)
      const result = await updateModelConfigSection('api_providers', cleanedProviders)
      if (!result.success) {
        console.error('自动保存失败:', result.error)
        toast({
          title: '自动保存失败',
          description: result.error,
          variant: 'destructive',
        })
        setHasUnsavedChanges(true)
        return
      }
      setHasUnsavedChanges(false)
    } catch (error) {
      console.error('自动保存失败:', error)
      toast({
        title: '自动保存失败',
        description: (error as Error).message,
        variant: 'destructive',
      })
      setHasUnsavedChanges(true)
    } finally {
      setAutoSaving(false)
    }
  }, [providers, checkDeleteProviderImpact])

  // 监听 providers 变化，触发自动保存（带防抖）
  useEffect(() => {
    if (initialLoadRef.current) return

    setHasUnsavedChanges(true)

    // 清除之前的定时器
    if (autoSaveTimerRef.current) {
      clearTimeout(autoSaveTimerRef.current)
    }

    // 设置新的定时器（2秒后自动保存）
    autoSaveTimerRef.current = setTimeout(() => {
      autoSaveProviders(providers)
    }, 2000)

    // 清理函数
    return () => {
      if (autoSaveTimerRef.current) {
        clearTimeout(autoSaveTimerRef.current)
      }
    }
  }, [providers, autoSaveProviders])

  // 保存配置（手动保存，保存完整配置）
  const saveConfig = async () => {
    try {
      setSaving(true)
      
      // 先取消自动保存定时器
      if (autoSaveTimerRef.current) {
        clearTimeout(autoSaveTimerRef.current)
      }

      // 清理 providers 数据：将 null 值转换为默认值
      const cleanedProviders = providers.map(cleanProviderData)
      
      // 检查删除提供商的影响
      const { shouldProceed } = await checkDeleteProviderImpact(cleanedProviders, 'manual')
      if (!shouldProceed) {
        // 需要用户确认，等待确认对话框
        setSaving(false)
        return
      }

      const resultGet = await getModelConfig()
      if (!resultGet.success) {
        toast({
          title: '保存失败',
          description: resultGet.error,
          variant: 'destructive',
        })
        setSaving(false)
        return
      }
      const config = resultGet.data
      
      // 获取所有有效的 provider 名称
      const validProviderNames = new Set(cleanedProviders.map(p => p.name))
      
      // 过滤掉引用已删除 provider 的模型
      const originalModels = (config.models as any[]) || []
      const filteredModels = originalModels.filter((model: any) => {
        const isValid = validProviderNames.has(model.api_provider)
        if (!isValid) {
          console.warn(`模型 "${model.name}" 引用了已删除的提供商 "${model.api_provider}"、将被移除`)
        }
        return isValid
      })
      
      // 如果有模型被移除、显示警告
      if (originalModels.length !== filteredModels.length) {
        const removedCount = originalModels.length - filteredModels.length
        toast({
          title: '注意',
          description: `已自动移除 ${removedCount} 个引用已删除提供商的模型`,
          variant: 'default',
        })
      }
      
      console.log('发送的 providers 数据:', cleanedProviders)
      config.api_providers = cleanedProviders
      config.models = filteredModels
      console.log('完整配置数据:', config)
      
      const resultUpdate = await updateModelConfig(config)
      if (!resultUpdate.success) {
        toast({
          title: '保存失败',
          description: resultUpdate.error,
          variant: 'destructive',
        })
        setSaving(false)
        return
      }
      setHasUnsavedChanges(false)
      toast({
        title: '保存成功',
        description: '模型提供商配置已保存',
      })
    } catch (error) {
      console.error('保存配置失败:', error)
      toast({
        title: '保存失败',
        description: (error as Error).message,
        variant: 'destructive',
      })
    } finally {
      setSaving(false)
    }
  }

  // 打开编辑对话框
  const openEditDialog = (provider: APIProvider | null, index: number | null) => {
    // 清除表单验证错误
    setFormErrors({})
    
    if (provider) {
      // 编辑现有提供商 - 检测匹配的模板
      const matchedTemplate = PROVIDER_TEMPLATES.find(
        t => t.base_url === provider.base_url && t.client_type === provider.client_type
      )
      setSelectedTemplate(matchedTemplate?.id || 'custom')
      setEditingProvider(provider)
    } else {
      // 新建提供商 - 默认使用自定义模板
      setSelectedTemplate('custom')
      setEditingProvider({
        name: '',
        base_url: '',
        api_key: '',
        client_type: 'openai',
        max_retry: 2,
        timeout: 30,
        retry_interval: 10,
      })
    }
    setEditingIndex(index)
    setShowApiKey(false)
    setEditDialogOpen(true)
  }
  
  // 处理模板选择变化
  const handleTemplateChange = useCallback((templateId: string) => {
    setSelectedTemplate(templateId)
    setTemplateComboboxOpen(false)
    const template = PROVIDER_TEMPLATES.find(t => t.id === templateId)
    if (template && template.id !== 'custom') {
      // 应用模板配置
      setEditingProvider(prev => ({
        ...prev!,
        name: template.name,
        base_url: template.base_url,
        client_type: template.client_type,
      }))
    } else if (template?.id === 'custom') {
      // 切换到自定义模板 - 清空URL和客户端类型(保留其他字段)
      setEditingProvider(prev => ({
        ...prev!,
        name: '',
        base_url: '',
        client_type: 'openai',
      }))
    }
  }, [])
  
  // 判断当前是否使用模板(非自定义)
  const isUsingTemplate = useMemo(() => {
    return selectedTemplate !== 'custom'
  }, [selectedTemplate])

  // 复制 API Key
  const copyApiKey = useCallback(async () => {
    if (!editingProvider?.api_key) return
    try {
      await navigator.clipboard.writeText(editingProvider.api_key)
      toast({
        title: '复制成功',
        description: 'API Key 已复制到剪贴板',
      })
    } catch {
      toast({
        title: '复制失败',
        description: '无法访问剪贴板',
        variant: 'destructive',
      })
    }
  }, [editingProvider?.api_key, toast])

  // 保存编辑
  const handleSaveEdit = () => {
    if (!editingProvider) return

    // 验证必填项（传入现有提供商列表和当前编辑索引用于重复检查）
    const { isValid, errors } = validateProvider(editingProvider, providers, editingIndex)

    if (!isValid) {
      setFormErrors(errors)
      return
    }

    // 清除错误状态
    setFormErrors({})

    // 填充空值的默认值
    const providerToSave = cleanProviderData(editingProvider)

    if (editingIndex !== null) {
      // 更新现有提供商
      const newProviders = [...providers]
      newProviders[editingIndex] = providerToSave
      setProviders(newProviders)
    } else {
      // 添加新提供商
      setProviders([...providers, providerToSave])
    }

    setEditDialogOpen(false)
    setEditingProvider(null)
    setEditingIndex(null)
  }

  // 处理编辑对话框关闭
  const handleEditDialogClose = (open: boolean) => {
    if (!open && editingProvider) {
      // 关闭时填充默认值
      const updatedProvider = {
        ...editingProvider,
        max_retry: editingProvider.max_retry ?? 2,
        timeout: editingProvider.timeout ?? 30,
        retry_interval: editingProvider.retry_interval ?? 10,
      }
      setEditingProvider(updatedProvider)
    }
    setEditDialogOpen(open)
  }

  // 打开删除确认对话框
  const openDeleteDialog = (index: number) => {
    setDeletingIndex(index)
    setDeleteDialogOpen(true)
  }

  // 确认删除提供商
  const handleConfirmDelete = async () => {
    if (deletingIndex !== null) {
      const newProviders = providers.filter((_, i) => i !== deletingIndex)
      
      // 检查删除影响
      const { shouldProceed } = await checkDeleteProviderImpact(newProviders, 'manual')
      
      if (shouldProceed) {
        // 没有影响，直接删除
        setProviders(newProviders)
        toast({
          title: '删除成功',
          description: '提供商已从列表中移除',
        })
      }
      // 如果 shouldProceed = false，对话框会自动打开，等待用户确认
    }
    setDeleteDialogOpen(false)
    setDeletingIndex(null)
  }

  // 切换单个提供商选择
  const toggleProviderSelection = (index: number) => {
    const newSelected = new Set(selectedProviders)
    if (newSelected.has(index)) {
      newSelected.delete(index)
    } else {
      newSelected.add(index)
    }
    setSelectedProviders(newSelected)
  }

  // 全选/取消全选
  const toggleSelectAll = () => {
    if (selectedProviders.size === filteredProviders.length) {
      setSelectedProviders(new Set())
    } else {
      const allIndices = filteredProviders.map((_, idx) => 
        providers.findIndex(p => p === filteredProviders[idx])
      )
      setSelectedProviders(new Set(allIndices))
    }
  }

  // 打开批量删除确认对话框
  const openBatchDeleteDialog = () => {
    if (selectedProviders.size === 0) {
      toast({
        title: '提示',
        description: '请先选择要删除的提供商',
        variant: 'default',
      })
      return
    }
    setBatchDeleteDialogOpen(true)
  }

  // 确认批量删除
  const handleConfirmBatchDelete = async () => {
    const newProviders = providers.filter((_, index) => !selectedProviders.has(index))
    
    // 检查删除影响
    const { shouldProceed } = await checkDeleteProviderImpact(newProviders, 'manual')
    
    if (shouldProceed) {
      // 没有影响，直接删除
      setProviders(newProviders)
      setSelectedProviders(new Set())
      toast({
        title: '批量删除成功',
        description: `已删除 ${selectedProviders.size} 个提供商`,
      })
    }
    // 如果 shouldProceed = false，对话框会自动打开，等待用户确认
    
    setBatchDeleteDialogOpen(false)
  }

  // 过滤提供商列表（使用 useMemo 优化性能）
  const filteredProviders = useMemo(() => {
    if (!searchQuery) return providers
    const query = searchQuery.toLowerCase()
    return providers.filter((provider) => (
      provider.name.toLowerCase().includes(query) ||
      provider.base_url.toLowerCase().includes(query) ||
      provider.client_type.toLowerCase().includes(query)
    ))
  }, [providers, searchQuery])

  // 分页逻辑（使用 useMemo 优化性能）
  const { totalPages, paginatedProviders } = useMemo(() => {
    const total = Math.ceil(filteredProviders.length / pageSize)
    const paginated = filteredProviders.slice(
      (page - 1) * pageSize,
      page * pageSize
    )
    return { totalPages: total, paginatedProviders: paginated }
  }, [filteredProviders, page, pageSize])

  // 页码跳转
  const handleJumpToPage = useCallback(() => {
    const targetPage = parseInt(jumpToPage)
    if (targetPage >= 1 && targetPage <= totalPages) {
      setPage(targetPage)
      setJumpToPage('')
    }
  }, [jumpToPage, totalPages])

  // 测试单个提供商连接
  const handleTestConnection = async (providerName: string) => {
    // 标记正在测试
    setTestingProviders(prev => new Set(prev).add(providerName))
    
    try {
      const result = await testProviderConnection(providerName)
      if (!result.success) {
        toast({
          title: '测试失败',
          description: result.error,
          variant: 'destructive',
        })
        return
      }
      const testResult = result.data
      setTestResults(prev => new Map(prev).set(providerName, testResult))

      // 显示结果 toast
      if (testResult.network_ok) {
        if (testResult.api_key_valid === true) {
          toast({
            title: '连接正常',
            description: `${providerName} 网络连接正常、API Key 有效 (${testResult.latency_ms}ms)`,
          })
        } else if (testResult.api_key_valid === false) {
          toast({
            title: '连接正常但 Key 无效',
            description: `${providerName} 网络连接正常、但 API Key 无效或已过期`,
            variant: 'destructive',
          })
        } else {
          toast({
            title: '网络连接正常',
            description: `${providerName} 可以访问 (${testResult.latency_ms}ms)`,
          })
        }
      } else {
        toast({
          title: '连接失败',
          description: testResult.error || '无法连接到提供商',
          variant: 'destructive',
        })
      }
    } catch (error) {
      toast({
        title: '测试失败',
        description: (error as Error).message,
        variant: 'destructive',
      })
    } finally {
      setTestingProviders(prev => {
        const newSet = new Set(prev)
        newSet.delete(providerName)
        return newSet
      })
    }
  }

  // 批量测试所有提供商
  const handleTestAllConnections = async () => {
    for (const provider of providers) {
      await handleTestConnection(provider.name)
    }
  }

  // 渲染测试状态指示器
  const renderTestStatus = (providerName: string) => {
    const isTesting = testingProviders.has(providerName)
    const result = testResults.get(providerName)
    
    if (isTesting) {
      return (
        <Badge variant="secondary" className="gap-1">
          <Loader2 className="h-3 w-3 animate-spin" />
          测试中
        </Badge>
      )
    }
    
    if (!result) return null
    
    if (result.network_ok) {
      if (result.api_key_valid === true) {
        return (
          <Badge className="gap-1 bg-green-600 hover:bg-green-700">
            <CheckCircle2 className="h-3 w-3" />
            正常
          </Badge>
        )
      } else if (result.api_key_valid === false) {
        return (
          <Badge variant="destructive" className="gap-1">
            <AlertCircle className="h-3 w-3" />
            Key无效
          </Badge>
        )
      } else {
        return (
          <Badge className="gap-1 bg-blue-600 hover:bg-blue-700">
            <CheckCircle2 className="h-3 w-3" />
            可访问
          </Badge>
        )
      }
    } else {
      return (
        <Badge variant="destructive" className="gap-1">
          <XCircle className="h-3 w-3" />
          离线
        </Badge>
      )
    }
  }

  if (loading) {
    return (
      <div className="space-y-4 sm:space-y-6 p-4 sm:p-6">
        <div className="flex items-center justify-center h-64">
          <p className="text-muted-foreground">加载中...</p>
        </div>
      </div>
    )
  }

  return (
    <div className="space-y-4 sm:space-y-6 p-4 sm:p-6">
      {/* 页面标题 */}
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
        <div>
          <h1 className="text-2xl sm:text-3xl font-bold">AI模型厂商配置</h1>
          <p className="text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base">管理 AI 模型厂商的 API 配置</p>
        </div>
        <div className="flex flex-col sm:flex-row gap-2">
          {selectedProviders.size > 0 && (
            <Button 
              onClick={openBatchDeleteDialog} 
              size="sm" 
              variant="destructive" 
              className="w-full sm:w-auto"
            >
              <Trash2 className="mr-2 h-4 w-4" strokeWidth={2} fill="none" />
              批量删除 ({selectedProviders.size})
            </Button>
          )}
          <Button 
            onClick={handleTestAllConnections} 
            size="sm" 
            variant="outline"
            className="w-full sm:w-auto"
            disabled={providers.length === 0 || testingProviders.size > 0}
          >
            <Zap className="mr-2 h-4 w-4" />
            {testingProviders.size > 0 ? `测试中 (${testingProviders.size})` : '测试全部'}
          </Button>
          <Button onClick={() => openEditDialog(null, null)} size="sm" className="w-full sm:w-auto" data-tour="add-provider-button">
            <Plus className="mr-2 h-4 w-4" strokeWidth={2} fill="none" />
            添加提供商
          </Button>
          <Button 
            onClick={saveConfig} 
            disabled={saving || autoSaving || !hasUnsavedChanges || isRestarting} 
            size="sm" 
            variant="outline"
            className="w-full sm:w-auto sm:min-w-[120px]"
          >
            <Save className="mr-2 h-4 w-4" strokeWidth={2} fill="none" />
            {saving ? '保存中...' : autoSaving ? '自动保存中...' : hasUnsavedChanges ? '保存配置' : '已保存'}
          </Button>
          <AlertDialog>
            <AlertDialogTrigger asChild>
              <Button
                disabled={saving || autoSaving || isRestarting}
                size="sm"
                className="w-full sm:w-auto sm:min-w-[120px]"
              >
                <Power className="mr-2 h-4 w-4" />
                {isRestarting ? '重启中...' : hasUnsavedChanges ? '保存并重启' : '重启麦麦'}
              </Button>
            </AlertDialogTrigger>
            <AlertDialogContent>
              <AlertDialogHeader>
                <AlertDialogTitle>确认重启麦麦？</AlertDialogTitle>
                <AlertDialogDescription asChild>
                  <div>
                    <p>
                      {hasUnsavedChanges
                        ? '当前有未保存的配置更改。点击确认将先保存配置,然后重启麦麦使新配置生效。重启过程中麦麦将暂时离线。'
                        : '即将重启麦麦主程序。重启过程中麦麦将暂时离线,配置将在重启后生效。'
                      }
                    </p>
                  </div>
                </AlertDialogDescription>
              </AlertDialogHeader>
              <AlertDialogFooter>
                <AlertDialogCancel>取消</AlertDialogCancel>
                <AlertDialogAction onClick={hasUnsavedChanges ? handleSaveAndRestart : handleRestart}>
                  {hasUnsavedChanges ? '保存并重启' : '确认重启'}
                </AlertDialogAction>
              </AlertDialogFooter>
            </AlertDialogContent>
          </AlertDialog>
        </div>
      </div>

      {/* 重启提示 */}
      <Alert>
        <Info className="h-4 w-4" />
        <AlertDescription>
          配置更新后需要<strong>重启麦麦</strong>才能生效。你可以点击右上角的"保存并重启"按钮一键完成保存和重启。
        </AlertDescription>
      </Alert>

      <ScrollArea className="h-[calc(100vh-260px)]">
        {/* 搜索框 */}
        <div className="flex flex-col sm:flex-row items-start sm:items-center gap-2 mb-4">
          <div className="relative w-full sm:flex-1 sm:max-w-sm">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              placeholder="搜索提供商名称、URL 或类型..."
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="pl-9"
            />
          </div>
          {searchQuery && (
            <p className="text-sm text-muted-foreground whitespace-nowrap">
              找到 {filteredProviders.length} 个结果
            </p>
          )}
        </div>

        {/* 提供商列表 - 移动端卡片视图 */}
        <div className="md:hidden space-y-3">
          {filteredProviders.length === 0 ? (
            <div className="text-center text-muted-foreground py-8 rounded-lg border bg-card">
              {searchQuery ? '未找到匹配的提供商' : '暂无提供商配置，点击"添加提供商"开始配置'}
            </div>
          ) : (
            paginatedProviders.map((provider, displayIndex) => {
              const actualIndex = providers.findIndex(p => p === provider)
              return (
              <div key={displayIndex} className="rounded-lg border bg-card p-4 space-y-3">
                <div className="flex items-start justify-between gap-2">
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2 flex-wrap">
                      <h3 className="font-semibold text-base truncate">{provider.name}</h3>
                      {renderTestStatus(provider.name)}
                    </div>
                    <p className="text-xs text-muted-foreground mt-1 break-all">{provider.base_url}</p>
                  </div>
                  <div className="flex gap-1 flex-shrink-0">
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => handleTestConnection(provider.name)}
                      disabled={testingProviders.has(provider.name)}
                      title="测试连接"
                    >
                      {testingProviders.has(provider.name) ? (
                        <Loader2 className="h-4 w-4 animate-spin" />
                      ) : (
                        <Zap className="h-4 w-4" />
                      )}
                    </Button>
                    <Button
                      variant="default"
                      size="sm"
                      onClick={() => openEditDialog(provider, actualIndex)}
                    >
                      <Pencil className="h-4 w-4" strokeWidth={2} fill="none" />
                    </Button>
                    <Button
                      size="sm"
                      onClick={() => openDeleteDialog(actualIndex)}
                      className="bg-red-600 hover:bg-red-700 text-white"
                    >
                      <Trash2 className="h-4 w-4" strokeWidth={2} fill="none" />
                    </Button>
                  </div>
                </div>
                <div className="grid grid-cols-2 gap-2 text-sm">
                  <div>
                    <span className="text-muted-foreground text-xs">客户端类型</span>
                    <p className="font-medium">{provider.client_type}</p>
                  </div>
                  <div>
                    <span className="text-muted-foreground text-xs">最大重试</span>
                    <p className="font-medium">{provider.max_retry}</p>
                  </div>
                  <div>
                    <span className="text-muted-foreground text-xs">超时(秒)</span>
                    <p className="font-medium">{provider.timeout}</p>
                  </div>
                  <div>
                    <span className="text-muted-foreground text-xs">重试间隔(秒)</span>
                    <p className="font-medium">{provider.retry_interval}</p>
                  </div>
                </div>
              </div>
              )
            })
          )}
        </div>

        {/* 提供商列表 - 桌面端表格视图 */}
        <div className="hidden md:block rounded-lg border bg-card overflow-hidden">
          <div className="overflow-x-auto">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-12">
                    <Checkbox
                      checked={selectedProviders.size === filteredProviders.length && filteredProviders.length > 0}
                      onCheckedChange={toggleSelectAll}
                    />
                  </TableHead>
                  <TableHead>状态</TableHead>
                  <TableHead>名称</TableHead>
                  <TableHead>基础URL</TableHead>
                  <TableHead>客户端类型</TableHead>
                  <TableHead className="text-right">最大重试</TableHead>
                  <TableHead className="text-right">超时(秒)</TableHead>
                  <TableHead className="text-right">重试间隔(秒)</TableHead>
                  <TableHead className="text-right">操作</TableHead>
                </TableRow>
              </TableHeader>
            <TableBody>
              {paginatedProviders.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={9} className="text-center text-muted-foreground py-8">
                    {searchQuery ? '未找到匹配的提供商' : '暂无提供商配置，点击"添加提供商"开始配置'}
                  </TableCell>
                </TableRow>
              ) : (
                paginatedProviders.map((provider, displayIndex) => {
                  const actualIndex = providers.findIndex(p => p === provider)
                  return (
                    <TableRow key={displayIndex}>
                      <TableCell>
                        <Checkbox
                          checked={selectedProviders.has(actualIndex)}
                          onCheckedChange={() => toggleProviderSelection(actualIndex)}
                        />
                      </TableCell>
                      <TableCell>
                        {renderTestStatus(provider.name) || (
                          <Badge variant="outline" className="text-muted-foreground">
                            未测试
                          </Badge>
                        )}
                      </TableCell>
                      <TableCell className="font-medium">{provider.name}</TableCell>
                      <TableCell className="max-w-xs truncate" title={provider.base_url}>
                        {provider.base_url}
                      </TableCell>
                      <TableCell>{provider.client_type}</TableCell>
                      <TableCell className="text-right">{provider.max_retry}</TableCell>
                      <TableCell className="text-right">{provider.timeout}</TableCell>
                      <TableCell className="text-right">{provider.retry_interval}</TableCell>
                      <TableCell className="text-right">
                        <div className="flex justify-end gap-2">
                          <Button
                            variant="outline"
                            size="sm"
                            onClick={() => handleTestConnection(provider.name)}
                            disabled={testingProviders.has(provider.name)}
                            title="测试连接"
                          >
                            {testingProviders.has(provider.name) ? (
                              <Loader2 className="h-4 w-4 animate-spin" />
                            ) : (
                              <Zap className="h-4 w-4" />
                            )}
                          </Button>
                          <Button
                            variant="default"
                            size="sm"
                            onClick={() => openEditDialog(provider, actualIndex)}
                          >
                            <Pencil className="h-4 w-4 mr-1" strokeWidth={2} fill="none" />
                            编辑
                          </Button>
                          <Button
                            size="sm"
                            onClick={() => openDeleteDialog(actualIndex)}
                            className="bg-red-600 hover:bg-red-700 text-white"
                          >
                            <Trash2 className="h-4 w-4 mr-1" strokeWidth={2} fill="none" />
                            删除
                          </Button>
                        </div>
                      </TableCell>
                    </TableRow>
                  )
                })
              )}
            </TableBody>
          </Table>
          </div>
        </div>

        {/* 分页 - 增强版 */}
        {filteredProviders.length > 0 && (
          <div className="flex flex-col sm:flex-row items-center justify-between gap-4 mt-4">
            <div className="flex items-center gap-2">
              <Label htmlFor="page-size-provider" className="text-sm whitespace-nowrap">每页显示</Label>
              <Select
                value={pageSize.toString()}
                onValueChange={(value) => {
                  setPageSize(parseInt(value))
                  setPage(1)
                  setSelectedProviders(new Set())
                }}
              >
                <SelectTrigger id="page-size-provider" className="w-20">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="10">10</SelectItem>
                  <SelectItem value="20">20</SelectItem>
                  <SelectItem value="50">50</SelectItem>
                  <SelectItem value="100">100</SelectItem>
                </SelectContent>
              </Select>
              <span className="text-sm text-muted-foreground">
                显示 {(page - 1) * pageSize + 1} 到{' '}
                {Math.min(page * pageSize, filteredProviders.length)} 条，共 {filteredProviders.length} 条
              </span>
            </div>
            <div className="flex items-center gap-2">
              <Button
                variant="outline"
                size="sm"
                onClick={() => setPage(1)}
                disabled={page === 1}
                className="hidden sm:flex"
              >
                <ChevronsLeft className="h-4 w-4" />
              </Button>
              <Button
                variant="outline"
                size="sm"
                onClick={() => setPage((p) => Math.max(1, p - 1))}
                disabled={page === 1}
              >
                <ChevronLeft className="h-4 w-4 sm:mr-1" />
                <span className="hidden sm:inline">上一页</span>
              </Button>
              <div className="flex items-center gap-2">
                <Input
                  type="number"
                  value={jumpToPage}
                  onChange={(e) => setJumpToPage(e.target.value)}
                  onKeyDown={(e) => e.key === 'Enter' && handleJumpToPage()}
                  placeholder={page.toString()}
                  className="w-16 h-8 text-center"
                  min={1}
                  max={totalPages}
                />
                <Button
                  variant="outline"
                  size="sm"
                  onClick={handleJumpToPage}
                  disabled={!jumpToPage}
                  className="h-8"
                >
                  跳转
                </Button>
              </div>
              <Button
                variant="outline"
                size="sm"
                onClick={() => setPage((p) => p + 1)}
                disabled={page >= totalPages}
              >
                <span className="hidden sm:inline">下一页</span>
                <ChevronRight className="h-4 w-4 sm:ml-1" />
              </Button>
              <Button
                variant="outline"
                size="sm"
                onClick={() => setPage(totalPages)}
                disabled={page >= totalPages}
                className="hidden sm:flex"
              >
                <ChevronsRight className="h-4 w-4" />
              </Button>
            </div>
          </div>
        )}
      </ScrollArea>

      {/* 编辑对话框 */}
      <Dialog open={editDialogOpen} onOpenChange={handleEditDialogClose}>
        <DialogContent 
          className="max-w-[95vw] sm:max-w-2xl max-h-[90vh] overflow-y-auto" 
          data-tour="provider-dialog"
          preventOutsideClose={tourState.isRunning}
        >
          <DialogHeader>
            <DialogTitle>
              {editingIndex !== null ? '编辑提供商' : '添加提供商'}
            </DialogTitle>
            <DialogDescription>
              配置 API 提供商的连接信息和参数
            </DialogDescription>
          </DialogHeader>

          <form onSubmit={(e) => { e.preventDefault(); handleSaveEdit(); }} autoComplete="off">
          <div className="grid gap-4 py-4">
            <div className="grid gap-2" data-tour="provider-template-select">
              <Label htmlFor="template">提供商模板</Label>
              <Popover open={templateComboboxOpen} onOpenChange={setTemplateComboboxOpen}>
                <PopoverTrigger asChild>
                  <Button
                    variant="outline"
                    role="combobox"
                    aria-expanded={templateComboboxOpen}
                    className="w-full justify-between"
                  >
                    {selectedTemplate
                      ? PROVIDER_TEMPLATES.find((template) => template.id === selectedTemplate)?.display_name
                      : "选择提供商模板..."}
                    <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="p-0" align="start" style={{ width: 'var(--radix-popover-trigger-width)' }}>
                  <Command>
                    <CommandInput placeholder="搜索提供商模板..." />
                    <ScrollArea className="h-[300px]">
                      <CommandList className="max-h-none overflow-visible">
                        <CommandEmpty>未找到匹配的模板</CommandEmpty>
                        <CommandGroup>
                          {PROVIDER_TEMPLATES.map((template) => (
                            <CommandItem
                              key={template.id}
                              value={template.display_name}
                              onSelect={() => handleTemplateChange(template.id)}
                            >
                              <Check
                                className={`mr-2 h-4 w-4 ${
                                  selectedTemplate === template.id ? "opacity-100" : "opacity-0"
                                }`}
                              />
                              {template.display_name}
                            </CommandItem>
                          ))}
                        </CommandGroup>
                      </CommandList>
                    </ScrollArea>
                  </Command>
                </PopoverContent>
              </Popover>
              <p className="text-xs text-muted-foreground">
                选择预设模板可自动填充 URL 和客户端类型,支持搜索
              </p>
            </div>

            <div className="grid gap-2" data-tour="provider-name-input">
              <div className="flex items-center gap-1.5">
                <Label htmlFor="name" className={formErrors.name ? 'text-destructive' : ''}>名称 *</Label>
                <HelpTooltip
                  content={
                    <div className="space-y-2">
                      <p className="font-medium">提供商名称</p>
                      <p>为这个 API 提供商设置一个便于识别的名称，用于在模型配置中引用。</p>
                      <ul className="list-disc list-inside space-y-1 text-xs">
                        <li>推荐使用厂商官方名称，如 DeepSeek、OpenAI</li>
                        <li>名称需要唯一，不能与现有提供商重复</li>
                      </ul>
                    </div>
                  }
                  side="right"
                  maxWidth="350px"
                />
              </div>
              <Input
                id="name"
                value={editingProvider?.name || ''}
                onChange={(e) => {
                  setEditingProvider((prev) =>
                    prev ? { ...prev, name: e.target.value } : null
                  )
                  if (formErrors.name) {
                    setFormErrors((prev) => ({ ...prev, name: undefined }))
                  }
                }}
                placeholder="例如: DeepSeek, SiliconFlow"
                className={formErrors.name ? 'border-destructive focus-visible:ring-destructive' : ''}
              />
              {formErrors.name && (
                <p className="text-xs text-destructive">{formErrors.name}</p>
              )}
            </div>

            <div className="grid gap-2" data-tour="provider-url-input">
              <div className="flex items-center gap-1.5">
                <Label htmlFor="base_url" className={formErrors.base_url ? 'text-destructive' : ''}>基础 URL *</Label>
                <HelpTooltip
                  content={
                    <div className="space-y-2">
                      <p className="font-medium">API 基础地址</p>
                      <p>提供商的 API 端点基础 URL，通常以 /v1 结尾。</p>
                      <ul className="list-disc list-inside space-y-1 text-xs">
                        <li><strong>OpenAI 格式：</strong>https://api.openai.com/v1</li>
                        <li><strong>DeepSeek：</strong>https://api.deepseek.com</li>
                        <li><strong>硅基流动：</strong>https://api.siliconflow.cn/v1</li>
                        <li>选择模板会自动填充正确的 URL</li>
                      </ul>
                    </div>
                  }
                  side="right"
                  maxWidth="400px"
                />
              </div>
              <Input
                id="base_url"
                value={editingProvider?.base_url || ''}
                onChange={(e) => {
                  setEditingProvider((prev) =>
                    prev ? { ...prev, base_url: e.target.value } : null
                  )
                  if (formErrors.base_url) {
                    setFormErrors((prev) => ({ ...prev, base_url: undefined }))
                  }
                }}
                placeholder="https://api.example.com/v1"
                disabled={isUsingTemplate}
                className={`${isUsingTemplate ? 'bg-muted cursor-not-allowed' : ''} ${formErrors.base_url ? 'border-destructive focus-visible:ring-destructive' : ''}`}
              />
              {formErrors.base_url && (
                <p className="text-xs text-destructive">{formErrors.base_url}</p>
              )}
              {isUsingTemplate && !formErrors.base_url && (
                <p className="text-xs text-muted-foreground">
                  使用模板时 URL 不可编辑,切换到"自定义"以手动配置
                </p>
              )}
            </div>

            <div className="grid gap-2" data-tour="provider-apikey-input">
              <div className="flex items-center gap-1.5">
                <Label htmlFor="api_key" className={formErrors.api_key ? 'text-destructive' : ''}>API Key *</Label>
                <HelpTooltip
                  content={
                    <div className="space-y-2">
                      <p className="font-medium">API 密钥</p>
                      <p>从提供商平台获取的身份验证密钥。</p>
                      <ul className="list-disc list-inside space-y-1 text-xs">
                        <li>通常以 <code>sk-</code> 开头</li>
                        <li>请妥善保管，不要泄露给他人</li>
                        <li>可以点击眼睛图标切换显示/隐藏</li>
                        <li>点击复制图标可快速复制密钥</li>
                      </ul>
                    </div>
                  }
                  side="right"
                  maxWidth="350px"
                />
              </div>
              <div className="flex gap-2">
                <Input
                  id="api_key"
                  type={showApiKey ? 'text' : 'password'}
                  value={editingProvider?.api_key || ''}
                  onChange={(e) => {
                    setEditingProvider((prev) =>
                      prev ? { ...prev, api_key: e.target.value } : null
                    )
                    if (formErrors.api_key) {
                      setFormErrors((prev) => ({ ...prev, api_key: undefined }))
                    }
                  }}
                  placeholder="sk-..."
                  className={`flex-1 ${formErrors.api_key ? 'border-destructive focus-visible:ring-destructive' : ''}`}
                />
                <Button
                  type="button"
                  variant="outline"
                  size="icon"
                  onClick={() => setShowApiKey(!showApiKey)}
                  title={showApiKey ? '隐藏密钥' : '显示密钥'}
                >
                  {showApiKey ? (
                    <EyeOff className="h-4 w-4" />
                  ) : (
                    <Eye className="h-4 w-4" />
                  )}
                </Button>
                <Button
                  type="button"
                  variant="outline"
                  size="icon"
                  onClick={copyApiKey}
                  title="复制密钥"
                >
                  <Copy className="h-4 w-4" />
                </Button>
              </div>
              {formErrors.api_key && (
                <p className="text-xs text-destructive">{formErrors.api_key}</p>
              )}
            </div>

            <div className="grid gap-2">
              <div className="flex items-center gap-1.5">
                <Label htmlFor="client_type">客户端类型</Label>
                <HelpTooltip
                  content={
                    <div className="space-y-2">
                      <p className="font-medium">API 客户端类型</p>
                      <p>指定与提供商通信时使用的 API 协议格式。</p>
                      <ul className="list-disc list-inside space-y-1 text-xs">
                        <li><strong>OpenAI：</strong>兼容 OpenAI API 格式的提供商</li>
                        <li><strong>Gemini：</strong>Google Gemini 专用格式</li>
                        <li>大部分第三方提供商都兼容 OpenAI 格式</li>
                      </ul>
                    </div>
                  }
                  side="right"
                  maxWidth="350px"
                />
              </div>
              <Select
                value={editingProvider?.client_type || 'openai'}
                onValueChange={(value) =>
                  setEditingProvider((prev) =>
                    prev ? { ...prev, client_type: value } : null
                  )
                }
                disabled={isUsingTemplate}
              >
                <SelectTrigger id="client_type" className={isUsingTemplate ? 'bg-muted cursor-not-allowed' : ''}>
                  <SelectValue placeholder="选择客户端类型" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="openai">OpenAI</SelectItem>
                  <SelectItem value="gemini">Gemini</SelectItem>
                </SelectContent>
              </Select>
              {isUsingTemplate && (
                <p className="text-xs text-muted-foreground">
                  使用模板时客户端类型不可编辑,切换到"自定义"以手动配置
                </p>
              )}
            </div>

            <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
              <div className="grid gap-2">
                <div className="flex items-center gap-1.5">
                  <Label htmlFor="max_retry">最大重试</Label>
                  <HelpTooltip
                    content="API 请求失败时的最大重试次数。设置为 0 表示不重试。默认值：2"
                    side="top"
                    maxWidth="250px"
                  />
                </div>
                <Input
                  id="max_retry"
                  type="number"
                  min="0"
                  value={editingProvider?.max_retry ?? ''}
                  onChange={(e) => {
                    const val = e.target.value === '' ? null : parseInt(e.target.value)
                    setEditingProvider((prev) =>
                      prev ? { ...prev, max_retry: val } : null
                    )
                  }}
                  placeholder="默认: 2"
                />
              </div>

              <div className="grid gap-2">
                <div className="flex items-center gap-1.5">
                  <Label htmlFor="timeout">超时(秒)</Label>
                  <HelpTooltip
                    content="单次 API 请求的超时时间（秒）。超时后会触发重试或报错。默认值：30 秒"
                    side="top"
                    maxWidth="250px"
                  />
                </div>
                <Input
                  id="timeout"
                  type="number"
                  min="1"
                  value={editingProvider?.timeout ?? ''}
                  onChange={(e) => {
                    const val = e.target.value === '' ? null : parseInt(e.target.value)
                    setEditingProvider((prev) =>
                      prev ? { ...prev, timeout: val } : null
                    )
                  }}
                  placeholder="默认: 30"
                />
              </div>

              <div className="grid gap-2">
                <div className="flex items-center gap-1.5">
                  <Label htmlFor="retry_interval">重试间隔(秒)</Label>
                  <HelpTooltip
                    content="两次重试之间的等待时间（秒）。适当的间隔可以避免触发 API 限流。默认值：10 秒"
                    side="top"
                    maxWidth="250px"
                  />
                </div>
                <Input
                  id="retry_interval"
                  type="number"
                  min="1"
                  value={editingProvider?.retry_interval ?? ''}
                  onChange={(e) => {
                    const val = e.target.value === '' ? null : parseInt(e.target.value)
                    setEditingProvider((prev) =>
                      prev
                        ? { ...prev, retry_interval: val }
                        : null
                    )
                  }}
                  placeholder="默认: 10"
                />
              </div>
            </div>
          </div>

          <DialogFooter>
            <Button type="button" variant="outline" onClick={() => setEditDialogOpen(false)} data-tour="provider-cancel-button">
              取消
            </Button>
            <Button type="submit" data-tour="provider-save-button">保存</Button>
          </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      {/* 删除确认对话框 */}
      <AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>确认删除</AlertDialogTitle>
            <AlertDialogDescription>
              确定要删除提供商 "{deletingIndex !== null ? providers[deletingIndex]?.name : ''}" 吗？
              此操作无法撤销。
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>取消</AlertDialogCancel>
            <AlertDialogAction onClick={handleConfirmDelete}>删除</AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* 批量删除确认对话框 */}
      <AlertDialog open={batchDeleteDialogOpen} onOpenChange={setBatchDeleteDialogOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>确认批量删除</AlertDialogTitle>
            <AlertDialogDescription>
              确定要删除选中的 {selectedProviders.size} 个提供商吗？
              此操作无法撤销。
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>取消</AlertDialogCancel>
            <AlertDialogAction onClick={handleConfirmBatchDelete} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
              批量删除
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* 删除提供商影响确认对话框 */}
      <AlertDialog open={deleteConfirmState.isOpen} onOpenChange={(open) => setDeleteConfirmState(prev => ({ ...prev, isOpen: open }))}>
        <AlertDialogContent className="max-w-2xl">
          <AlertDialogHeader>
            <AlertDialogTitle>确认删除提供商</AlertDialogTitle>
            <AlertDialogDescription asChild>
              <div className="space-y-3">
                <p>
                  您即将删除以下提供商：
                  <strong className="text-foreground ml-1">
                    {deleteConfirmState.providersToDelete.join(', ')}
                  </strong>
                </p>
                <p className="text-yellow-600 dark:text-yellow-500 font-medium">
                  ⚠️ 此操作将同时删除 {deleteConfirmState.affectedModels.length} 个关联的模型：
                </p>
                <ScrollArea className="h-32 w-full rounded border p-3">
                  <div className="space-y-1">
                    {deleteConfirmState.affectedModels.map((model: any, idx: number) => (
                      <div key={idx} className="text-sm">
                        <span className="font-mono text-muted-foreground">•</span>
                        <span className="ml-2 font-medium">{model.name}</span>
                        <span className="ml-2 text-xs text-muted-foreground">
                          ({model.model_identifier})
                        </span>
                      </div>
                    ))}
                  </div>
                </ScrollArea>
                <p className="text-sm text-muted-foreground">
                  这些模型将从模型列表和所有任务分配中移除。此操作无法撤销。
                </p>
              </div>
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel onClick={handleCancelDeleteProvider}>取消</AlertDialogCancel>
            <AlertDialogAction 
              onClick={handleConfirmDeleteProvider}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              确认删除
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* 重启遮罩层 */}
      <RestartOverlay />
    </div>
  )
}
