import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { CheckCircle2, XCircle, Eye, EyeOff, Loader2, Trash2, Plus, Bot, ArrowRight } from 'lucide-react'
import toast from 'react-hot-toast'
import { providersApi, type Provider, type ModelInUse } from '../api/providers'
import { Card, PageHeader, Badge, Button, Input, Spinner } from '../components/ui'
import { clsx } from '../lib/clsx'

function StatusBadge({ configured }: { configured: boolean }) {
  return configured ? (
    <Badge variant="green">
      <CheckCircle2 size={10} className="mr-1" />
      已配置
    </Badge>
  ) : (
    <Badge variant="default">未配置</Badge>
  )
}

interface ProviderCardProps {
  provider: Provider
  onSave: (id: string, key: string) => void
  onRemove: (id: string) => void
  onTest: (id: string) => void
  testing: boolean
  testResult: { ok: boolean; message: string } | null
  saving: boolean
}

function ProviderCard({ provider, onSave, onRemove, onTest, testing, testResult, saving }: ProviderCardProps) {
  const [editing, setEditing] = useState(false)
  const [apiKey, setApiKey] = useState('')
  const [showKey, setShowKey] = useState(false)

  function handleSave() {
    onSave(provider.id, apiKey)
    setApiKey('')
    setEditing(false)
  }

  return (
    <Card className="space-y-4">
      {/* Header */}
      <div className="flex items-start justify-between">
        <div>
          <p className="text-sm font-semibold text-gray-900">{provider.name}</p>
          <p className="text-xs text-gray-400 mt-0.5">{provider.base_url || '本地服务'}</p>
        </div>
        <StatusBadge configured={provider.configured} />
      </div>

      {/* Models */}
      <div className="flex flex-wrap gap-1">
        {provider.models.slice(0, 4).map(m => (
          <span key={m} className="text-xs bg-gray-100 text-gray-600 px-2 py-0.5 rounded">
            {m}
          </span>
        ))}
        {provider.models.length > 4 && (
          <span className="text-xs text-gray-400">+{provider.models.length - 4} 个</span>
        )}
      </div>

      {/* No-key providers info */}
      {provider.no_key_required && (
        <p className="text-xs text-green-700 bg-green-50 rounded-lg px-3 py-2">
          无需 API Key，直接使用
        </p>
      )}

      {/* API Key input */}
      {!provider.no_key_required && editing && (
        <div className="space-y-2">
          <div className="relative">
            <input
              type={showKey ? 'text' : 'password'}
              placeholder={`${provider.env_key || 'API_KEY'}（填写后保存在本机）`}
              value={apiKey}
              onChange={e => setApiKey(e.target.value)}
              className="w-full rounded-lg border border-gray-300 px-3 py-2 pr-9 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500"
            />
            <button
              onClick={() => setShowKey(v => !v)}
              className="absolute right-2.5 top-2.5 text-gray-400 hover:text-gray-600"
            >
              {showKey ? <EyeOff size={14} /> : <Eye size={14} />}
            </button>
          </div>
          <div className="flex gap-2">
            <Button size="sm" onClick={handleSave} loading={saving} disabled={!apiKey}>
              保存
            </Button>
            <Button size="sm" variant="secondary" onClick={() => { setEditing(false); setApiKey('') }}>
              取消
            </Button>
          </div>
        </div>
      )}

      {/* Test result */}
      {testResult && (
        <div
          className={clsx(
            'flex items-start gap-2 text-xs rounded-lg px-3 py-2',
            testResult.ok ? 'bg-green-50 text-green-700' : 'bg-red-50 text-red-700',
          )}
        >
          {testResult.ok ? <CheckCircle2 size={13} className="mt-0.5 shrink-0" /> : <XCircle size={13} className="mt-0.5 shrink-0" />}
          {testResult.message}
        </div>
      )}

      {/* Actions */}
      <div className="flex gap-2 pt-1">
        <Button
          size="sm"
          variant="secondary"
          onClick={() => onTest(provider.id)}
          loading={testing}
          className="flex-1"
        >
          {testing ? '测试中…' : '测试连接'}
        </Button>

        {!provider.no_key_required && !editing && (
          <Button size="sm" variant="ghost" onClick={() => setEditing(true)} icon={<Plus size={13} />}>
            {provider.configured ? '更新 Key' : '配置 Key'}
          </Button>
        )}

        {provider.configured && !provider.no_key_required && (
          <button
            onClick={() => {
              if (window.confirm(`确定要移除 ${provider.name} 的 API Key 吗？`)) {
                onRemove(provider.id)
              }
            }}
            className="p-1.5 text-gray-300 hover:text-red-500 transition-colors"
            title="移除 Key"
          >
            <Trash2 size={14} />
          </button>
        )}
      </div>
    </Card>
  )
}

