import { useCallback, useEffect, useMemo, useState } from "react";
import {
  App,
  Breadcrumb,
  Button,
  Card,
  Descriptions,
  Empty,
  Modal,
  Table,
  Tooltip,
} from "antd";
import { DeleteOutlined, DownloadOutlined, EditOutlined, EyeOutlined, PlusOutlined } from "@ant-design/icons";
import { useNavigate, useParams } from "react-router";
import DetailHeader from "@/components/DetailHeader";
import { SearchControls } from "@/components/SearchControls";
import useFetchData from "@/hooks/useFetchData";
import {
  deleteKnowledgeItemByIdUsingDelete,
  deleteKnowledgeSetByIdUsingDelete,
  downloadKnowledgeItemFileUsingGet,
  exportKnowledgeItemsUsingGet,
  queryKnowledgeItemsUsingGet,
  queryKnowledgeSetByIdUsingGet,
} from "../knowledge-management.api";
import {
  knowledgeContentTypeOptions,
  knowledgeSourceTypeOptions,
  knowledgeStatusMap,
  mapKnowledgeItem,
  KnowledgeItemView,
} from "../knowledge-management.const";
import {
  KnowledgeItem,
  KnowledgeSet,
  KnowledgeContentType,
  KnowledgeSourceType,
  KnowledgeStatusType,
} from "../knowledge-management.model";
import CreateKnowledgeSet from "../components/CreateKnowledgeSet";
import KnowledgeItemEditor from "../components/KnowledgeItemEditor";
import ImportKnowledgeItemsDialog from "../components/ImportKnowledgeItemsDialog";
import { formatDate } from "@/utils/unit";
import { PREVIEW_TEXT_MAX_LENGTH, resolvePreviewFileType, truncatePreviewText } from "@/utils/filePreview";

const PREVIEW_MAX_HEIGHT = 500;
const PREVIEW_MODAL_WIDTH = {
  text: 800,
  media: 700,
};
const PREVIEW_TEXT_FONT_SIZE = 12;
const PREVIEW_TEXT_PADDING = 12;
const PREVIEW_AUDIO_PADDING = 40;

