import { useEffect, useState } from "react";
import { Button, DatePicker, Form, Input, message, Modal, Select, Upload, UploadFile } from "antd";
import { UploadOutlined } from "@ant-design/icons";
import dayjs from "dayjs";
import {
  downloadKnowledgeItemFileUsingGet,
  replaceKnowledgeItemFileUsingPut,
  updateKnowledgeItemByIdUsingPut,
  uploadKnowledgeItemsUsingPost,
} from "../knowledge-management.api";
import {
  knowledgeStatusOptions,
} from "../knowledge-management.const";
import {
  KnowledgeContentType,
  KnowledgeItem,
  KnowledgeSourceType,
  KnowledgeStatusType,
} from "../knowledge-management.model";
import { queryDatasetTagsUsingGet } from "@/pages/DataManagement/dataset.api";

const stripFileExtension = (fileName: string) => {
  const dotIndex = fileName.lastIndexOf(".");
  if (dotIndex <= 0) {
    return fileName;
  }
  return fileName.slice(0, dotIndex);
};

export default function KnowledgeItemEditor({
  open,
  setId,
  data,
  onCancel,
  onSuccess,
  readOnly,
}: {
  open: boolean;
  setId: string;
  data?: Partial<KnowledgeItem> | null;
  readOnly?: boolean;
  onCancel: () => void;
  onSuccess: () => void;
}) {
  const [form] = Form.useForm();
  const [tagOptions, setTagOptions] = useState<{ label: string; value: string }[]>([]);
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [replaceFileList, setReplaceFileList] = useState<UploadFile[]>([]);
  const [titleBeforeReplace, setTitleBeforeReplace] = useState<string | null>(null);
  const isMultiFile = fileList.length > 1;
  const isFileItem =
    data?.contentType === KnowledgeContentType.FILE ||
    data?.sourceType === KnowledgeSourceType.FILE_UPLOAD;
  const contentTypeLabel = !data?.id
    ? "文件"
    : data?.contentType === KnowledgeContentType.MARKDOWN
      ? "Markdown"
      : data?.contentType === KnowledgeContentType.TEXT
        ? "文本"
        : "文件";

  const fetchTags = async () => {
    try {
      const { data: tagData } = await queryDatasetTagsUsingGet();
      const options = Array.isArray(tagData)
        ? tagData.map((tag) => ({ label: tag.name, value: tag.name }))
        : [];
      setTagOptions(options);
    } catch (error) {
      console.error("获取标签失败", error);
    }
  };

  useEffect(() => {
    if (open) {
      fetchTags();
    }
  }, [open]);

  useEffect(() => {
    if (open) {
      if (data?.id) {
        form.setFieldsValue({
          title: data.title,
          status: data.status ?? KnowledgeStatusType.DRAFT,
          domain: data.domain,
          businessLine: data.businessLine,
          owner: data.owner,
          sensitivity: data.sensitivity,
          validFrom: data.validFrom ? dayjs(data.validFrom) : null,
          validTo: data.validTo ? dayjs(data.validTo) : null,
          tags: data.tags?.map((tag) => tag.name) || [],
          metadata: data.metadata,
        });
        setTitleBeforeReplace(null);
      } else {
        form.resetFields();
        form.setFieldsValue({
          status: KnowledgeStatusType.DRAFT,
          tags: [],
        });
        setTitleBeforeReplace(null);
      }
      setFileList([]);
      setReplaceFileList([]);
    } else {
      setFileList([]);
      setReplaceFileList([]);
      setTitleBeforeReplace(null);
    }
  }, [open, data, form]);

  const handleFileBeforeUpload = (file: File) => {
    setFileList((prev) => {
      const nextList = [
        ...prev,
        {
          uid: `${Date.now()}-${file.name}`,
          name: file.name,
          status: "done",
          originFileObj: file,
        },
      ];
      if (nextList.length === 1) {
        const currentTitle = form.getFieldValue("title");
        if (!currentTitle) {
          form.setFieldsValue({
            title: stripFileExtension(file.name),
          });
        }
      }
      return nextList;
    });
    message.success("文件已就绪，可提交创建条目");
    return false;
  };

  const handleFileRemove = (removedFile: UploadFile) => {
    setFileList((prev) => {
      const nextList = prev.filter((file) => file.uid !== removedFile.uid);
      if (!data?.id && nextList.length === 0) {
        form.setFieldsValue({ title: undefined });
      }
      return nextList;
    });
    return true;
  };

  const handleReplaceFileBeforeUpload = (file: File) => {
    if (!titleBeforeReplace) {
      setTitleBeforeReplace(form.getFieldValue("title") || null);
    }
    setReplaceFileList([
      {
        uid: `${Date.now()}-${file.name}`,
        name: file.name,
        status: "done",
        originFileObj: file,
      },
    ]);
    form.setFieldsValue({ title: stripFileExtension(file.name) });
    message.success("已选择替换文件，提交后生效");
    return false;
  };

  const handleReplaceFileRemove = (removedFile: UploadFile) => {
    setReplaceFileList((prev) => prev.filter((file) => file.uid !== removedFile.uid));
    if (titleBeforeReplace !== null) {
      form.setFieldsValue({ title: titleBeforeReplace || undefined });
      setTitleBeforeReplace(null);
    }
    return true;
  };

  const handleDownloadFile = async () => {
    if (!data?.id) {
      return;
    }
    try {
      await downloadKnowledgeItemFileUsingGet(setId, data.id, data.sourceFileId);
    } catch (error) {
      console.error("下载文件失败", error);
      message.error("下载失败，请稍后重试");
    }
  };

  const handleSubmit = async () => {
    try {
      if (!data?.id && fileList.length === 0) {
        message.warning("请先选择文件");
        return;
      }
      const values = await form.validateFields();
      const validFrom = values.validFrom ? values.validFrom.format("YYYY-MM-DD") : undefined;
      const validTo = values.validTo ? values.validTo.format("YYYY-MM-DD") : undefined;

      if (validFrom && validTo && dayjs(validFrom).isAfter(dayjs(validTo))) {
        message.warning("有效期开始不能晚于结束时间");
        return;
      }

      if (data?.id) {
        const payload: Record<string, unknown> = {
          ...values,
          validFrom,
          validTo,
          tags: values.tags || [],
        };
        if (replaceFileList.length > 0) {
          delete payload.title;
        }
        await updateKnowledgeItemByIdUsingPut(setId, data.id, payload);
        if (replaceFileList.length > 0) {
          const formData = new FormData();
          const replaceFile = replaceFileList[0]?.originFileObj as File | undefined;
          if (!replaceFile) {
            message.warning("请先选择要替换的文件");
            return;
          }
          formData.append("file", replaceFile);
          await replaceKnowledgeItemFileUsingPut(setId, data.id, formData);
        }
        message.success("知识条目更新成功");
      } else {
        if (fileList.length === 0) {
          message.warning("请先选择文件");
          return;
        }

        const formData = new FormData();
        fileList.forEach((file) => {
          const origin = file.originFileObj as File | undefined;
          if (origin) {
            formData.append("files", origin);
          }
        });
        if (fileList.length === 1 && values.title) {
          formData.append("title", values.title);
        }
        if (values.status) {
          formData.append("status", values.status);
        }
        if (values.tags && Array.isArray(values.tags)) {
          values.tags.forEach((tag) => formData.append("tags", tag));
        }
        if (values.domain) {
          formData.append("domain", values.domain);
        }
        if (values.businessLine) {
          formData.append("businessLine", values.businessLine);
        }
        if (values.owner) {
          formData.append("owner", values.owner);
        }
        if (values.sensitivity) {
          formData.append("sensitivity", values.sensitivity);
        }
        if (validFrom) {
          formData.append("validFrom", validFrom);
        }
        if (validTo) {
          formData.append("validTo", validTo);
        }
        if (values.metadata) {
          formData.append("metadata", values.metadata);
        }

        await uploadKnowledgeItemsUsingPost(setId, formData);
        message.success(`已创建 ${fileList.length} 个知识条目`);
      }

      form.resetFields();
      setFileList([]);
      setReplaceFileList([]);
      setTitleBeforeReplace(null);
      onSuccess();
    } catch {
      message.error("操作失败，请重试");
    }
  };

  const title = data?.id ? "编辑知识条目" : "新建知识条目";

  return (
    <Modal
      title={title}
      open={open}
      onCancel={onCancel}
      onOk={handleSubmit}
      okText="确定"
      cancelText="取消"
      width={860}
      maskClosable={false}
      okButtonProps={{ disabled: readOnly }}
    >
      <Form form={form} layout="vertical" disabled={readOnly}>
        <div className="grid grid-cols-2 gap-4">
          <Form.Item
            label="标题"
            name="title"
            rules={[{ required: !isMultiFile, message: "请输入标题" }]}
          >
            <Input
              placeholder={isMultiFile ? "多文件将按文件名自动生成" : "请输入标题"}
              disabled={readOnly || (!data?.id && isMultiFile)}
            />
          </Form.Item>
          <Form.Item label="状态" name="status">
            <Select options={knowledgeStatusOptions} />
          </Form.Item>
        </div>
        {!data?.id && (
          <Form.Item label="上传文件" required>
            <Upload
              beforeUpload={handleFileBeforeUpload}
              fileList={fileList}
              multiple
              onRemove={handleFileRemove}
              showUploadList={{ showPreviewIcon: false }}
              disabled={readOnly}
            >
              <Button icon={<UploadOutlined />}>选择文件</Button>
            </Upload>
            <div className="text-xs text-gray-500 mt-1">
              支持多格式文件；多文件将自动拆分为多个条目
            </div>
          </Form.Item>
        )}
        {data?.id && isFileItem && (
          <Form.Item label="文件">
            <div className="flex items-center gap-2">
              <span className="truncate" title={data.sourceFileId || data.title}>
                {data.sourceFileId || data.title || "-"}
              </span>
              <Button size="small" onClick={handleDownloadFile} disabled={readOnly}>
                下载
              </Button>
            </div>
          </Form.Item>
        )}
        {data?.id && isFileItem && !readOnly && (
          <Form.Item label="替换文件">
            <Upload
              beforeUpload={handleReplaceFileBeforeUpload}
              fileList={replaceFileList}
              onRemove={handleReplaceFileRemove}
              showUploadList={{ showPreviewIcon: false }}
              maxCount={1}
            >
              <Button icon={<UploadOutlined />}>选择文件</Button>
            </Upload>
            <div className="text-xs text-gray-500 mt-1">仅支持单文件，替换后标题自动更新</div>
          </Form.Item>
        )}
        <div className="grid grid-cols-2 gap-4">
          <Form.Item label="内容类型">
            <Input value={contentTypeLabel} disabled />
          </Form.Item>
          <Form.Item label="敏感级别" name="sensitivity">
            <Input placeholder="请输入敏感级别" />
          </Form.Item>
        </div>
        <div className="grid grid-cols-2 gap-4">
          <Form.Item label="领域" name="domain">
            <Input placeholder="请输入领域" />
          </Form.Item>
          <Form.Item label="业务线" name="businessLine">
            <Input placeholder="请输入业务线" />
          </Form.Item>
        </div>
        <div className="grid grid-cols-2 gap-4">
          <Form.Item label="负责人" name="owner">
            <Input placeholder="请输入负责人" />
          </Form.Item>
          <Form.Item label="标签" name="tags">
            <Select
              mode="tags"
              options={tagOptions}
              placeholder="请选择或输入标签"
            />
          </Form.Item>
        </div>
        <div className="grid grid-cols-2 gap-4">
          <Form.Item label="有效期开始" name="validFrom">
            <DatePicker className="w-full" />
          </Form.Item>
          <Form.Item label="有效期结束" name="validTo">
            <DatePicker className="w-full" />
          </Form.Item>
        </div>
        <Form.Item label="扩展元数据" name="metadata">
          <Input.TextArea placeholder="请输入元数据（JSON）" rows={3} />
        </Form.Item>
        {data?.sourceType && (
          <div className="grid grid-cols-2 gap-4 text-sm text-gray-500">
            <div>来源类型：{data.sourceType}</div>
            <div>来源文件：{data.sourceFileId || "-"}</div>
          </div>
        )}
      </Form>
    </Modal>
  );
}
