import React, { useEffect, useState, useRef } from 'react';
import { Search, Plus, FileText, Upload, ArrowLeft, CloudUpload, File as FileIcon, X, Pencil, Trash2, Settings2, MoreHorizontal } from 'lucide-react';
import { Button, Input, TableHeader, TableRow, TableHead, TableCell, Card, Dialog, Badge } from '../components/UI';
import { KnowledgeBase } from '../types';
import { createKnowledgeBase, deleteKnowledgeBase, deleteKnowledgeDocument, fetchKnowledgeBaseById, fetchKnowledgeBases, fetchLLMModels, updateKnowledgeBase, uploadKnowledgeDocument } from '../services/backendApi';

const EMBEDDING_OPTIONS = [
  'text-embedding-3-small',
  'text-embedding-3-large',
  'bge-small-zh',
];

export const KnowledgeBasePage: React.FC = () => {
  const [view, setView] = useState<'list' | 'detail'>('list');
  const [selectedKb, setSelectedKb] = useState<KnowledgeBase | null>(null);
  const [searchTerm, setSearchTerm] = useState('');
  const [kbs, setKbs] = useState<KnowledgeBase[]>([]);
  const [isUploadOpen, setIsUploadOpen] = useState(false);
  const [isKbModalOpen, setIsKbModalOpen] = useState(false);
  const [editingKb, setEditingKb] = useState<KnowledgeBase | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [isDetailLoading, setIsDetailLoading] = useState(false);
  const [embeddingOptions, setEmbeddingOptions] = useState<string[]>(EMBEDDING_OPTIONS);
  const [hasDbEmbeddingModels, setHasDbEmbeddingModels] = useState(false);
  const [openMenuKbId, setOpenMenuKbId] = useState<string | null>(null);

  const [kbName, setKbName] = useState('');
  const [kbDescription, setKbDescription] = useState('');
  const [kbEmbeddingModel, setKbEmbeddingModel] = useState('text-embedding-3-small');
  const [kbChunkSize, setKbChunkSize] = useState(500);
  const [kbChunkOverlap, setKbChunkOverlap] = useState(50);
  const [isSavingKb, setIsSavingKb] = useState(false);

  const filteredKbs = kbs.filter((kb) => kb.name.toLowerCase().includes(searchTerm.toLowerCase()));

  const refreshKnowledgeBases = async () => {
    setIsLoading(true);
    try {
      const list = await fetchKnowledgeBases();
      setKbs(list);
      if (selectedKb) {
        const nextSelected = list.find((item) => item.id === selectedKb.id) || null;
        setSelectedKb(nextSelected);
      }
    } catch (error: any) {
      console.error(error);
      alert(error?.message || '加载知识库失败，请检查后端服务。');
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    refreshKnowledgeBases();
    const loadEmbeddingModels = async () => {
      try {
        const models = await fetchLLMModels();
        const fromDb = Array.from(new Set(models
          .filter((m) => m.type === 'embedding')
          .map((m) => (m.modelName || m.name || '').trim())
          .filter(Boolean)));

        setHasDbEmbeddingModels(fromDb.length > 0);

        // Prefer DB embedding models first; keep defaults as fallback at the end.
        const defaultsTail = EMBEDDING_OPTIONS.filter((item) => !fromDb.includes(item));
        const ordered = [...fromDb, ...defaultsTail];
        setEmbeddingOptions(ordered.length > 0 ? ordered : EMBEDDING_OPTIONS);
      } catch {
        setEmbeddingOptions(EMBEDDING_OPTIONS);
        setHasDbEmbeddingModels(false);
      }
    };
    loadEmbeddingModels();
  }, []);

  useEffect(() => {
    const onDocClick = () => setOpenMenuKbId(null);
    document.addEventListener('click', onDocClick);
    return () => document.removeEventListener('click', onDocClick);
  }, []);

  const handleSelect = async (kb: KnowledgeBase) => {
    setSelectedKb(kb);
    setView('detail');
    setIsDetailLoading(true);
    try {
      const fullKb = await fetchKnowledgeBaseById(kb.id);
      setSelectedKb(fullKb);
    } catch (error: any) {
      console.error(error);
      alert(error?.message || '加载知识库详情失败。');
    } finally {
      setIsDetailLoading(false);
    }
  };

  const openCreateKb = () => {
    setEditingKb(null);
    setKbName('');
    setKbDescription('');
    setKbEmbeddingModel('text-embedding-3-small');
    setKbChunkSize(500);
    setKbChunkOverlap(50);
    setIsKbModalOpen(true);
  };

  const openEditKb = (kb: KnowledgeBase) => {
    setEditingKb(kb);
    setKbName(kb.name || '');
    setKbDescription(kb.description || '');
    setKbEmbeddingModel(kb.embeddingModel || 'text-embedding-3-small');
    setKbChunkSize(kb.chunkSize ?? 500);
    setKbChunkOverlap(kb.chunkOverlap ?? 50);
    setIsKbModalOpen(true);
  };

  const handleSaveKb = async () => {
    if (!kbName.trim()) {
      alert('请输入知识库名称');
      return;
    }
    if (kbChunkSize <= 0) {
      alert('Chunk Size 必须大于 0');
      return;
    }
    if (kbChunkOverlap < 0) {
      alert('Chunk Overlap 不能小于 0');
      return;
    }
    if (kbChunkOverlap >= kbChunkSize) {
      alert('Chunk Overlap 必须小于 Chunk Size');
      return;
    }

    try {
      setIsSavingKb(true);
      if (editingKb) {
        await updateKnowledgeBase(editingKb.id, {
          name: kbName.trim(),
          description: kbDescription,
          embeddingModel: kbEmbeddingModel,
          chunkSize: kbChunkSize,
          chunkOverlap: kbChunkOverlap,
        });
      } else {
        await createKnowledgeBase({
          name: kbName.trim(),
          description: kbDescription,
          embeddingModel: kbEmbeddingModel,
          chunkSize: kbChunkSize,
          chunkOverlap: kbChunkOverlap,
        });
      }
      setIsKbModalOpen(false);
      await refreshKnowledgeBases();
    } catch (error: any) {
      console.error(error);
      alert(error?.message || (editingKb ? '更新知识库失败。' : '新建知识库失败。'));
    } finally {
      setIsSavingKb(false);
    }
  };

  const handleDeleteKb = async (kb: KnowledgeBase) => {
    if (!confirm(`确认删除知识库「${kb.name}」吗？此操作会删除其所有文档和向量数据。`)) return;
    try {
      await deleteKnowledgeBase(kb.id);
      if (selectedKb?.id === kb.id) {
        setSelectedKb(null);
        setView('list');
      }
      await refreshKnowledgeBases();
    } catch (error: any) {
      console.error(error);
      alert(error?.message || '删除知识库失败。');
    }
  };

  if (view === 'detail' && selectedKb) {
    return (
      <div className="py-4 pb-10">
        {isDetailLoading ? (
          <div className="rounded-lg border border-white/10 bg-card/40 p-8 text-center text-muted-foreground">知识库详情加载中...</div>
        ) : (
          <KnowledgeBaseDetail
            kb={selectedKb}
            onBack={() => setView('list')}
            onImport={() => setIsUploadOpen(true)}
            onEdit={() => openEditKb(selectedKb)}
            onDelete={() => handleDeleteKb(selectedKb)}
            onDeleteDocument={async (docId) => {
              try {
                await deleteKnowledgeDocument(selectedKb.id, docId);
                await refreshKnowledgeBases();
              } catch (error: any) {
                console.error(error);
                alert(error?.message || '删除文档失败。');
              }
            }}
          />
        )}
        <UploadModal
          kbId={selectedKb.id}
          isOpen={isUploadOpen}
          onClose={() => setIsUploadOpen(false)}
          onUploaded={refreshKnowledgeBases}
        />

        <KnowledgeBaseModal
          isOpen={isKbModalOpen}
          onClose={() => setIsKbModalOpen(false)}
          onSave={handleSaveKb}
          saving={isSavingKb}
          editingKb={editingKb}
          kbName={kbName}
          setKbName={setKbName}
          kbDescription={kbDescription}
          setKbDescription={setKbDescription}
          kbEmbeddingModel={kbEmbeddingModel}
          setKbEmbeddingModel={setKbEmbeddingModel}
          kbChunkSize={kbChunkSize}
          setKbChunkSize={setKbChunkSize}
          kbChunkOverlap={kbChunkOverlap}
          setKbChunkOverlap={setKbChunkOverlap}
          embeddingOptions={embeddingOptions}
          hasDbEmbeddingModels={hasDbEmbeddingModels}
        />
      </div>
    );
  }

  return (
    <div className="space-y-6 animate-in fade-in py-4 pb-10">
      <div className="flex items-center justify-between">
        <h1 className="text-2xl font-bold tracking-tight text-white">知识库</h1>
      </div>

      <div className="bg-card/50 p-4 rounded-lg border border-white/5 shadow-sm">
        <div className="relative w-full">
          <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 w-full"
            value={searchTerm}
            onChange={(e) => setSearchTerm(e.target.value)}
          />
        </div>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
        {filteredKbs.map((kb) => (
          <Card
            key={kb.id}
            className="p-6 hover:border-primary/50 transition-colors cursor-pointer group relative"
            onClick={() => handleSelect(kb)}
          >
            <div className="absolute top-3 right-3 z-20">
              <Button
                variant="ghost"
                size="icon"
                title="更多操作"
                onClick={(e) => {
                  e.stopPropagation();
                  setOpenMenuKbId((prev) => (prev === kb.id ? null : kb.id));
                }}
              >
                <MoreHorizontal className="h-4 w-4" />
              </Button>
              {openMenuKbId === kb.id && (
                <div
                  className="absolute right-0 mt-1 w-36 rounded-md border border-white/10 bg-card/95 backdrop-blur-md shadow-lg overflow-hidden"
                  onClick={(e) => e.stopPropagation()}
                >
                  <button
                    className="w-full text-left px-3 py-2 text-sm hover:bg-white/10 text-destructive"
                    onClick={() => {
                      setOpenMenuKbId(null);
                      handleDeleteKb(kb);
                    }}
                  >
                    删除
                  </button>
                </div>
              )}
            </div>
            <div className="flex items-start justify-between mb-4">
              <div className="p-2 bg-primary/10 rounded-lg text-primary">
                <FileText className="h-6 w-6" />
              </div>
            </div>
            <h3 className="text-lg font-semibold group-hover:text-primary transition-colors text-white">{kb.name}</h3>
            <div className="mt-2">
              <Badge variant="outline">{kb.embeddingModel || 'embedding'}</Badge>
            </div>
            <div className="mt-4 space-y-1 text-sm text-muted-foreground">
              <p>文档数量: {kb.documents.length}</p>
              <p>分片数量: {kb.chunkSize ?? 500}/{kb.chunkOverlap ?? 50}</p>
              <p>创建时间: {kb.createdAt}</p>
            </div>
          </Card>
        ))}

        <div
          onClick={openCreateKb}
          className="border border-dashed border-white/10 rounded-xl p-6 flex flex-col items-center justify-center text-muted-foreground hover:bg-white/5 hover:border-primary/30 transition-all cursor-pointer min-h-[200px]"
        >
          <Plus className="h-8 w-8 mb-2 opacity-50" />
          <span>新建知识库</span>
        </div>

        {!isLoading && filteredKbs.length === 0 && (
          <div className="col-span-full text-center text-muted-foreground py-8">暂无知识库</div>
        )}
        {isLoading && (
          <div className="col-span-full text-center text-muted-foreground py-8">加载中...</div>
        )}
      </div>

      <KnowledgeBaseModal
        isOpen={isKbModalOpen}
        onClose={() => setIsKbModalOpen(false)}
        onSave={handleSaveKb}
        saving={isSavingKb}
        editingKb={editingKb}
        kbName={kbName}
        setKbName={setKbName}
        kbDescription={kbDescription}
        setKbDescription={setKbDescription}
        kbEmbeddingModel={kbEmbeddingModel}
        setKbEmbeddingModel={setKbEmbeddingModel}
        kbChunkSize={kbChunkSize}
        setKbChunkSize={setKbChunkSize}
        kbChunkOverlap={kbChunkOverlap}
        setKbChunkOverlap={setKbChunkOverlap}
        embeddingOptions={embeddingOptions}
        hasDbEmbeddingModels={hasDbEmbeddingModels}
      />
    </div>
  );
};

