"use client";

import { ChangeEvent, useCallback, useEffect, useMemo, useState } from "react";
import { Braces, Database, Loader2, MessageSquare, RefreshCw, Trash2, Upload } from "lucide-react";
import DashboardLayout from "@/components/layout/dashboard-layout";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { useToast } from "@/components/ui/use-toast";
import {
  CodeKnowledgeBase,
  CodeQuestionResponse,
  askCodeKnowledgeBase,
  deleteCodeKnowledgeBase,
  listCodeKnowledgeBases,
  uploadCodeKnowledgeBase,
} from "@/lib/consistency-api";

const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

const formatDateTime = (value?: string | null) => {
  if (!value) {
    return "-";
  }
  return new Date(value).toLocaleString("zh-CN");
};

export default function CodeKnowledgeBasePage() {
  const [knowledgeBases, setKnowledgeBases] = useState<CodeKnowledgeBase[]>([]);
  const [selectedKbId, setSelectedKbId] = useState<number | "">("");
  const [files, setFiles] = useState<File[]>([]);
  const [name, setName] = useState("");
  const [useSemantic, setUseSemantic] = useState(true);
  const [isUploading, setIsUploading] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const [question, setQuestion] = useState("");
  const [isAsking, setIsAsking] = useState(false);
  const [deletingKbId, setDeletingKbId] = useState<number | null>(null);
  const [answer, setAnswer] = useState<CodeQuestionResponse | null>(null);
  const { toast } = useToast();

  const selectedKb = useMemo(
    () => knowledgeBases.find((item) => item.id === selectedKbId) ?? null,
    [knowledgeBases, selectedKbId]
  );

  const loadKnowledgeBases = useCallback(async () => {
    setIsLoading(true);
    try {
      const items = await listCodeKnowledgeBases();
      setKnowledgeBases(items);
      setSelectedKbId((current) => {
        if (current && items.some((item) => item.id === current)) {
          return current;
        }
        return items.find((item) => item.status === "active")?.id || items[0]?.id || "";
      });
    } catch (error) {
      const message = error instanceof Error ? error.message : "加载失败";
      toast({ title: "加载失败", description: message, variant: "destructive" });
    } finally {
      setIsLoading(false);
    }
  }, [toast]);

  useEffect(() => {
    void loadKnowledgeBases();
  }, [loadKnowledgeBases]);

  const handleFiles = (event: ChangeEvent<HTMLInputElement>) => {
    const nextFiles = Array.from(event.target.files || []);
    setFiles(nextFiles);
    if (!name && nextFiles[0]) {
      setName(nextFiles[0].name.replace(/\.[^.]+$/, ""));
    }
  };

  const pollCodeKb = async (id: number) => {
    for (let index = 0; index < 300; index += 1) {
      const items = await listCodeKnowledgeBases();
      setKnowledgeBases(items);
      const hit = items.find((item) => item.id === id);
      if (!hit) {
        throw new Error("代码知识库记录不存在");
      }
      if (hit.status === "active") {
        setSelectedKbId(hit.id);
        return;
      }
      if (hit.status === "failed") {
        const error = String(hit.metadata_summary?.error_message || "构建失败");
        throw new Error(error);
      }
      await wait(2000);
    }
    throw new Error("代码知识库仍在后台构建，请稍后刷新查看。");
  };

  const handleUpload = async () => {
    if (!name.trim() || files.length === 0) {
      toast({
        title: "缺少输入",
        description: "请填写名称并选择代码文件或 zip 包。",
        variant: "destructive",
      });
      return;
    }
    setIsUploading(true);
    try {
      const created = await uploadCodeKnowledgeBase(name.trim(), files, useSemantic);
      toast({ title: "构建已启动", description: `代码知识库任务 #${created.id}` });
      await pollCodeKb(created.id);
      toast({ title: "构建完成", description: "现在可以针对代码内容提问。" });
    } catch (error) {
      const message = error instanceof Error ? error.message : "上传或构建失败";
      toast({
        title: message.includes("后台构建") ? "构建仍在进行" : "构建失败",
        description: message,
        variant: message.includes("后台构建") ? "default" : "destructive",
      });
    } finally {
      setIsUploading(false);
    }
  };

  const handleSelectKb = (id: number) => {
    setSelectedKbId(id);
    setAnswer(null);
  };

  const handleDeleteKb = async (item: CodeKnowledgeBase) => {
    const confirmed = window.confirm(`确认删除代码知识库 ${item.name}？`);
    if (!confirmed) {
      return;
    }

    setDeletingKbId(item.id);
    try {
      await deleteCodeKnowledgeBase(item.id);
      const items = await listCodeKnowledgeBases();
      setKnowledgeBases(items);
      setSelectedKbId((current) => {
        if (current !== item.id && current && items.some((entry) => entry.id === current)) {
          return current;
        }
        return items.find((entry) => entry.status === "active")?.id || items[0]?.id || "";
      });
      if (selectedKbId === item.id) {
        setAnswer(null);
      }
      toast({ title: "删除成功", description: "代码知识库已删除。" });
    } catch (error) {
      const message = error instanceof Error ? error.message : "删除失败";
      toast({ title: "删除失败", description: message, variant: "destructive" });
    } finally {
      setDeletingKbId(null);
    }
  };

  const handleAsk = async () => {
    if (!selectedKb || !question.trim()) {
      toast({
        title: "缺少输入",
        description: "请选择已完成的代码知识库并输入问题。",
        variant: "destructive",
      });
      return;
    }
    if (selectedKb.status !== "active") {
      toast({
        title: "代码知识库未就绪",
        description: "请等待构建完成后再提问。",
        variant: "destructive",
      });
      return;
    }
    setIsAsking(true);
    try {
      const result = await askCodeKnowledgeBase(selectedKb.id, question.trim(), 6, true);
      setAnswer(result);
    } catch (error) {
      const message = error instanceof Error ? error.message : "问答失败";
      toast({ title: "问答失败", description: message, variant: "destructive" });
    } finally {
      setIsAsking(false);
    }
  };

  return (
    <DashboardLayout>
      <div className="space-y-6">
        <Card>
          <CardHeader>
            <CardTitle className="text-2xl">代码知识库</CardTitle>
            <CardDescription>
              上传 C/C++ 源码文件或 zip 工程包，后台调用 RAG-TEST-TOOLS 构建函数级代码知识库。
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="grid gap-4 md:grid-cols-2">
              <div className="space-y-2">
                <Label>知识库名称</Label>
                <Input value={name} onChange={(event) => setName(event.target.value)} />
              </div>
              <div className="space-y-2">
                <Label>语义增强</Label>
                <select
                  className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm"
                  value={useSemantic ? "true" : "false"}
                  onChange={(event) => setUseSemantic(event.target.value === "true")}
                >
                  <option value="true">生成函数摘要和 embedding</option>
                  <option value="false">仅解析结构，跳过模型调用</option>
                </select>
              </div>
              <div className="space-y-2 md:col-span-2">
                <Label>代码文件</Label>
                <Input
                  type="file"
                  multiple
                  accept=".zip,.c,.cpp,.h,.hpp,.tcc"
                  onChange={handleFiles}
                />
                <p className="text-xs text-muted-foreground">
                  已选择 {files.length} 个文件；上传 zip 时会自动解压后构建。
                </p>
              </div>
            </div>
            <div className="flex flex-wrap gap-3">
              <Button onClick={handleUpload} disabled={isUploading}>
                {isUploading ? (
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                ) : (
                  <Upload className="mr-2 h-4 w-4" />
                )}
                上传并构建
              </Button>
              <Button variant="outline" onClick={() => void loadKnowledgeBases()} disabled={isLoading}>
                <RefreshCw className="mr-2 h-4 w-4" />
                刷新
              </Button>
            </div>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle className="text-lg">代码知识库列表</CardTitle>
            <CardDescription>选择一个已完成构建的知识库用于问答或一致性比对。</CardDescription>
          </CardHeader>
          <CardContent>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>名称</TableHead>
                  <TableHead>状态</TableHead>
                  <TableHead>函数数</TableHead>
                  <TableHead>创建时间</TableHead>
                  <TableHead className="text-right">操作</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {knowledgeBases.length === 0 && (
                  <TableRow>
                    <TableCell colSpan={5} className="text-center text-muted-foreground">
                      暂无代码知识库
                    </TableCell>
                  </TableRow>
                )}
                {knowledgeBases.map((item) => (
                  <TableRow key={item.id}>
                    <TableCell>
                      <p className="font-medium">{item.name}</p>
                      {item.status === "failed" && Boolean(item.metadata_summary?.error_message) && (
                        <p className="mt-1 line-clamp-2 text-xs text-muted-foreground">
                          {String(item.metadata_summary?.error_message || "")}
                        </p>
                      )}
                    </TableCell>
                    <TableCell>
                      <Badge
                        variant={
                          item.status === "failed"
                            ? "destructive"
                            : item.status === "active"
                            ? "default"
                            : "secondary"
                        }
                      >
                        {item.status}
                      </Badge>
                    </TableCell>
                    <TableCell>{String(item.metadata_summary?.function_count ?? "-")}</TableCell>
                    <TableCell>{formatDateTime(item.created_at)}</TableCell>
                    <TableCell className="text-right">
                      <div className="flex justify-end gap-2">
                        <Button
                          size="sm"
                          variant={selectedKbId === item.id ? "secondary" : "outline"}
                          onClick={() => handleSelectKb(item.id)}
                          disabled={item.status !== "active"}
                        >
                          <Database className="mr-1 h-3.5 w-3.5" />
                          {selectedKbId === item.id ? "已选择" : "选择"}
                        </Button>
                        <Button
                          size="sm"
                          variant="destructive"
                          onClick={() => void handleDeleteKb(item)}
                          disabled={deletingKbId === item.id}
                        >
                          {deletingKbId === item.id ? (
                            <Loader2 className="mr-1 h-3.5 w-3.5 animate-spin" />
                          ) : (
                            <Trash2 className="mr-1 h-3.5 w-3.5" />
                          )}
                          删除
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle className="text-lg">代码问答</CardTitle>
            <CardDescription>问题会先检索函数级证据，再基于证据生成回答。</CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="space-y-2">
              <Label>当前知识库</Label>
              <p className="rounded-md border p-3 text-sm text-muted-foreground">
                {selectedKb ? `${selectedKb.name} · ${selectedKb.status}` : "未选择"}
              </p>
            </div>
            <div className="space-y-2">
              <Label>问题</Label>
              <textarea
                className="min-h-[100px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                value={question}
                onChange={(event) => setQuestion(event.target.value)}
                placeholder="例如：姿态控制初始化逻辑在哪里实现？调用链是什么？"
              />
            </div>
            <Button
              onClick={handleAsk}
              disabled={isAsking || !selectedKb || selectedKb.status !== "active" || !question.trim()}
            >
              {isAsking ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              ) : (
                <MessageSquare className="mr-2 h-4 w-4" />
              )}
              提问
            </Button>

            {answer && (
              <div className="space-y-4">
                <div className="rounded-md border p-4">
                  <h3 className="mb-2 flex items-center gap-2 text-sm font-medium">
                    <Braces className="h-4 w-4" />
                    回答
                  </h3>
                  <p className="whitespace-pre-wrap text-sm text-muted-foreground">{answer.answer}</p>
                </div>

                <div className="space-y-2">
                  <h3 className="text-sm font-medium">函数证据</h3>
                  {answer.evidence.map((item, index) => (
                    <div key={`${item.node_id}-${index}`} className="rounded-md border p-3 text-sm">
                      <p className="font-medium">
                        {item.name} · similarity {Number(item.similarity || 0).toFixed(2)}
                      </p>
                      <p className="text-xs text-muted-foreground">
                        {item.file}:{item.start_line}-{item.end_line}
                      </p>
                      <p className="mt-2 line-clamp-3 text-xs text-muted-foreground">
                        {item.summary || item.evidence_summary || "-"}
                      </p>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </CardContent>
        </Card>
      </div>
    </DashboardLayout>
  );
}