const KnowledgeSetDetail = () => {
  const navigate = useNavigate();
  const { message } = App.useApp();
  const { id } = useParams<{ id: string }>();
  const [knowledgeSet, setKnowledgeSet] = useState<KnowledgeSet | null>(null);
  const [showEdit, setShowEdit] = useState(false);
  const [itemEditorOpen, setItemEditorOpen] = useState(false);
  const [currentItem, setCurrentItem] = useState<KnowledgeItem | null>(null);
  const [readItemId, setReadItemId] = useState<string | null>(null);
  const [readModalOpen, setReadModalOpen] = useState(false);
  const [readContent, setReadContent] = useState("");
  const [readTitle, setReadTitle] = useState("");
  const [previewVisible, setPreviewVisible] = useState(false);
  const [previewContent, setPreviewContent] = useState("");
  const [previewFileName, setPreviewFileName] = useState("");
  const [previewFileType, setPreviewFileType] = useState<"text" | "image" | "video" | "audio">("text");
  const [previewMediaUrl, setPreviewMediaUrl] = useState("");
  const [previewLoadingItemId, setPreviewLoadingItemId] = useState<string | null>(null);

  const fetchKnowledgeSet = useCallback(async () => {
    if (!id) return;
    const { data } = await queryKnowledgeSetByIdUsingGet(id);
    setKnowledgeSet(data);
  }, [id]);

  useEffect(() => {
    fetchKnowledgeSet();
  }, [fetchKnowledgeSet]);

  const {
    loading,
    tableData: items,
    searchParams,
    pagination,
    fetchData,
    setSearchParams,
    handleFiltersChange,
    handleKeywordChange,
  } = useFetchData<KnowledgeItemView>(
    (params) => (id ? queryKnowledgeItemsUsingGet(id, params) : Promise.resolve({ data: [] })),
    mapKnowledgeItem,
    30000,
    false,
    [],
    0
  );

  const isReadOnly =
    knowledgeSet?.status === KnowledgeStatusType.ARCHIVED ||
    knowledgeSet?.status === KnowledgeStatusType.DEPRECATED;

  const handleDeleteSet = async () => {
    if (!knowledgeSet) return;
    await deleteKnowledgeSetByIdUsingDelete(knowledgeSet.id);
    message.success("知识集已删除");
    navigate("/data/knowledge-management");
  };

  const handleDeleteItem = async (item: KnowledgeItemView) => {
    if (!id) return;
    await deleteKnowledgeItemByIdUsingDelete(id, item.id);
    message.success("知识条目已删除");
    fetchData();
  };

  const handleExportItems = async () => {
    if (!id) return;
    await exportKnowledgeItemsUsingGet(id);
    message.success("知识条目导出成功");
  };

  const isReadableItem = (record: KnowledgeItemView) => {
    if (
      record.contentType === KnowledgeContentType.FILE ||
      record.sourceType === KnowledgeSourceType.FILE_UPLOAD
    ) {
      return false;
    }
    return (
      record.contentType === KnowledgeContentType.TEXT ||
      record.contentType === KnowledgeContentType.MARKDOWN
    );
  };

  const resolvePreviewFileName = (record: KnowledgeItemView) => {
    if (record.sourceFileId) {
      return record.sourceFileId;
    }
    if (record.content) {
      const segments = record.content.split("/");
      const lastSegment = segments[segments.length - 1];
      if (lastSegment) {
        return lastSegment;
      }
    }
    return "文件";
  };

  const handlePreviewItemFile = async (record: KnowledgeItemView) => {
    if (!id) return;
    const fileName = resolvePreviewFileName(record);
    const fileType = resolvePreviewFileType(fileName);
    if (!fileType) {
      message.warning("不支持预览该文件类型");
      return;
    }

    const previewUrl = `/api/data-management/knowledge-sets/${id}/items/${record.id}/preview`;
    setPreviewFileName(fileName);
    setPreviewFileType(fileType);
    setPreviewContent("");
    setPreviewMediaUrl("");

    if (fileType === "text") {
      setPreviewLoadingItemId(record.id);
      try {
        const response = await fetch(previewUrl);
        if (!response.ok) {
          throw new Error("下载失败");
        }
        const text = await response.text();
        setPreviewContent(truncatePreviewText(text, PREVIEW_TEXT_MAX_LENGTH));
        setPreviewVisible(true);
      } catch (error) {
        console.error("预览知识条目文件失败", error);
        message.error("预览失败，请稍后重试");
      } finally {
        setPreviewLoadingItemId(null);
      }
      return;
    }

    setPreviewMediaUrl(previewUrl);
    setPreviewVisible(true);
  };

  const closePreview = () => {
    setPreviewVisible(false);
    setPreviewContent("");
    setPreviewMediaUrl("");
    setPreviewFileName("");
    setPreviewFileType("text");
  };

  const handleReadItem = async (record: KnowledgeItemView) => {
    if (
      record.contentType === KnowledgeContentType.FILE ||
      record.sourceType === KnowledgeSourceType.FILE_UPLOAD
    ) {
      message.info("该条目为文件，请使用下载查看");
      return;
    }
    setReadItemId(record.id);
    setReadTitle("知识条目");

    if (!record.sourceDatasetId || !record.sourceFileId) {
      const content = record.content || "";
      setReadContent(truncatePreviewText(content, PREVIEW_TEXT_MAX_LENGTH));
      setReadModalOpen(true);
      setReadItemId(null);
      return;
    }

    const fileUrl = `/api/data-management/datasets/${record.sourceDatasetId}/files/${record.sourceFileId}/download`;

    try {
      const response = await fetch(fileUrl);
      if (!response.ok) {
        throw new Error("下载失败");
      }
      const text = await response.text();
      setReadContent(truncatePreviewText(text, PREVIEW_TEXT_MAX_LENGTH));
      setReadModalOpen(true);
    } catch (error) {
      console.error("读取知识条目失败", error);
      message.error("读取失败，请稍后重试");
    } finally {
      setReadItemId(null);
    }
  };

  const handleDownloadItem = async (record: KnowledgeItemView) => {
    if (!id) return;
    try {
      await downloadKnowledgeItemFileUsingGet(id, record.id, record.sourceFileId);
    } catch (error) {
      console.error("下载知识条目文件失败", error);
      message.error("下载失败，请稍后重试");
    }
  };

  const statusMeta = knowledgeSet?.status
    ? knowledgeStatusMap[knowledgeSet.status]
    : undefined;

  const statistics = useMemo(
    () => [
      {
        key: "items",
        icon: <PlusOutlined className="text-blue-500" />,
        label: "条目数",
        value: pagination.total || 0,
      },
      {
        key: "updated",
        icon: <EditOutlined className="text-gray-500" />,
        label: "更新时间",
        value: knowledgeSet?.updatedAt ? formatDate(knowledgeSet.updatedAt) : "-",
      },
    ],
    [pagination.total, knowledgeSet?.updatedAt]
  );

  const itemColumns = [
    {
      title: "文件名",
      dataIndex: "sourceFileId",
      key: "sourceFileId",
      fixed: "left" as const,
      width: 260,
      ellipsis: true,
      render: (_: string, record: KnowledgeItemView) => {
        if (
          record.contentType === KnowledgeContentType.FILE ||
          record.sourceType === KnowledgeSourceType.FILE_UPLOAD
        ) {
          return resolvePreviewFileName(record);
        }
        return record.sourceFileId || "-";
      },
    },
    {
      title: "类型",
      dataIndex: "contentType",
      key: "contentType",
      width: 120,
      render: (contentType: string) =>
        knowledgeContentTypeOptions.find((opt) => opt.value === contentType)?.label ||
        contentType,
    },
    {
      title: "来源",
      dataIndex: "sourceType",
      key: "sourceType",
      width: 140,
      ellipsis: true,
      render: (sourceType: string) =>
        knowledgeSourceTypeOptions.find((opt) => opt.value === sourceType)?.label ||
        sourceType ||
        "-",
    },
    {
      title: "更新时间",
      dataIndex: "updatedAt",
      key: "updatedAt",
      width: 180,
      ellipsis: true,
    },
    {
      title: "操作",
      key: "actions",
      width: 200,
      render: (_: unknown, record: KnowledgeItemView) => (
        <div className="flex items-center gap-2">
          {isReadableItem(record) && (
            <Tooltip title="阅读">
              <Button
                type="text"
                icon={<EyeOutlined />}
                onClick={() => handleReadItem(record)}
                loading={readItemId === record.id}
                aria-label="阅读"
              />
            </Tooltip>
          )}
          {(() => {
            const isFileRecord =
              record.contentType === KnowledgeContentType.FILE ||
              record.sourceType === KnowledgeSourceType.FILE_UPLOAD;
            return (
              <>
                {isFileRecord && (
                  <Tooltip title="预览">
                    <Button
                      type="text"
                      icon={<EyeOutlined />}
                      onClick={() => handlePreviewItemFile(record)}
                      loading={previewLoadingItemId === record.id}
                      aria-label="预览"
                    />
                  </Tooltip>
                )}
                {isFileRecord && (
                  <Tooltip title="下载文件">
                    <Button
                      type="text"
                      icon={<DownloadOutlined />}
                      onClick={() => handleDownloadItem(record)}
                      aria-label="下载文件"
                    />
                  </Tooltip>
                )}
                {isFileRecord && (
                  <Button
                    type="text"
                    icon={<EditOutlined />}
                    onClick={() => {
                      setCurrentItem({
                        ...(record as unknown as KnowledgeItem),
                        status: record.rawStatus,
                      });
                      setItemEditorOpen(true);
                    }}
                    disabled={
                      isReadOnly ||
                      record.rawStatus === KnowledgeStatusType.ARCHIVED ||
                      record.rawStatus === KnowledgeStatusType.DEPRECATED
                    }
                  />
                )}
              </>
            );
          })()}
          <Button
            type="text"
            danger
            icon={<DeleteOutlined />}
            onClick={() => handleDeleteItem(record)}
            disabled={isReadOnly}
          />
        </div>
      ),
    },
  ];

  return (
    <div className="h-full flex flex-col">
      <div className="mb-4">
        <Breadcrumb>
          <Breadcrumb.Item>
            <a onClick={() => navigate("/data/knowledge-management")}>知识管理</a>
          </Breadcrumb.Item>
          <Breadcrumb.Item>{knowledgeSet?.name || "-"}</Breadcrumb.Item>
        </Breadcrumb>
      </div>

      <DetailHeader
        data={{
          name: knowledgeSet?.name,
          description: knowledgeSet?.description,
          status: statusMeta,
          tags: knowledgeSet?.tags,
        }}
        statistics={statistics}
        operations={[
          {
            key: "edit",
            label: "编辑",
            icon: <EditOutlined />,
            onClick: () => setShowEdit(true),
            danger: false,
          },
          {
            key: "export",
            label: "导出",
            icon: <DownloadOutlined />,
            onClick: handleExportItems,
          },
          {
            key: "delete",
            label: "删除",
            icon: <DeleteOutlined />,
            danger: true,
            confirm: {
              title: "确认删除该知识集吗？",
              description: "删除后将无法恢复，请谨慎操作。",
              cancelText: "取消",
              okText: "删除",
              okType: "danger",
              onConfirm: () => handleDeleteSet(),
            },
          },
        ]}
      />

      <CreateKnowledgeSet
        showBtn={false}
        isEdit={showEdit}
        data={knowledgeSet}
        onUpdate={() => {
          setShowEdit(false);
          fetchKnowledgeSet();
        }}
        onClose={() => setShowEdit(false)}
      />

      <Card className="mt-4">
        <Descriptions column={2} size="small">
          <Descriptions.Item label="领域">{knowledgeSet?.domain || "-"}</Descriptions.Item>
          <Descriptions.Item label="业务线">{knowledgeSet?.businessLine || "-"}</Descriptions.Item>
          <Descriptions.Item label="负责人">{knowledgeSet?.owner || "-"}</Descriptions.Item>
          <Descriptions.Item label="敏感级别">{knowledgeSet?.sensitivity || "-"}</Descriptions.Item>
          <Descriptions.Item label="有效期">
            {knowledgeSet?.validFrom || "-"} ~ {knowledgeSet?.validTo || "-"}
          </Descriptions.Item>
          <Descriptions.Item label="来源类型">{knowledgeSet?.sourceType || "-"}</Descriptions.Item>
        </Descriptions>
      </Card>

      <div className="flex-1 border-card p-6 mt-4">
        <div className="flex items-center justify-between mb-4 gap-3">
          <SearchControls
            searchTerm={searchParams.keyword}
            onSearchChange={handleKeywordChange}
            searchPlaceholder="搜索文件名或内容"
            filters={[]}
            onFiltersChange={handleFiltersChange}
            onClearFilters={() => setSearchParams({ ...searchParams, filter: { type: [], status: [], tags: [] } })}
            showViewToggle={false}
            showReload={false}
          />
          <div className="flex items-center gap-2">
            <Button
              type="primary"
              icon={<PlusOutlined />}
              onClick={() => {
                setCurrentItem(null);
                setItemEditorOpen(true);
              }}
              disabled={isReadOnly}
            >
              新建条目
            </Button>
            <ImportKnowledgeItemsDialog
              setId={id || ""}
              onImported={fetchData}
              disabled={isReadOnly}
            />
          </div>
        </div>

        {items.length === 0 ? (
          <Empty description="暂无知识条目" />
        ) : (
          <Table
            loading={loading}
            columns={itemColumns}
            dataSource={items}
            rowKey="id"
            pagination={pagination}
            scroll={{ y: "calc(100vh - 36rem)" }}
          />
        )}
      </div>

      <KnowledgeItemEditor
        open={itemEditorOpen}
        setId={id || ""}
        data={currentItem}
        readOnly={isReadOnly}
        onCancel={() => {
          setItemEditorOpen(false);
          setCurrentItem(null);
        }}
        onSuccess={() => {
          setItemEditorOpen(false);
          setCurrentItem(null);
          fetchData();
        }}
      />

      <Modal
        title={`文件预览：${previewFileName}`}
        open={previewVisible}
        onCancel={closePreview}
        footer={[
          <Button key="close" onClick={closePreview}>
            关闭
          </Button>,
        ]}
        width={previewFileType === "text" ? PREVIEW_MODAL_WIDTH.text : PREVIEW_MODAL_WIDTH.media}
      >
        {previewFileType === "text" && (
          <pre
            style={{
              maxHeight: `${PREVIEW_MAX_HEIGHT}px`,
              overflow: "auto",
              whiteSpace: "pre-wrap",
              wordBreak: "break-all",
              fontSize: PREVIEW_TEXT_FONT_SIZE,
              color: "#222",
              backgroundColor: "#f5f5f5",
              padding: `${PREVIEW_TEXT_PADDING}px`,
              borderRadius: "4px",
            }}
          >
            {previewContent}
          </pre>
        )}
        {previewFileType === "image" && (
          <div style={{ textAlign: "center" }}>
            <img
              src={previewMediaUrl}
              alt={previewFileName}
              style={{ maxWidth: "100%", maxHeight: `${PREVIEW_MAX_HEIGHT}px`, objectFit: "contain" }}
            />
          </div>
        )}
        {previewFileType === "video" && (
          <div style={{ textAlign: "center" }}>
            <video
              src={previewMediaUrl}
              controls
              style={{ maxWidth: "100%", maxHeight: `${PREVIEW_MAX_HEIGHT}px` }}
            >
              您的浏览器不支持视频播放
            </video>
          </div>
        )}
        {previewFileType === "audio" && (
          <div style={{ textAlign: "center", padding: `${PREVIEW_AUDIO_PADDING}px 0` }}>
            <audio src={previewMediaUrl} controls style={{ width: "100%" }}>
              您的浏览器不支持音频播放
            </audio>
          </div>
        )}
      </Modal>

      <Modal
        open={readModalOpen}
        title={`阅读：${readTitle}`}
        width={820}
        onCancel={() => {
          setReadModalOpen(false);
          setReadContent("");
          setReadTitle("");
        }}
        footer={[
          <Button
            key="close"
            onClick={() => {
              setReadModalOpen(false);
              setReadContent("");
              setReadTitle("");
            }}
          >
            关闭
          </Button>,
        ]}
      >
        <pre
          className="max-h-[520px] overflow-auto rounded bg-gray-50 p-4 text-xs whitespace-pre-wrap break-all"
        >
          {readContent}
        </pre>
      </Modal>
    </div>
  );
};

export default KnowledgeSetDetail;
