import { queryDatasetsUsingGet, queryDatasetFilesUsingGet } from "@/pages/DataManagement/dataset.api";
import { mapDataset } from "@/pages/DataManagement/dataset.const";
import { App, Button, Form, Input, Modal, Select, Radio, Table } from "antd";
import type { RadioChangeEvent } from "antd";
import TextArea from "antd/es/input/TextArea";
import { useEffect, useMemo, useState } from "react";
import type { ReactNode } from "react";
import { Eye } from "lucide-react";
import {
  createAnnotationTaskUsingPost,
  getAnnotationTaskByIdUsingGet,
  updateAnnotationTaskByIdUsingPut,
  queryAnnotationTemplatesUsingGet,
} from "../../annotation.api";
import { DatasetType, type Dataset } from "@/pages/DataManagement/dataset.model";
import { DataType, type AnnotationTemplate, type AnnotationTask } from "../../annotation.model";
import LabelStudioEmbed from "@/components/business/LabelStudioEmbed";
import TemplateConfigurationTreeEditor from "../../components/TemplateConfigurationTreeEditor";
import { useTagConfig } from "@/hooks/useTagConfig";

interface AnnotationTaskDialogProps {
  open: boolean;
  onClose: () => void;
  onRefresh: () => void;
  /** 编辑模式：传入要编辑的任务数据 */
  editTask?: AnnotationTask | null;
}

type DatasetOption = Dataset & { icon?: ReactNode };

type DatasetPreviewFile = {
  id: string;
  fileName?: string;
  fileSize?: number;
};

type AnnotationTaskDetail = {
  name?: string;
  description?: string;
  datasetId?: string;
  labelConfig?: string;
  template?: { labelConfig?: string };
  segmentationEnabled?: boolean;
};

type ApiResponse<T> = {
  code?: number;
  message?: string;
  data?: T;
};

const isRecord = (value: unknown): value is Record<string, unknown> =>
  !!value && typeof value === "object" && !Array.isArray(value);

const DEFAULT_SEGMENTATION_ENABLED = true;
const SEGMENTATION_OPTIONS = [
  { label: "需要切片段", value: true },
  { label: "不需要切片段", value: false },
];
const resolveTemplateDataType = (datasetType?: DatasetType) => {
  switch (datasetType) {
    case DatasetType.TEXT:
      return DataType.TEXT;
    case DatasetType.IMAGE:
      return DataType.IMAGE;
    case DatasetType.AUDIO:
      return DataType.AUDIO;
    case DatasetType.VIDEO:
      return DataType.VIDEO;
    default:
      return undefined;
  }
};
const resolveTemplateTimestamp = (template: AnnotationTemplate) => {
  const timestamp = template.updatedAt || template.createdAt;
  const parsed = Date.parse(timestamp);
  return Number.isNaN(parsed) ? 0 : parsed;
};
const resolveDefaultTemplate = (items: AnnotationTemplate[]) =>
  items.reduce<AnnotationTemplate | undefined>((latest, current) => {
    if (!latest) {
      return current;
    }
    return resolveTemplateTimestamp(current) > resolveTemplateTimestamp(latest)
      ? current
      : latest;
  }, undefined);