// ── 使用中的模型：各智能体当前模型一览 + 切换 ──────────────────────────────

function ModelsInUseSection({ providers }: { providers: Provider[] }) {
  const qc = useQueryClient()
  // 切换草稿: agent_id -> "provider/model"
  const [draft, setDraft] = useState<Record<string, string>>({})

  const { data, isLoading } = useQuery({
    queryKey: ['models-in-use'],
    queryFn: providersApi.modelsInUse,
    retry: false,
  })

  const switchMut = useMutation({
    mutationFn: ({ agentId, provider, name }: { agentId: string; provider: string; name: string }) =>
      providersApi.switchModel(agentId, provider, name),
    onSuccess: (res) => {
      toast.success(`已切换：${res.previous} → 新模型（v${res.version}，可在版本历史回滚）`, { duration: 5000 })
      qc.invalidateQueries({ queryKey: ['models-in-use'] })
      qc.invalidateQueries({ queryKey: ['agents'] })
    },
    onError: (e: any) => toast.error(e.message ?? '切换失败'),
  })

  // 下拉选项：已配置的 provider 优先，其余置后并标注
  const options: { value: string; label: string; configured: boolean }[] = []
  for (const p of providers) {
    for (const m of p.models) {
      options.push({
        value: `${p.id}/${m}`,
        label: `${p.id} / ${m}${p.configured ? '' : '（未配置 Key）'}`,
        configured: p.configured,
      })
    }
  }
  options.sort((a, b) => Number(b.configured) - Number(a.configured))

  if (isLoading) return null
  const items = data?.items ?? []
  if (items.length === 0) return null

  return (
    <section>
      <h2 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-3">
        使用中的模型（{items.length} 个智能体）
      </h2>
      <Card className="divide-y divide-gray-100 p-0 overflow-hidden">
        {items.map((it: ModelInUse) => {
          const current = `${it.provider || '?'}/${it.model || '?'}`
          const selected = draft[it.agent_id] ?? ''
          const changed = selected && selected !== current
          return (
            <div key={it.agent_id} className="flex items-center gap-3 px-4 py-3 flex-wrap">
              <div className="flex items-center gap-2 min-w-0 flex-1">
                <Bot size={14} className="text-indigo-500 shrink-0" />
                <span className="text-sm font-medium text-gray-900 truncate">{it.agent_name}</span>
                <span className="text-[10px] text-gray-400 font-mono shrink-0">v{it.version}</span>
              </div>
              <Badge variant={it.provider ? 'green' : 'default'}>
                {current}
              </Badge>
              <ArrowRight size={12} className="text-gray-300 shrink-0" />
              <select
                value={selected || current}
                onChange={e => setDraft(prev => ({ ...prev, [it.agent_id]: e.target.value }))}
                className="text-xs border border-gray-200 rounded-lg px-2 py-1.5 bg-white text-gray-700 max-w-[220px]"
              >
                {!options.some(o => o.value === current) && (
                  <option value={current}>{current}（当前）</option>
                )}
                {options.map(o => (
                  <option key={o.value} value={o.value}>{o.label}</option>
                ))}
              </select>
              <Button
                size="sm"
                disabled={!changed || switchMut.isPending}
                onClick={() => {
                  const [provider, ...rest] = selected.split('/')
                  switchMut.mutate({ agentId: it.agent_id, provider, name: rest.join('/') })
                }}
              >
                {switchMut.isPending ? '切换中…' : '切换'}
              </Button>
            </div>
          )
        })}
      </Card>
      <p className="text-[11px] text-gray-400 mt-2">
        切换会生成新版本（旧配置保留在「智能体 → 编辑 → 版本历史」中可回滚）；
        ollama 选项列出的是本机实际安装的模型。
      </p>
    </section>
  )
}

