import React, { useEffect, useState } from 'react';
import { Search, Filter, Plus, BrainCircuit, Trash2, Key, Settings2, Server, Thermometer, Pencil, Play } from 'lucide-react';
import { Button, Input, Select, TableHeader, TableRow, TableHead, TableCell, Dialog, Badge, LibraryPageShell, TableStatusRow, LibraryActionCell } from '../components/UI';
import { LLMModel } from '../types';
import { createLLMModel, deleteLLMModel, fetchLLMModels, previewLLMModel, updateLLMModel } from '../services/backendApi';

const maskApiKey = (key?: string) => {
  if (!key) return '********';
  if (key.length < 8) return '********';
  return `${key.slice(0, 3)}****${key.slice(-4)}`;
};

export const LLMLibraryPage: React.FC = () => {
  const [models, setModels] = useState<LLMModel[]>([]);
  const [searchTerm, setSearchTerm] = useState('');
  const [vendorFilter, setVendorFilter] = useState<string>('OpenAI Compatible');
  const [typeFilter, setTypeFilter] = useState<string>('all');
  const [isAddModalOpen, setIsAddModalOpen] = useState(false);
  const [editingModel, setEditingModel] = useState<LLMModel | null>(null);
  const [previewingModel, setPreviewingModel] = useState<LLMModel | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const load = async () => {
      setIsLoading(true);
      try {
        setModels(await fetchLLMModels());
      } catch (error) {
        console.error(error);
        setModels([]);
      } finally {
        setIsLoading(false);
      }
    };
    load();
  }, []);

  const filteredModels = models.filter((m) => {
    const q = searchTerm.toLowerCase();
    const matchesSearch =
      m.name.toLowerCase().includes(q) ||
      (m.modelName || '').toLowerCase().includes(q) ||
      (m.baseUrl || '').toLowerCase().includes(q);
    const matchesVendor = m.vendor === vendorFilter;
    const matchesType = typeFilter === 'all' || m.type === typeFilter;
    return matchesSearch && matchesVendor && matchesType;
  });

  const handleCreate = async (data: Partial<LLMModel>) => {
    const created = await createLLMModel(data);
    setModels((prev) => [created, ...prev]);
    setIsAddModalOpen(false);
  };

  const handleUpdate = async (id: string, data: Partial<LLMModel>) => {
    const updated = await updateLLMModel(id, data);
    setModels((prev) => prev.map((item) => (item.id === id ? updated : item)));
    setEditingModel(null);
  };

  const handleDelete = async (id: string) => {
    if (!confirm('确认删除该模型吗？该操作不可恢复。')) return;
    await deleteLLMModel(id);
    setModels((prev) => prev.filter((item) => item.id !== id));
  };

  return (
    <LibraryPageShell
      title="模型接入"
      primaryAction={(
        <Button onClick={() => setIsAddModalOpen(true)} className="shadow-[0_0_15px_rgba(6,182,212,0.4)]">
          <Plus className="mr-2 h-4 w-4" /> 添加模型
        </Button>
      )}
      filterBar={(
        <>
        <div className="relative col-span-1 md:col-span-2">
          <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
          <Input
            placeholder="搜索名称..."
            className="pl-9 border-0 bg-white/5"
            value={searchTerm}
            onChange={(e) => setSearchTerm(e.target.value)}
          />
        </div>
        <div className="flex items-center space-x-2">
          <Filter className="h-4 w-4 text-muted-foreground" />
          <Select
            value={vendorFilter}
            onChange={(e) => setVendorFilter(e.target.value)}
          >
            <option value="OpenAI Compatible">OpenAI Compatible</option>
          </Select>
        </div>
        <div className="flex items-center space-x-2">
          <Select
            value={typeFilter}
            onChange={(e) => setTypeFilter(e.target.value)}
          >
            <option value="all">所有类型</option>
            <option value="text">文本 (Text)</option>
            <option value="embedding">嵌入 (Embedding)</option>
            <option value="rerank">重排 (Rerank)</option>
          </Select>
        </div>
        </>
      )}
    >

      <div className="rounded-md border border-white/5 bg-card/40 backdrop-blur-md overflow-hidden">
        <table className="w-full text-sm">
          <TableHeader>
            <TableRow>
              <TableHead>模型名称</TableHead>
              <TableHead>厂商</TableHead>
              <TableHead>类型</TableHead>
              <TableHead>模型标识</TableHead>
              <TableHead>Base URL</TableHead>
              <TableHead>API Key</TableHead>
              <TableHead className="text-right">操作</TableHead>
            </TableRow>
          </TableHeader>
          <tbody>
            {!isLoading && filteredModels.map((model) => (
              <TableRow key={model.id}>
                <TableCell className="font-medium text-white flex items-center">
                  <BrainCircuit className="w-4 h-4 mr-2 text-primary" />
                  {model.name}
                </TableCell>
                <TableCell>
                  <Badge variant="outline">{model.vendor}</Badge>
                </TableCell>
                <TableCell>
                  <Badge variant={model.type === 'text' ? 'default' : 'outline'} className={model.type !== 'text' ? 'text-blue-400 border-blue-400/20 bg-blue-400/5' : ''}>
                    {model.type.toUpperCase()}
                  </Badge>
                </TableCell>
                <TableCell className="font-mono text-xs text-muted-foreground">{model.modelName || '-'}</TableCell>
                <TableCell className="font-mono text-xs text-muted-foreground max-w-[240px] truncate">{model.baseUrl}</TableCell>
                <TableCell className="font-mono text-xs text-muted-foreground">{maskApiKey(model.apiKey)}</TableCell>
                <LibraryActionCell
                  previewAction={(
                    <Button
                    variant="ghost"
                    size="icon"
                    onClick={() => setPreviewingModel(model)}
                    disabled={model.type === 'rerank'}
                    title={model.type === 'rerank' ? '暂不支持 rerank 预览' : (model.type === 'embedding' ? '预览 embedding 向量' : '预览模型')}
                  >
                    <Play className="h-4 w-4" />
                  </Button>
                  )}
                  editAction={(
                    <Button variant="ghost" size="icon" onClick={() => setEditingModel(model)} title="编辑模型">
                      <Pencil className="h-4 w-4" />
                    </Button>
                  )}
                  deleteAction={(
                    <Button variant="ghost" size="icon" onClick={() => handleDelete(model.id)} className="text-muted-foreground hover:text-destructive transition-colors" title="删除模型">
                      <Trash2 className="h-4 w-4" />
                    </Button>
                  )}
                />
              </TableRow>
            ))}
            {!isLoading && filteredModels.length === 0 && <TableStatusRow colSpan={7} text="暂无模型数据" />}
            {isLoading && <TableStatusRow colSpan={7} text="加载中..." />}
          </tbody>
        </table>
      </div>

      <LLMModelModal isOpen={isAddModalOpen} onClose={() => setIsAddModalOpen(false)} onSubmit={handleCreate} />

      <LLMModelModal
        isOpen={!!editingModel}
        onClose={() => setEditingModel(null)}
        onSubmit={(data) => handleUpdate(editingModel!.id, data)}
        initialModel={editingModel || undefined}
      />

      <LLMPreviewModal
        isOpen={!!previewingModel}
        onClose={() => setPreviewingModel(null)}
        model={previewingModel}
      />
    </LibraryPageShell>
  );
};