export default function CreateAnnotationTask({
  open,
  onClose,
  onRefresh,
  editTask,
}: AnnotationTaskDialogProps) {
  const isEditMode = !!editTask;
  const { message } = App.useApp();
  const [manualForm] = Form.useForm();
  const [datasets, setDatasets] = useState<DatasetOption[]>([]);
  const [templates, setTemplates] = useState<AnnotationTemplate[]>([]);
  const [submitting, setSubmitting] = useState(false);
  const [nameManuallyEdited, setNameManuallyEdited] = useState(false);

  const [labelConfig, setLabelConfig] = useState("");
  const [showPreview, setShowPreview] = useState(false);
  const [previewTaskData, setPreviewTaskData] = useState<Record<string, unknown>>({});
  const [configMode, setConfigMode] = useState<"template" | "custom">("template");

  // 数据集预览相关状态
  const [datasetPreviewVisible, setDatasetPreviewVisible] = useState(false);
  const [datasetPreviewData, setDatasetPreviewData] = useState<DatasetPreviewFile[]>([]);
  const [datasetPreviewLoading, setDatasetPreviewLoading] = useState(false);
  const [selectedDatasetId, setSelectedDatasetId] = useState<string | null>(null);

  // 文件内容预览相关状态
  const [fileContentVisible, setFileContentVisible] = useState(false);
  const [fileContent, setFileContent] = useState("");
  const [fileContentLoading, setFileContentLoading] = useState(false);
  const [previewFileName, setPreviewFileName] = useState("");
  const [previewFileType, setPreviewFileType] = useState<"text" | "image" | "video" | "audio">("text");
  const [previewMediaUrl, setPreviewMediaUrl] = useState("");

  // 任务详情加载状态（编辑模式）
  const [taskDetailLoading, setTaskDetailLoading] = useState(false);
  const { config: tagConfig } = useTagConfig(false);

  const selectedDataset = useMemo(
    () => datasets.find((dataset) => dataset.id === selectedDatasetId),
    [datasets, selectedDatasetId]
  );
  const isTextDataset = selectedDataset?.datasetType === DatasetType.TEXT;

  useEffect(() => {
    if (!open) return;
    const fetchData = async () => {
      try {
        // Fetch datasets
        const { data: datasetData } = await queryDatasetsUsingGet({
          page: 0,
          pageSize: 1000,
        });
        setDatasets(datasetData.content.map(mapDataset) || []);

      } catch (error) {
        console.error("Error fetching data:", error);
        setTemplates([]);
      }
    };
    fetchData();
  }, [open]);

  const fetchTemplates = async (dataType?: string) => {
    if (!dataType) {
      setTemplates([]);
      return;
    }
    try {
      const templateResponse = await queryAnnotationTemplatesUsingGet({
        page: 1,
        size: 100,  // Backend max is 100 (template API uses 'size' not 'pageSize')
        dataType,
      });

      if (templateResponse.code === 200 && templateResponse.data) {
        const fetchedTemplates = templateResponse.data.content || [];
        setTemplates(fetchedTemplates);
      } else {
        console.error("Failed to fetch templates:", templateResponse);
        setTemplates([]);
      }
    } catch (error) {
      console.error("Error fetching templates:", error);
      setTemplates([]);
    }
  };

  useEffect(() => {
    if (!open || isEditMode) {
      return;
    }
    if (!selectedDataset) {
      setTemplates([]);
      manualForm.setFieldsValue({ templateId: undefined });
      setLabelConfig("");
      return;
    }
    const dataType = resolveTemplateDataType(selectedDataset.datasetType);
    fetchTemplates(dataType);
  }, [isEditMode, manualForm, open, selectedDataset]);

  useEffect(() => {
    if (!open || isEditMode || configMode !== "template" || !selectedDataset) {
      return;
    }
    if (templates.length === 0) {
      manualForm.setFieldsValue({ templateId: undefined });
      setLabelConfig("");
      return;
    }
    const currentTemplateId = manualForm.getFieldValue("templateId");
    const currentTemplate = templates.find((template) => template.id === currentTemplateId);
    if (currentTemplate) {
      return;
    }
    const defaultTemplate = resolveDefaultTemplate(templates);
    if (defaultTemplate) {
      manualForm.setFieldsValue({ templateId: defaultTemplate.id });
      setLabelConfig(defaultTemplate.labelConfig || "");
    }
  }, [configMode, isEditMode, manualForm, open, selectedDataset, templates]);

  // Reset form and manual-edit flag when modal opens, or load task data in edit mode
  useEffect(() => {
    if (open) {
      manualForm.resetFields();
      setNameManuallyEdited(false);
      setLabelConfig("");
      setShowPreview(false);
      setPreviewTaskData({});
      setDatasetPreviewData([]);

      if (isEditMode && editTask) {
        // 编辑模式：加载任务详情
        setTaskDetailLoading(true);
        getAnnotationTaskByIdUsingGet(editTask.id)
          .then((res: ApiResponse<AnnotationTaskDetail>) => {
            if (res.code === 200 && res.data) {
              const taskDetail = res.data;
              // 填充基本信息
              manualForm.setFieldsValue({
                name: taskDetail.name,
                description: taskDetail.description,
                datasetId: taskDetail.datasetId,
                segmentationEnabled: typeof taskDetail.segmentationEnabled === "boolean"
                  ? taskDetail.segmentationEnabled
                  : DEFAULT_SEGMENTATION_ENABLED,
              });
              if (taskDetail.datasetId) {
                setSelectedDatasetId(taskDetail.datasetId);
              }

              // 获取实际的 labelConfig（优先使用任务自身的配置，回退到模板配置）
              const configXml = taskDetail.labelConfig || taskDetail.template?.labelConfig;

              if (configXml) {
                setLabelConfig(configXml);
              }

              // 编辑模式始终使用 custom 配置模式（不改变结构，只改属性）
              setConfigMode("custom");
            }
          })
          .catch((err) => {
            console.error("Failed to load task detail:", err);
            message.error("加载任务详情失败");
          })
          .finally(() => {
            setTaskDetailLoading(false);
          });
      } else {
        // 创建模式：重置为默认状态
        setConfigMode("template");
        setSelectedDatasetId(null);
        manualForm.setFieldsValue({
          segmentationEnabled: DEFAULT_SEGMENTATION_ENABLED,
        });
      }
    }
  }, [open, manualForm, isEditMode, editTask, message]);

  // 预览数据集
  const handlePreviewDataset = async () => {
    if (!selectedDatasetId) {
      message.warning("请先选择数据集");
      return;
    }
    setDatasetPreviewLoading(true);
    try {
      // 对于文本数据集，排除已被转换为TXT的源文档文件（PDF/DOC/DOCX）
      const params: { page: number; size: number; excludeSourceDocuments?: boolean } = { page: 0, size: 10 };
      if (isTextDataset) {
        params.excludeSourceDocuments = true;
      }
      const res = await queryDatasetFilesUsingGet(selectedDatasetId, params);
      if (res.code === '0' && res.data) {
        setDatasetPreviewData((res.data.content || []) as DatasetPreviewFile[]);
        setDatasetPreviewVisible(true);
      } else {
        message.error("获取数据集预览失败");
      }
    } catch (error) {
      console.error("Preview dataset error:", error);
      message.error("获取数据集预览失败");
    } finally {
      setDatasetPreviewLoading(false);
    }
  };

  // 预览文件内容
  const handlePreviewFileContent = async (file: DatasetPreviewFile) => {
    const fileName = file.fileName?.toLowerCase() || '';

    // 文件类型扩展名映射
    const textExtensions = ['.json', '.jsonl', '.txt', '.csv', '.tsv', '.xml', '.md', '.yaml', '.yml'];
    const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg'];
    const videoExtensions = ['.mp4', '.webm', '.ogg', '.mov', '.avi'];
    const audioExtensions = ['.mp3', '.wav', '.ogg', '.aac', '.flac', '.m4a'];

    const isTextFile = textExtensions.some(ext => fileName.endsWith(ext));
    const isImageFile = imageExtensions.some(ext => fileName.endsWith(ext));
    const isVideoFile = videoExtensions.some(ext => fileName.endsWith(ext));
    const isAudioFile = audioExtensions.some(ext => fileName.endsWith(ext));

    if (!isTextFile && !isImageFile && !isVideoFile && !isAudioFile) {
      message.warning("不支持预览该文件类型");
      return;
    }

    setFileContentLoading(true);
    setPreviewFileName(file.fileName);

    const fileUrl = `/api/data-management/datasets/${selectedDatasetId}/files/${file.id}/download`;

    try {
      if (isTextFile) {
        // 文本文件：获取内容
        const response = await fetch(fileUrl);
        if (!response.ok) {
          throw new Error('下载失败');
        }
        const text = await response.text();
        // 限制预览内容长度
        const maxLength = 50000;
        if (text.length > maxLength) {
          setFileContent(text.substring(0, maxLength) + '\n\n... (内容过长，仅显示前 50000 字符)');
        } else {
          setFileContent(text);
        }
        setPreviewFileType("text");
      } else if (isImageFile) {
        // 图片文件：直接使用 URL
        setPreviewMediaUrl(fileUrl);
        setPreviewFileType("image");
      } else if (isVideoFile) {
        // 视频文件：使用 URL
        setPreviewMediaUrl(fileUrl);
        setPreviewFileType("video");
      } else if (isAudioFile) {
        // 音频文件：使用 URL
        setPreviewMediaUrl(fileUrl);
        setPreviewFileType("audio");
      }
      setFileContentVisible(true);
    } catch (error) {
      console.error("Preview file content error:", error);
      message.error("获取文件内容失败");
    } finally {
      setFileContentLoading(false);
    }
  };

  const DEFAULT_OBJECT_TAGS = [
    "Image",
    "Text",
    "Audio",
    "Video",
    "HyperText",
    "PDF",
    "Markdown",
    "Paragraphs",
    "Table",
    "AudioPlus",
    "Timeseries",
    "TimeSeries",
    "Vector",
    "Chat",
  ];
  const DEFAULT_LABELING_CONTROL_TAGS = [
    "Choices",
    "Labels",
    "RectangleLabels",
    "PolygonLabels",
    "EllipseLabels",
    "KeyPointLabels",
    "BrushLabels",
    "TextArea",
    "Number",
    "DateTime",
    "Rating",
    "Taxonomy",
    "ParagraphLabels",
    "HyperTextLabels",
    "Relations",
    "Relation",
    "Pairwise",
    "TimeseriesLabels",
    "TimeSeriesLabels",
    "VectorLabels",
    "VideoRectangle",
    "MagicWand",
    "BitmaskLabels",
  ];

  const resolveObjectTags = () => {
    const configTags = tagConfig?.objects ? Object.keys(tagConfig.objects) : [];
    return new Set(configTags.length > 0 ? configTags : DEFAULT_OBJECT_TAGS);
  };

  const resolveLabelingControlTags = () => {
    if (tagConfig?.controls) {
      const labelingTags = Object.entries(tagConfig.controls)
        .filter(([, config]) => config.category === "labeling")
        .map(([tag]) => tag);
      if (labelingTags.length > 0) {
        return new Set(labelingTags);
      }
    }
    return new Set(DEFAULT_LABELING_CONTROL_TAGS);
  };

  const parseXmlElements = (xml: string): Element[] => {
    if (!xml) return [];
    try {
      const parser = new DOMParser();
      const doc = parser.parseFromString(xml, "text/xml");
      if (doc.getElementsByTagName("parsererror").length > 0) {
        return [];
      }
      return Array.from(doc.getElementsByTagName("*"));
    } catch (error) {
      console.error("解析 XML 失败", error);
      return [];
    }
  };

  const extractObjectsFromLabelConfig = (xml: string) => {
    const objectTags = resolveObjectTags();
    const elements = parseXmlElements(xml);
    return elements
      .filter((element) => objectTags.has(element.tagName))
      .map((element) => ({
        name: element.getAttribute("name") || "",
        type: element.tagName,
        value: element.getAttribute("value") || "",
      }))
      .filter((item) => item.name || item.value);
  };

  const generatePreviewTaskDataFromLabelConfig = (xml: string) => {
    const exampleDataByType: Record<string, unknown> = {
      Image: "https://labelstud.io/images/opa-header.png",
      Audio: "https://labelstud.io/files/sample.wav",
      AudioPlus: "https://labelstud.io/files/sample.wav",
      Video: "https://labelstud.io/files/sample.mp4",
      Text: "这是示例文本，用于预览标注界面。",
      HyperText: "<p>这是示例 HTML 内容</p>",
      Markdown: "# 示例标题\n\n这里是示例 Markdown 内容。",
      Paragraphs: "段落一\n\n段落二\n\n段落三",
      PDF: "https://labelstud.io/files/sample.pdf",
      Table: [
        { key: "字段A", value: "示例值A" },
        { key: "字段B", value: "示例值B" },
      ],
      Chat: [
        { text: "你好，我想了解一下产品。", author: "user" },
        { text: "当然可以，请告诉我你的需求。", author: "assistant" },
      ],
      Timeseries: "https://labelstud.io/files/sample.csv",
      TimeSeries: "https://labelstud.io/files/sample.csv",
      Vector: [0.12, 0.52, 0.33],
    };

    const objects = extractObjectsFromLabelConfig(xml);
    if (objects.length === 0) {
      return {
        image: exampleDataByType.Image,
        text: exampleDataByType.Text,
        audio: exampleDataByType.Audio,
      };
    }

    const data: Record<string, unknown> = {};
    objects.forEach((obj) => {
      const name = obj.name || "";
      const value = obj.value || "";
      const varName = value.startsWith("$") ? value.slice(1) : name || value;
      if (!varName) return;

      if (exampleDataByType[obj.type]) {
        data[varName] = exampleDataByType[obj.type];
        return;
      }

      const lowerName = varName.toLowerCase();
      if (lowerName.includes("image") || lowerName.includes("img")) {
        data[varName] = exampleDataByType.Image;
      } else if (lowerName.includes("audio") || lowerName.includes("sound")) {
        data[varName] = exampleDataByType.Audio;
      } else if (lowerName.includes("video")) {
        data[varName] = exampleDataByType.Video;
      } else if (lowerName.includes("chat")) {
        data[varName] = exampleDataByType.Chat;
      } else {
        data[varName] = exampleDataByType.Text;
      }
    });

    return data;
  };

  // 当选择模板时，加载 XML 配置到树编辑器（仅快速填充）
  const handleTemplateSelect = (value: string, option: unknown) => {
    if (!value) {
      setLabelConfig("");
      return;
    }

    const selectedTemplate = templates.find((template) => template.id === value);
    const configXml = selectedTemplate?.labelConfig
      || (isRecord(option) && typeof option.config === "string" ? option.config : "")
      || "";
    setLabelConfig(configXml);
  };

  const validateLabelConfigForSubmit = () => {
    const xml = labelConfig.trim();
    if (!xml) {
      message.error("请配置标注模板");
      return false;
    }

    const elements = parseXmlElements(xml);
    if (elements.length === 0) {
      message.error("标注配置 XML 格式有误");
      return false;
    }

    const objectTags = resolveObjectTags();
    const labelingControlTags = resolveLabelingControlTags();
    const objectCount = elements.filter((element) => objectTags.has(element.tagName)).length;
    const labelingControlCount = elements.filter((element) => labelingControlTags.has(element.tagName)).length;

    if (objectCount === 0) {
      message.error("至少需要一个数据对象标签");
      return false;
    }

    if (labelingControlCount === 0) {
      message.error("至少需要一个标注控件标签");
      return false;
    }

    return true;
  };

  const handleManualSubmit = async () => {
    try {
      const values = await manualForm.validateFields();
      if (!validateLabelConfigForSubmit()) {
        return;
      }

      setSubmitting(true);
      const requestData = {
        name: values.name,
        description: values.description,
        datasetId: values.datasetId,
        templateId: configMode === "template" ? values.templateId : undefined,
        labelConfig: labelConfig.trim(),
      };
      if (!isEditMode && isTextDataset) {
        requestData.segmentationEnabled =
          values.segmentationEnabled ?? DEFAULT_SEGMENTATION_ENABLED;
      }

      if (isEditMode && editTask) {
        // 编辑模式：调用更新接口
        await updateAnnotationTaskByIdUsingPut(editTask.id, requestData);
        message.success("更新标注任务成功");
      } else {
        // 创建模式：调用创建接口
        await createAnnotationTaskUsingPost(requestData);
        message.success("创建标注任务成功");
      }
      onClose();
      onRefresh();
    } catch (err: unknown) {
      console.error(isEditMode ? "Update annotation task failed" : "Create annotation task failed", err);
      const error = err as { message?: string; data?: { message?: string } };
      const msg = error?.message || error?.data?.message || (isEditMode ? "更新失败，请稍后重试" : "创建失败，请稍后重试");
      message.error(msg);
    } finally {
      setSubmitting(false);
    }
  };

  const handleConfigModeChange = (e: RadioChangeEvent) => {
    const mode = e.target.value;
    setConfigMode(mode);
    if (mode === "custom") {
      manualForm.setFieldsValue({ templateId: undefined });
    }
  };

  return (
    <>
      <Modal
        open={open}
        onCancel={onClose}
        title={isEditMode ? "编辑标注任务" : "创建标注任务"}
        loading={taskDetailLoading}
        footer={
          <>
            <Button onClick={onClose} disabled={submitting}>
              取消
            </Button>
            <Button
              type="primary"
              onClick={handleManualSubmit}
              loading={submitting}
            >
              确定
            </Button>
          </>
        }
        width={800}
      >
        <Form form={manualForm} layout="vertical">
          {/* 数据集 与 标注工程名称 并排显示（数据集在左） */}
          <div className="grid grid-cols-2 gap-4">
            <Form.Item
              label={
                <div className="flex items-center justify-between w-full">
                  <span>数据集</span>
                  <Button
                    type="link"
                    size="small"
                    icon={<Eye size={14} />}
                    disabled={!selectedDatasetId}
                    loading={datasetPreviewLoading}
                    onClick={handlePreviewDataset}
                    className="p-0 h-auto"
                  >
                    预览
                  </Button>
                </div>
              }
              name="datasetId"
              rules={[{ required: true, message: "请选择数据集" }]}
              help={isEditMode ? "数据集不可修改" : undefined}
            >
              <Select
                placeholder="请选择数据集"
                disabled={isEditMode}
                options={datasets.map((dataset) => {
                  return {
                    label: (
                      <div className="flex items-center justify-between gap-3 py-2">
                        <div className="flex items-center font-sm text-gray-900">
                          <span className="mr-2">{dataset.icon}</span>
                          <span>{dataset.name}</span>
                        </div>
                        <div className="text-xs text-gray-500">{dataset.size}</div>
                      </div>
                    ),
                    value: dataset.id,
                  };
                })}
                onChange={(value) => {
                  setSelectedDatasetId(value);
                  if (!isEditMode) {
                    manualForm.setFieldsValue({ templateId: undefined });
                    setLabelConfig("");
                  }
                  const dataset = datasets.find((item) => item.id === value);
                  if (dataset?.datasetType === DatasetType.TEXT) {
                    const currentValue = manualForm.getFieldValue("segmentationEnabled");
                    if (currentValue === undefined) {
                      manualForm.setFieldsValue({
                        segmentationEnabled: DEFAULT_SEGMENTATION_ENABLED,
                      });
                    }
                  } else if (dataset) {
                    manualForm.setFieldsValue({ segmentationEnabled: false });
                  }
                  // 如果用户未手动修改名称，则用数据集名称作为默认任务名
                  if (!nameManuallyEdited) {
                    const ds = datasets.find((d) => d.id === value);
                    if (ds) {
                      let defaultName = ds.name || "";
                      if (defaultName.length < 3) {
                        defaultName = `${defaultName}-标注`;
                      }
                      manualForm.setFieldsValue({ name: defaultName });
                    }
                  }
                }}
              />
            </Form.Item>

            <Form.Item
              label="标注工程名称"
              name="name"
              rules={[
                {
                  validator: (_rule, value) => {
                    const trimmed = (value || "").trim();
                    if (!trimmed) {
                      return Promise.reject(new Error("请输入任务名称"));
                    }
                    if (trimmed.length < 3) {
                      return Promise.reject(
                        new Error("任务名称至少需要 3 个字符（不含首尾空格，Label Studio 限制）")
                      );
                    }
                    return Promise.resolve();
                  },
                },
              ]}
            >
              <Input
                placeholder="输入标注工程名称"
                onChange={() => setNameManuallyEdited(true)}
              />
            </Form.Item>
          </div>
          {/* 描述变为可选 */}
          <Form.Item label="描述" name="description">
            <TextArea placeholder="（可选）详细描述标注任务的要求和目标" rows={2} />
          </Form.Item>

          {selectedDatasetId && isTextDataset && (
            <Form.Item
              label="段落切片"
              name="segmentationEnabled"
              initialValue={DEFAULT_SEGMENTATION_ENABLED}
              extra={isEditMode ? "编辑模式暂不支持修改" : "仅文本数据集可配置该项"}
            >
              <Radio.Group
                options={SEGMENTATION_OPTIONS}
                optionType="button"
                buttonStyle="solid"
                disabled={isEditMode}
              />
            </Form.Item>
          )}

          {/* 标注模板选择 */}
          <div className="flex items-center justify-between mb-2">
              <span className="text-sm font-medium text-gray-700 after:content-['*'] after:text-red-500 after:ml-1">标注配置</span>

              <div className="flex gap-2">
                {!isEditMode && (
                  <Radio.Group value={configMode} onChange={handleConfigModeChange} size="small" buttonStyle="solid">
                    <Radio.Button value="template">现有模板</Radio.Button>
                    {/*<Radio.Button value="custom">自定义配置</Radio.Button>*/}
                  </Radio.Group>
                )}

                <Button
                  type="link"
                  size="small"
                  onClick={() => {
                    if (!labelConfig.trim()) {
                      message.warning("请先配置标注模板");
                      return;
                    }

                    const exampleData = generatePreviewTaskDataFromLabelConfig(labelConfig);
                    setPreviewTaskData(exampleData);
                    setShowPreview(true);
                  }}
                >
                  预览配置效果
                </Button>
              </div>
          </div>

          {isEditMode ? (
            // 编辑模式：只允许修改标签取值
            <div className="bg-gray-50 p-4 rounded-md border border-gray-200">
              <div className="text-sm text-gray-500 mb-3 bg-blue-50 p-2 rounded border border-blue-200">
                编辑模式下，模板结构（数据对象、控件类型等）不可修改，仅可修改属性值（来源名称、标签/选项取值等）。
              </div>
              <TemplateConfigurationTreeEditor
                value={labelConfig}
                onChange={setLabelConfig}
                readOnlyStructure={true}
                height={360}
              />
            </div>
          ) : configMode === 'template' ? (
            <div className="bg-gray-50 p-4 rounded-md border border-gray-200">
              <Form.Item
                label="加载现有模板"
                name="templateId"
                style={{ marginBottom: 12 }}
                help="选择模板后，配置将自动填充到可视化编辑器中，您可以继续修改。"
                rules={[{ required: true, message: "请选择标注模板" }]}
              >
                <Select
                  placeholder="选择一个模板作为基础"
                  showSearch
                  allowClear
                  optionFilterProp="label"
                  options={templates.map((template) => ({
                    label: template.name,
                    value: template.id,
                    title: template.description,
                    config: template.labelConfig,
                  }))}
                  onChange={handleTemplateSelect}
                  optionRender={(option) => (
                    <div>
                      <div style={{ fontWeight: 500 }}>{option.label}</div>
                      {option.data.title && (
                        <div style={{ fontSize: 12, color: '#999', marginTop: 2 }}>
                          {option.data.title}
                        </div>
                      )}
                    </div>
                  )}
                />
              </Form.Item>

              <TemplateConfigurationTreeEditor
                value={labelConfig}
                onChange={setLabelConfig}
                height={360}
              />
            </div>
          ) : (
            <div className="bg-gray-50 p-4 rounded-md border border-gray-200">
              <TemplateConfigurationTreeEditor
                value={labelConfig}
                onChange={setLabelConfig}
                height={360}
              />
            </div>
          )}

        </Form>
      </Modal>

      {/* Preview Modal */}
      <Modal
        open={showPreview}
        onCancel={() => setShowPreview(false)}
        title="标注界面预览"
        width={1000}
        footer={[
          <Button key="close" onClick={() => setShowPreview(false)}>
            关闭
          </Button>
        ]}
      >
        <div style={{ height: '600px', overflow: 'hidden' }}>
          {showPreview && (
            <LabelStudioEmbed
              config={labelConfig}
              task={{
                  id: 1,
                  data: previewTaskData,
              }}
            />
          )}
        </div>
      </Modal>

      {/* 数据集预览弹窗 */}
      <Modal
        open={datasetPreviewVisible}
        onCancel={() => setDatasetPreviewVisible(false)}
        title="数据集预览（前10条文件）"
        width={700}
        footer={[
          <Button key="close" onClick={() => setDatasetPreviewVisible(false)}>
            关闭
          </Button>
        ]}
      >
        <div className="mb-2 text-xs text-gray-500">点击文件名可预览文件内容（支持文本、图片、音频、视频）</div>
        <Table
          dataSource={datasetPreviewData}
          columns={[
            {
              title: "文件名",
              dataIndex: "fileName",
              key: "fileName",
              ellipsis: true,
              render: (text: string, record: DatasetPreviewFile) => (
                <Button
                  type="link"
                  size="small"
                  className="p-0 h-auto text-left"
                  loading={fileContentLoading && previewFileName === text}
                  onClick={() => handlePreviewFileContent(record)}
                >
                  {text}
                </Button>
              ),
            },
            {
              title: "大小",
              dataIndex: "fileSize",
              key: "fileSize",
              width: 120,
              render: (value: number) => {
                if (!value) return "-";
                if (value < 1024) return `${value} B`;
                if (value < 1024 * 1024) return `${(value / 1024).toFixed(1)} KB`;
                return `${(value / 1024 / 1024).toFixed(1)} MB`;
              },
            },
          ]}
          rowKey="id"
          pagination={false}
          scroll={{ y: 300 }}
          size="small"
        />
      </Modal>

      {/* 文件内容预览弹窗 */}
      <Modal
        open={fileContentVisible}
        onCancel={() => {
          setFileContentVisible(false);
          setPreviewMediaUrl("");
          setFileContent("");
        }}
        title={`文件预览：${previewFileName}`}
        width={previewFileType === "text" ? 800 : 700}
        footer={[
          <Button key="close" onClick={() => {
            setFileContentVisible(false);
            setPreviewMediaUrl("");
            setFileContent("");
          }}>
            关闭
          </Button>
        ]}
      >
        {previewFileType === "text" && (
          <pre
            style={{
              maxHeight: '500px',
              overflow: 'auto',
              backgroundColor: '#f5f5f5',
              padding: '12px',
              borderRadius: '4px',
              fontSize: '12px',
              whiteSpace: 'pre-wrap',
              wordBreak: 'break-all',
            }}
          >
            {fileContent}
          </pre>
        )}
        {previewFileType === "image" && (
          <div style={{ textAlign: 'center' }}>
            <img
              src={previewMediaUrl}
              alt={previewFileName}
              style={{ maxWidth: '100%', maxHeight: '500px', objectFit: 'contain' }}
            />
          </div>
        )}
        {previewFileType === "video" && (
          <div style={{ textAlign: 'center' }}>
            <video
              src={previewMediaUrl}
              controls
              style={{ maxWidth: '100%', maxHeight: '500px' }}
            >
              您的浏览器不支持视频播放
            </video>
          </div>
        )}
        {previewFileType === "audio" && (
          <div style={{ textAlign: 'center', padding: '40px 0' }}>
            <audio src={previewMediaUrl} controls style={{ width: '100%' }}>
              您的浏览器不支持音频播放
            </audio>
          </div>
        )}
      </Modal>
    </>
  );
}