export default function Providers() {
  const qc = useQueryClient()
  const [testingId, setTestingId] = useState<string | null>(null)
  const [testResults, setTestResults] = useState<Record<string, { ok: boolean; message: string }>>({})
  const [savingId, setSavingId] = useState<string | null>(null)

  const { data, isLoading, isError } = useQuery({
    queryKey: ['providers'],
    queryFn: providersApi.list,
    retry: false,
  })

  const saveMutation = useMutation({
    mutationFn: ({ id, key }: { id: string; key: string }) =>
      providersApi.save(id, { api_key: key }),
    onSuccess: (_, vars) => {
      qc.invalidateQueries({ queryKey: ['providers'] })
      toast.success('API Key 已保存')
      setSavingId(null)
    },
    onError: () => {
      toast.error('保存失败')
      setSavingId(null)
    },
  })

  const removeMutation = useMutation({
    mutationFn: (id: string) => providersApi.remove(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['providers'] })
      toast.success('Key 已移除')
    },
    onError: () => toast.error('移除失败'),
  })

  async function handleTest(id: string) {
    setTestingId(id)
    try {
      const result = await providersApi.test(id)
      setTestResults(prev => ({ ...prev, [id]: result }))
    } catch {
      setTestResults(prev => ({ ...prev, [id]: { ok: false, message: '请求失败' } }))
    } finally {
      setTestingId(null)
    }
  }

  function handleSave(id: string, key: string) {
    setSavingId(id)
    saveMutation.mutate({ id, key })
  }

  const configured = data?.providers?.filter(p => p.configured) ?? []
  const unconfigured = data?.providers?.filter(p => !p.configured) ?? []

  return (
    <div className="p-8 max-w-6xl mx-auto">
      <PageHeader
        title="模型提供商"
        description={data ? `${configured.length} / ${data.providers.length} 个已配置` : undefined}
      />

      {isLoading ? (
        <div className="flex justify-center py-16"><Spinner size={32} /></div>
      ) : isError ? (
        <div className="rounded-xl border border-yellow-200 bg-yellow-50 p-6 text-sm text-yellow-800">
          <p className="font-medium mb-1">无法连接到后端服务</p>
          <p className="text-yellow-700">请先启动 AgentPaaS 服务：
            <code className="ml-1 bg-yellow-100 px-1.5 py-0.5 rounded font-mono text-xs">agentpaas serve --dev</code>
          </p>
        </div>
      ) : (
        <div className="space-y-8">
          <ModelsInUseSection providers={data?.providers ?? []} />

          {configured.length > 0 && (
            <section>
              <h2 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-3">
                已配置
              </h2>
              <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
                {configured.map(p => (
                  <ProviderCard
                    key={p.id}
                    provider={p}
                    onSave={handleSave}
                    onRemove={id => removeMutation.mutate(id)}
                    onTest={handleTest}
                    testing={testingId === p.id}
                    testResult={testResults[p.id] ?? null}
                    saving={savingId === p.id}
                  />
                ))}
              </div>
            </section>
          )}

          {unconfigured.length > 0 && (
            <section>
              <h2 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-3">
                可添加
              </h2>
              <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
                {unconfigured.map(p => (
                  <ProviderCard
                    key={p.id}
                    provider={p}
                    onSave={handleSave}
                    onRemove={id => removeMutation.mutate(id)}
                    onTest={handleTest}
                    testing={testingId === p.id}
                    testResult={testResults[p.id] ?? null}
                    saving={savingId === p.id}
                  />
                ))}
              </div>
            </section>
          )}
        </div>
      )}
    </div>
  )
}