const LLMModelModal: React.FC<{
  isOpen: boolean;
  onClose: () => void;
  onSubmit: (model: Partial<LLMModel>) => Promise<void>;
  initialModel?: LLMModel;
}> = ({ isOpen, onClose, onSubmit, initialModel }) => {
  const [name, setName] = useState('');
  const [vendor, setVendor] = useState('OpenAI Compatible');
  const [type, setType] = useState<'text' | 'embedding' | 'rerank'>('text');
  const [modelName, setModelName] = useState('');
  const [baseUrl, setBaseUrl] = useState('');
  const [apiKey, setApiKey] = useState('');
  const [temperature, setTemperature] = useState(0.7);
  const [contextLength, setContextLength] = useState(8192);
  const [enabled, setEnabled] = useState(true);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    if (!isOpen) return;
    if (initialModel) {
      setName(initialModel.name || '');
      setVendor(initialModel.vendor || 'OpenAI Compatible');
      setType(initialModel.type || 'text');
      setModelName(initialModel.modelName || '');
      setBaseUrl(initialModel.baseUrl || '');
      setApiKey(initialModel.apiKey || '');
      setTemperature(initialModel.temperature ?? 0.7);
      setContextLength(initialModel.contextLength ?? 8192);
      setEnabled(initialModel.enabled ?? true);
      return;
    }

    setName('');
    setVendor('OpenAI Compatible');
    setType('text');
    setModelName('');
    setBaseUrl('');
    setApiKey('');
    setTemperature(0.7);
    setContextLength(8192);
    setEnabled(true);
  }, [initialModel, isOpen]);

  const handleSubmit = async () => {
    if (!name.trim() || !baseUrl.trim() || !apiKey.trim()) {
      alert('请填写完整信息');
      return;
    }

    try {
      setSaving(true);
      await onSubmit({
        name: name.trim(),
        vendor: vendor.trim(),
        type,
        modelName: modelName.trim() || undefined,
        baseUrl: baseUrl.trim(),
        apiKey: apiKey.trim(),
        temperature: type === 'text' ? temperature : undefined,
        contextLength: contextLength > 0 ? contextLength : undefined,
        enabled,
      });
    } catch (error: any) {
      alert(error?.message || '保存失败');
    } finally {
      setSaving(false);
    }
  };

  return (
    <Dialog
      isOpen={isOpen}
      onClose={onClose}
      title={initialModel ? '编辑大模型' : '添加大模型'}
      footer={
        <>
          <Button variant="ghost" onClick={onClose}>取消</Button>
          <Button onClick={handleSubmit} disabled={saving}>{saving ? '保存中...' : (initialModel ? '保存修改' : '确认添加')}</Button>
        </>
      }
    >
      <div className="space-y-4 max-h-[75vh] overflow-y-auto px-1 custom-scrollbar">
        <div className="space-y-1.5">
          <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">厂商 (Vendor)</label>
          <Select
            className="h-10 border border-white/10 appearance-none cursor-pointer"
            value={vendor}
            onChange={(e) => setVendor(e.target.value)}
          >
            <option value="OpenAI Compatible">OpenAI Compatible</option>
          </Select>
        </div>

        <div className="space-y-1.5">
          <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">模型类型 (Type)</label>
          <div className="flex bg-white/5 p-1 rounded-lg border border-white/10">
            {(['text', 'embedding', 'rerank'] as const).map((t) => (
              <button
                key={t}
                onClick={() => setType(t)}
                className={`flex-1 flex items-center justify-center py-1.5 text-xs font-bold rounded-md transition-all ${type === t ? 'bg-primary text-primary-foreground shadow-lg' : 'text-muted-foreground hover:text-foreground'}`}
              >
                {t === 'text' && <Settings2 className="w-3 h-3 mr-1.5" />}
                {t === 'embedding' && <BrainCircuit className="w-3 h-3 mr-1.5" />}
                {t === 'rerank' && <Filter className="w-3 h-3 mr-1.5" />}
                {t === 'text' ? '文本' : t === 'embedding' ? '嵌入' : '重排'}
              </button>
            ))}
          </div>
        </div>

        <div className="space-y-1.5">
          <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">模型名称 (Display Name)</label>
          <Input value={name} onChange={(e) => setName(e.target.value)} placeholder="例如: GPT4o-Prod" />
        </div>

        <div className="space-y-1.5">
          <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">模型标识 (model_name)</label>
          <Input value={modelName} onChange={(e) => setModelName(e.target.value)} placeholder="例如: gpt-4o-mini" />
        </div>

        <div className="space-y-1.5">
          <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block flex items-center"><Server className="w-3 h-3 mr-1.5" /> Base URL</label>
          <Input value={baseUrl} onChange={(e) => setBaseUrl(e.target.value)} placeholder="https://api.openai.com/v1" className="font-mono text-xs" />
        </div>

        <div className="space-y-1.5">
          <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block flex items-center"><Key className="w-3 h-3 mr-1.5" /> API Key</label>
          <Input type="password" value={apiKey} onChange={(e) => setApiKey(e.target.value)} placeholder="sk-..." className="font-mono text-xs" />
        </div>

        {type === 'text' && (
          <div className="space-y-3 pt-2">
            <div className="flex justify-between items-center mb-1">
              <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block flex items-center"><Thermometer className="w-3 h-3 mr-1.5" /> 温度 (Temperature)</label>
              <span className="text-[10px] font-mono text-primary bg-primary/10 px-1.5 py-0.5 rounded">{temperature.toFixed(1)}</span>
            </div>
            <input
              type="range"
              min="0"
              max="2"
              step="0.1"
              value={temperature}
              onChange={(e) => setTemperature(parseFloat(e.target.value))}
              className="w-full h-1.5 bg-secondary rounded-lg appearance-none cursor-pointer accent-primary"
            />
          </div>
        )}

        <div className="space-y-1.5">
          <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">上下文长度 (context_length)</label>
          <Input type="number" min={1} value={contextLength} onChange={(e) => setContextLength(parseInt(e.target.value || '0', 10))} />
        </div>

        <label className="flex items-center space-x-2 text-xs text-muted-foreground">
          <input type="checkbox" checked={enabled} onChange={(e) => setEnabled(e.target.checked)} />
          <span>启用</span>
        </label>
      </div>
    </Dialog>
  );
};

