import React, { FC, useMemo, useEffect, useState, ClassAttributes } from "react";
import { AnchorHTMLAttributes } from "react";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Skeleton } from "@/components/ui/skeleton";
import { Divider } from "@/components/ui/divider";
import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";
import rehypeHighlight from "rehype-highlight";
import { api } from "@/lib/api";
import { FileIcon } from "react-file-icon";

interface Citation {
  id: number;
  text: string;
  metadata: Record<string, any>;
}

interface KnowledgeBaseInfo {
  name: string;
}

interface DocumentInfo {
  file_name: string;
  knowledge_base: KnowledgeBaseInfo;
}

interface CitationInfo {
  knowledge_base: KnowledgeBaseInfo;
  document: DocumentInfo;
}

type CitationLinkProps = ClassAttributes<HTMLAnchorElement> &
  AnchorHTMLAttributes<HTMLAnchorElement> & {
    citations: Citation[];
    citationInfoMap: Record<string, CitationInfo>;
  };

const CitationLink: FC<CitationLinkProps> = ({
  citations,
  citationInfoMap,
  ...props
}) => {
  const [open, setOpen] = useState(false);
  const citationId = props.href?.match(/^(\d+)$/)?.[1];
  const citation = citationId ? citations[parseInt(citationId) - 1] : null;

  if (!citation) {
    return <a>[{props.href}]</a>;
  }

  const citationInfo =
    citationInfoMap[
      `${citation.metadata.kb_id}-${citation.metadata.document_id}`
    ];

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <a
          {...props}
          href="#"
          role="button"
          onClick={(event) => {
            event.preventDefault();
            setOpen((prev) => !prev);
          }}
          onMouseEnter={() => setOpen(true)}
          onMouseLeave={() => setOpen(false)}
          className="inline-flex items-center px-1.5 py-0.5 text-xs font-medium text-blue-600 bg-blue-50 rounded hover:bg-blue-100 transition-colors"
        >
          [{props.href}]
        </a>
      </PopoverTrigger>
      <PopoverContent
        side="top"
        align="start"
        onMouseEnter={() => setOpen(true)}
        onMouseLeave={() => setOpen(false)}
        className="max-w-2xl w-[calc(100vw-100px)] max-h-[70vh] overflow-auto p-4 rounded-lg shadow-lg"
      >
        <div className="text-sm space-y-3">
          {citationInfo && (
            <div className="flex items-center gap-2 text-xs font-medium text-gray-700 bg-gray-50 p-2 rounded">
              <div className="w-5 h-5 flex items-center justify-center">
                <FileIcon
                  extension={citationInfo.document.file_name.split(".").pop() || ""}
                  color="#E2E8F0"
                  labelColor="#94A3B8"
                />
              </div>
              <span className="truncate">
                {citationInfo.knowledge_base.name} / {citationInfo.document.file_name}
              </span>
            </div>
          )}
          <Divider />
          <p className="text-gray-700 leading-relaxed">{citation.text}</p>
          <Divider />
          {Object.keys(citation.metadata).length > 0 && (
            <div className="text-xs text-gray-500 bg-gray-50 p-2 rounded">
              <div className="font-medium mb-2">调试信息：</div>
              <div className="space-y-1">
                {Object.entries(citation.metadata).map(([key, value]) => (
                  <div key={key} className="flex">
                    <span className="font-medium min-w-[100px]">{key}:</span>
                    <span className="text-gray-600">{String(value)}</span>
                  </div>
                ))}
              </div>
            </div>
          )}
        </div>
      </PopoverContent>
    </Popover>
  );
};

CitationLink.displayName = "CitationLink";

export const Answer: FC<{
  markdown: string;
  citations?: Citation[];
}> = ({ markdown, citations = [] }) => {
  const [citationInfoMap, setCitationInfoMap] = useState<
    Record<string, CitationInfo>
  >({});

  const processedMarkdown = useMemo(() => {
    return markdown
      .replace(/<think>/g, "## 💭 深度思考\n```think")
      .replace(/<\/think>/g, "```");
  }, [markdown]);

  useEffect(() => {
    const fetchCitationInfo = async () => {
      const infoMap: Record<string, CitationInfo> = {};

      for (const citation of citations) {
        const { kb_id, document_id } = citation.metadata;
        if (!kb_id || !document_id) continue;

        const key = `${kb_id}-${document_id}`;
        if (infoMap[key]) continue;

        try {
          const [kb, doc] = await Promise.all([
            api.get(`/api/knowledge-base/${kb_id}`),
            api.get(`/api/knowledge-base/${kb_id}/documents/${document_id}`),
          ]);

          infoMap[key] = {
            knowledge_base: {
              name: kb.name,
            },
            document: {
              file_name: doc.file_name,
              knowledge_base: {
                name: kb.name,
              },
            },
          };
        } catch (error) {
          console.error("Failed to fetch citation info:", error);
        }
      }

      setCitationInfoMap(infoMap);
    };

    if (citations.length > 0) {
      fetchCitationInfo();
    }
  }, [citations]);

  const CitationLinkRenderer = useMemo(() => {
    const Renderer = (
      props: ClassAttributes<HTMLAnchorElement> &
        AnchorHTMLAttributes<HTMLAnchorElement>
    ) => (
      <CitationLink
        {...props}
        citations={citations}
        citationInfoMap={citationInfoMap}
      />
    );
    Renderer.displayName = "CitationLinkRenderer";
    return Renderer;
  }, [citations, citationInfoMap]);

  if (!markdown) {
    return (
      <div className="flex flex-col gap-2">
        <Skeleton className="max-w-sm h-4 bg-zinc-200" />
        <Skeleton className="max-w-lg h-4 bg-zinc-200" />
        <Skeleton className="max-w-2xl h-4 bg-zinc-200" />
        <Skeleton className="max-w-lg h-4 bg-zinc-200" />
        <Skeleton className="max-w-xl h-4 bg-zinc-200" />
      </div>
    );
  }

  return (
    <div className="prose prose-sm max-w-full">
      <Markdown
        remarkPlugins={[remarkGfm]}
        rehypePlugins={[rehypeHighlight]}
        components={{
          a: CitationLinkRenderer,
        }}
      >
        {processedMarkdown}
      </Markdown>
    </div>
  );
};