const KnowledgeBaseModal: React.FC<{
  isOpen: boolean;
  onClose: () => void;
  onSave: () => Promise<void>;
  saving: boolean;
  editingKb: KnowledgeBase | null;
  kbName: string;
  setKbName: (v: string) => void;
  kbDescription: string;
  setKbDescription: (v: string) => void;
  kbEmbeddingModel: string;
  setKbEmbeddingModel: (v: string) => void;
  kbChunkSize: number;
  setKbChunkSize: (v: number) => void;
  kbChunkOverlap: number;
  setKbChunkOverlap: (v: number) => void;
  embeddingOptions: string[];
  hasDbEmbeddingModels: boolean;
}> = ({
  isOpen,
  onClose,
  onSave,
  saving,
  editingKb,
  kbName,
  setKbName,
  kbDescription,
  setKbDescription,
  kbEmbeddingModel,
  setKbEmbeddingModel,
  kbChunkSize,
  setKbChunkSize,
  kbChunkOverlap,
  setKbChunkOverlap,
  embeddingOptions,
  hasDbEmbeddingModels,
}) => (
  <Dialog
    isOpen={isOpen}
    onClose={onClose}
    title={editingKb ? '编辑知识库' : '新建知识库'}
    footer={
      <>
        <Button variant="ghost" onClick={onClose}>取消</Button>
        <Button onClick={onSave} disabled={saving || !kbName.trim()}>{saving ? '保存中...' : (editingKb ? '保存修改' : '确认创建')}</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">知识库名称</label>
        <Input
          value={kbName}
          onChange={(e) => setKbName(e.target.value)}
          placeholder="请输入知识库名称..."
          autoFocus
          onKeyDown={(e) => e.key === 'Enter' && onSave()}
        />
      </div>

      <div className="space-y-1.5">
        <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">描述</label>
        <textarea
          className="flex min-h-[80px] w-full rounded-md border border-white/10 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"
          value={kbDescription}
          onChange={(e) => setKbDescription(e.target.value)}
          placeholder="描述知识库用途与内容范围..."
        />
      </div>

      <div className="grid grid-cols-1 md:grid-cols-3 gap-3">
        <div className="space-y-1.5">
          <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">Embedding Model</label>
          <select
            className="flex h-9 w-full rounded-md border-0 bg-white/5 px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/50 [&>option]:bg-card text-foreground"
            value={kbEmbeddingModel}
            onChange={(e) => setKbEmbeddingModel(e.target.value)}
          >
            {embeddingOptions.map((m) => (
              <option key={m} value={m}>{m}</option>
            ))}
          </select>
        </div>
        <div className="space-y-1.5">
          <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">Chunk Size</label>
          <Input type="number" min={1} value={kbChunkSize} onChange={(e) => setKbChunkSize(parseInt(e.target.value || '0', 10))} />
        </div>
        <div className="space-y-1.5">
          <label className="text-[10px] font-black text-muted-foreground uppercase tracking-widest block">Chunk Overlap</label>
          <Input type="number" min={0} value={kbChunkOverlap} onChange={(e) => setKbChunkOverlap(parseInt(e.target.value || '0', 10))} />
        </div>
      </div>

      {!hasDbEmbeddingModels && (
        <p className="text-xs text-yellow-400/90">
          未在 LLM Library 检测到 `embedding` 类型模型，当前使用默认 embedding 选项。
        </p>
      )}

      <p className="text-xs text-muted-foreground">
        使用 ChromaDB 作为向量存储。若知识库已有已索引分片，不能直接变更 Embedding Model，需要先删除文档后重建。
      </p>
    </div>
  </Dialog>
);

const KnowledgeBaseDetail: React.FC<{
  kb: KnowledgeBase;
  onBack: () => void;
  onImport: () => void;
  onEdit: () => void;
  onDelete: () => void;
  onDeleteDocument: (docId: string) => void;
}> = ({ kb, onBack, onImport, onEdit, onDelete, onDeleteDocument }) => {
  const [docSearch, setDocSearch] = useState('');
  const filteredDocs = kb.documents.filter((d) => d.name.toLowerCase().includes(docSearch.toLowerCase()));

  return (
    <div className="space-y-6 animate-in slide-in-from-right-4">
      <div className="flex items-center justify-between">
        <div className="flex items-center space-x-4">
          <Button variant="ghost" size="icon" onClick={onBack}>
            <ArrowLeft className="h-4 w-4" />
          </Button>
          <div>
            <h1 className="text-2xl font-bold text-white">{kb.name}</h1>
            <p className="text-sm text-muted-foreground">创建于 {kb.createdAt} · {kb.embeddingModel} · by {kb.creator}</p>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <Button variant="outline" onClick={onEdit}><Settings2 className="mr-2 h-4 w-4" /> 编辑配置</Button>
          <Button onClick={onImport}><Upload className="mr-2 h-4 w-4" /> 新增知识 (导入)</Button>
          <Button variant="ghost" className="text-destructive" onClick={onDelete}><Trash2 className="mr-2 h-4 w-4" /> 删除</Button>
        </div>
      </div>

      <Card className="overflow-hidden border-white/5">
        <div className="p-4 border-b border-white/5 flex justify-between items-center bg-white/5">
          <h3 className="font-medium text-white">文档列表</h3>
          <div className="w-64">
            <Input
              placeholder="搜索文档..."
              value={docSearch}
              onChange={(e) => setDocSearch(e.target.value)}
              className="bg-black/20 border-transparent focus:bg-black/40"
            />
          </div>
        </div>
        <table className="w-full text-sm">
          <TableHeader>
            <TableRow>
              <TableHead>文档名称</TableHead>
              <TableHead>大小</TableHead>
              <TableHead>上传时间</TableHead>
              <TableHead className="text-right">操作</TableHead>
            </TableRow>
          </TableHeader>
          <tbody>
            {filteredDocs.length > 0 ? filteredDocs.map((doc) => (
              <TableRow key={doc.id}>
                <TableCell className="font-medium flex items-center text-white">
                  <FileText className="h-4 w-4 mr-2 text-primary" /> {doc.name}
                </TableCell>
                <TableCell className="text-muted-foreground">{doc.size}</TableCell>
                <TableCell className="text-muted-foreground">{doc.uploadDate}</TableCell>
                <TableCell className="text-right">
                  <Button
                    variant="ghost"
                    size="sm"
                    className="text-destructive hover:text-destructive/80"
                    onClick={() => onDeleteDocument(doc.id)}
                  >
                    删除
                  </Button>
                </TableCell>
              </TableRow>
            )) : (
              <TableRow>
                <TableCell colSpan={4} className="text-center py-8 text-muted-foreground">暂无文档</TableCell>
              </TableRow>
            )}
          </tbody>
        </table>
      </Card>
    </div>
  );
};

const UploadModal: React.FC<{ kbId: string; isOpen: boolean; onClose: () => void; onUploaded: () => Promise<void> }> = ({ kbId, isOpen, onClose, onUploaded }) => {
  const [dragActive, setDragActive] = useState(false);
  const [files, setFiles] = useState<File[]>([]);
  const inputRef = useRef<HTMLInputElement>(null);

  const handleDrag = (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    if (e.type === 'dragenter' || e.type === 'dragover') {
      setDragActive(true);
    } else if (e.type === 'dragleave') {
      setDragActive(false);
    }
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setDragActive(false);
    if (e.dataTransfer.files && e.dataTransfer.files[0]) {
      setFiles((prev) => [...prev, ...Array.from(e.dataTransfer.files)]);
    }
  };

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    e.preventDefault();
    if (e.target.files && e.target.files[0]) {
      setFiles((prev) => [...prev, ...Array.from(e.target.files || [])]);
    }
  };

  const removeFile = (idx: number) => {
    setFiles((prev) => prev.filter((_, i) => i !== idx));
  };

  const handleUpload = async () => {
    if (files.length === 0) return;
    try {
      await Promise.all(files.map((file) => uploadKnowledgeDocument(kbId, file)));
      await onUploaded();
      onClose();
      setFiles([]);
    } catch (error: any) {
      console.error(error);
      alert(error?.message || '上传失败，请稍后重试。');
    }
  };

  return (
    <Dialog
      isOpen={isOpen}
      onClose={onClose}
      title="上传知识文档"
      footer={
        <>
          <Button variant="ghost" onClick={onClose}>取消</Button>
          <Button onClick={handleUpload}>确认上传</Button>
        </>
      }
    >
      <div
        className={`relative flex flex-col items-center justify-center w-full h-48 rounded-lg border-2 border-dashed transition-colors ${dragActive ? 'border-primary bg-primary/10' : 'border-white/10 bg-white/5 hover:bg-white/10'}`}
        onDragEnter={handleDrag}
        onDragLeave={handleDrag}
        onDragOver={handleDrag}
        onDrop={handleDrop}
        onClick={() => inputRef.current?.click()}
      >
        <input
          ref={inputRef}
          type="file"
          multiple
          className="hidden"
          onChange={handleChange}
          accept=".pdf,.doc,.docx,.txt,.md"
        />
        <CloudUpload className={`h-10 w-10 mb-3 ${dragActive ? 'text-primary' : 'text-muted-foreground'}`} />
        <p className="text-sm text-muted-foreground text-center">
          <span className="font-semibold text-primary">点击上传</span> 或将文件拖拽到此处
        </p>
        <p className="text-xs text-muted-foreground mt-1 text-white/50">支持 PDF, DOCX, TXT (Max 10MB)</p>
      </div>

      {files.length > 0 && (
        <div className="mt-4 space-y-2 max-h-40 overflow-y-auto pr-1 custom-scrollbar">
          {files.map((file, idx) => (
            <div key={idx} className="flex items-center justify-between p-2 rounded-md bg-white/5 border border-white/5">
              <div className="flex items-center space-x-2 overflow-hidden">
                <FileIcon className="h-4 w-4 text-primary shrink-0" />
                <span className="text-sm truncate max-w-[200px] text-white">{file.name}</span>
                <span className="text-xs text-muted-foreground">({(file.size / 1024).toFixed(1)} KB)</span>
              </div>
              <button onClick={() => removeFile(idx)} className="text-muted-foreground hover:text-destructive transition-colors">
                <X className="h-4 w-4" />
              </button>
            </div>
          ))}
        </div>
      )}
    </Dialog>
  );
};