const LLMPreviewModal: React.FC<{
  isOpen: boolean;
  onClose: () => void;
  model: LLMModel | null;
}> = ({ isOpen, onClose, model }) => {
  const isEmbeddingModel = model?.type === 'embedding';
  const [systemPrompt, setSystemPrompt] = useState('You are a concise helpful assistant.');
  const [message, setMessage] = useState('Hello, please introduce yourself in one sentence.');
  const [temperature, setTemperature] = useState(0.7);
  const [maxTokens, setMaxTokens] = useState(256);
  const [reply, setReply] = useState('');
  const [latency, setLatency] = useState<number | null>(null);
  const [usage, setUsage] = useState<Record<string, number> | null>(null);
  const [isRunning, setIsRunning] = useState(false);

  useEffect(() => {
    if (!isOpen) return;
    setReply('');
    setLatency(null);
    setUsage(null);
    setTemperature(model?.temperature ?? 0.7);
  }, [isOpen, model]);

  const runPreview = async () => {
    if (!model?.id) return;
    if (!message.trim()) {
      alert('请输入测试消息');
      return;
    }

    try {
      setIsRunning(true);
      const result = await previewLLMModel(model.id, {
        message,
        system_prompt: systemPrompt || undefined,
        max_tokens: maxTokens,
        temperature,
      });
      setReply(result.reply || result.error || '无返回内容');
      setLatency(result.latency_ms ?? null);
      setUsage(result.usage || null);
    } catch (error: any) {
      alert(error?.message || '预览失败');
    } finally {
      setIsRunning(false);
    }
  };

  return (
    <Dialog
      isOpen={isOpen}
      onClose={onClose}
      title={`预览模型: ${model?.name || ''}`}
      footer={
        <>
          <Button variant="ghost" onClick={onClose}>关闭</Button>
          <Button onClick={runPreview} disabled={isRunning}>{isRunning ? '请求中...' : '开始预览'}</Button>
        </>
      }
    >
      <div className="space-y-4">
        <div className="space-y-1.5">
          <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">System Prompt</label>
          <textarea
            value={systemPrompt}
            onChange={(e) => setSystemPrompt(e.target.value)}
            className="flex min-h-[70px] w-full rounded-md border-0 bg-white/5 px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/50 text-white"
            placeholder={isEmbeddingModel ? 'embedding 预览无需 system prompt（可留空）' : '可选系统提示词'}
            disabled={isEmbeddingModel}
          />
        </div>

        <div className="space-y-1.5">
          <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">{isEmbeddingModel ? 'Input Text' : 'User Message'}</label>
          <textarea
            value={message}
            onChange={(e) => setMessage(e.target.value)}
            className="flex min-h-[90px] w-full rounded-md border-0 bg-white/5 px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/50 text-white"
            placeholder={isEmbeddingModel ? '输入需要生成向量的文本' : '输入用户消息'}
          />
        </div>

        <div className="grid grid-cols-2 gap-4">
          <div className="space-y-1.5">
            <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">Temperature</label>
            <Input type="number" min={0} max={2} step={0.1} value={temperature} onChange={(e) => setTemperature(parseFloat(e.target.value || '0'))} disabled={isEmbeddingModel} />
          </div>
          <div className="space-y-1.5">
            <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">Max Tokens</label>
            <Input type="number" min={1} value={maxTokens} onChange={(e) => setMaxTokens(parseInt(e.target.value || '1', 10))} disabled={isEmbeddingModel} />
          </div>
        </div>

        <div className="rounded-lg border border-primary/20 bg-primary/5 p-3 space-y-2">
          <div className="flex items-center justify-between text-xs text-primary">
            <span>模型回复</span>
            <span>{latency !== null ? `Latency: ${latency}ms` : ''}</span>
          </div>
          <textarea
            readOnly
            value={reply}
            className="flex min-h-[140px] w-full rounded-md border-0 bg-black/20 px-3 py-2 text-sm shadow-sm text-white"
            placeholder="回复会显示在这里"
          />
          {usage && (
            <div className="text-xs text-muted-foreground font-mono">
              prompt: {usage.prompt_tokens ?? '-'} | completion: {usage.completion_tokens ?? '-'} | total: {usage.total_tokens ?? '-'}
            </div>
          )}
        </div>
      </div>
    </Dialog>
  );
};
