import React, { useState, useMemo, useEffect, useCallback } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { DndProvider, useDrag, useDrop, useDragLayer } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

// 创建全局单例 backend 实例，避免多个 HTML5Backend 实例冲突
// 使用 WeakMap 来存储 backend 实例，确保全局只有一个实例
const backendCache = new WeakMap<Window, typeof HTML5Backend>();

const getHTML5Backend = () => {
  // HTML5Backend 是一个工厂函数，我们需要确保全局只有一个实例
  // 由于 HTML5Backend 本身就是一个函数，我们直接使用它
  // 但为了确保单例，我们使用 useMemo 在组件级别缓存
  return HTML5Backend;
};
import { 
  Button, 
  Input, 
  Select, 
  DatePicker, 
  TimePicker,
  InputNumber, 
  Switch, 
  Radio, 
  Checkbox,
  Card,
  Space,
  message,
  Modal,
  Form as AntdForm,
  Collapse,
  Divider,
  Cascader,
  Upload,
  Dropdown,
  Alert,
  Tag,
  Tabs
} from 'antd';
import type { MenuProps } from 'antd';
import { UploadOutlined, DownSquareOutlined, CheckSquareOutlined, ClockCircleOutlined, CopyOutlined, DeleteOutlined, DragOutlined } from '@ant-design/icons';
import type { UploadFile } from 'antd/es/upload/interface';
import { 
  ArrowLeft, 
  Save, 
  Plus, 
  Trash2, 
  MoveUp,
  MoveDown,
  Eye,
  Code,
  Undo2,
  Redo2,
  ZoomIn,
  ZoomOut,
  Grid,
  Type,
  Calendar,
  Hash,
  ToggleLeft,
  Upload as UploadIcon,
  Layout,
  FileText,
  AlertCircle
} from 'lucide-react';
import { toast } from 'sonner';
import * as FormApi from '../api/bpm/form';
import { DICT_TYPE, getIntDictOptions, setDictOptions, DictDataType } from '../utils/dict';
import { dictDataApi } from '../api/DictData';
import FormUploadField from './FormUploadField';

const { TextArea } = Input;
const { Panel } = Collapse;

// 自定义单选框图标组件
const RadioIcon: React.FC<{ className?: string }> = ({ className }) => {
  return (
    <svg
      className={className}
      viewBox="0 0 24 24"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
    >
      {/* 外层圆圈 */}
      <circle cx="12" cy="12" r="8" stroke="currentColor" strokeWidth="2" fill="none" />
      {/* 内层实心圆 */}
      <circle cx="12" cy="12" r="4" fill="currentColor" />
    </svg>
  );
};

// 表单字段类型
type FieldType = 
  | 'input' 
  | 'textarea' 
  | 'password'
  | 'select' 
  | 'date' 
  | 'daterange'
  | 'datetime'
  | 'number' 
  | 'switch' 
  | 'radio' 
  | 'checkbox'
  | 'upload'
  | 'slider'
  | 'rate'
  | 'cascader'
  | 'treeselect'
  | 'timepicker'
  | 'card'
  | 'grid'
  | 'tabs'
  | 'collapse'
  | 'alert';

interface FormField {
  id: string;
  type: FieldType;
  label: string;
  name: string;
  required?: boolean;
  placeholder?: string | string[]; // 支持字符串或数组（用于日期范围）
  options?: { label: string; value: string }[];
  defaultValue?: any;
  span?: number; // 栅格布局
  rules?: any[];
  disabled?: boolean;
  hidden?: boolean;
  width?: string | number;
  size?: 'small' | 'middle' | 'large';
  uploadType?: 'single-image' | 'multiple-image' | 'file'; // 上传类型：单图/多图/文件
  cascaderOptions?: any[]; // 级联选择器的选项数据
  maxCount?: number; // 上传文件最大数量
  accept?: string; // 上传文件类型限制
  // 新增属性
  readOnly?: boolean; // 是否只读
  maxLength?: number; // 最大输入长度
  showClear?: boolean; // 是否显示清除按钮（输入框）
  hint?: string; // 提示信息
  labelWidth?: number; // 标签宽度（px）
  fieldId?: string; // 字段ID（用于联动等）
  inputType?: string; // 输入框类型（text, password, number等）
  // 样式相关
  className?: string; // CSS类名
  style?: React.CSSProperties; // 内联样式
  margin?: { top?: number; right?: number; bottom?: number; left?: number }; // 外边距
  padding?: { top?: number; right?: number; bottom?: number; left?: number }; // 内边距
  // 验证规则
  validationRules?: Array<{
    id: string;
    type: 'min' | 'max' | 'len' | 'pattern' | 'validator' | 'required';
    trigger?: 'blur' | 'change' | 'submit'; // 验证方式：失去焦点、值改变、提交时
    value?: number | string; // 规则值（最小值、最大值、长度、正则表达式等）
    message: string; // 错误信息
    validator?: string; // 自定义验证函数（字符串形式）
    [key: string]: any;
  }>;
  requiredMessage?: string; // 必填提示语
  // 事件
  events?: {
    onChange?: string;
    onFocus?: string;
    onBlur?: string;
    [key: string]: string | undefined;
  };
  // 提示组件配置
  alertTitle?: string;
  alertDescription?: string;
  alertType?: 'success' | 'info' | 'warning' | 'error';
  alertClosable?: boolean;
  alertCloseText?: string;
  alertShowIcon?: boolean;
  alertCentered?: boolean;
  alertTheme?: 'light' | 'dark';
  // 容器相关属性
  children?: FormField[]; // 子字段（用于grid、card、tabs等容器组件）
  gridColumns?: 1 | 2 | 3; // 栅格布局的列数
  cardTitle?: string; // 卡片标题
  tabs?: Array<{ // 选项卡配置
    key: string;
    label: string;
    children?: string[]; // 选项卡内的字段ID数组
  }>;
}

// 表单配置接口
interface FormConfig {
  name: string; // 表单名称
  labelPosition?: 'left' | 'right' | 'top'; // 标签位置
  formSize?: 'small' | 'default' | 'large'; // 表单尺寸
  labelSuffix?: string; // 标签后缀
  labelWidth?: number; // 标签宽度
  hideRequiredMark?: boolean; // 隐藏必填字段的红色星号
  showValidationError?: boolean; // 显示校验错误信息
  inlineValidation?: boolean; // 以行内形式展示校验信息
  showSubmitButton?: boolean; // 是否显示表单提交按钮
  showResetButton?: boolean; // 是否显示表单重置按钮
  layoutColumns?: 1 | 2 | 3; // 表单布局列数
  useCardLayout?: boolean; // 是否使用外层卡片包装
}

// 组件库配置
type ComponentItem = {
  type: FieldType;
  label: string;
  icon: any;
  uploadType?: 'single-image' | 'multiple-image' | 'file';
  layoutColumns?: number; // 针对布局组件的列数
};

const componentLibrary: Record<string, ComponentItem[]> = {
  '输入控件': [
    { type: 'input', label: '输入框', icon: Type },
    { type: 'textarea', label: '多行输入', icon: FileText },
    { type: 'number', label: '数字输入', icon: Hash },
    { type: 'cascader', label: '联级选框', icon: DownSquareOutlined },
    { type: 'select', label: '下拉选框', icon: DownSquareOutlined },
    { type: 'switch', label: '开关', icon: ToggleLeft },
    { type: 'date', label: '日期选择', icon: Calendar },
    { type: 'daterange', label: '日期范围', icon: Calendar },
    { type: 'datetime', label: '时间日期选择器', icon: ClockCircleOutlined },
    { type: 'timepicker', label: '时间选择', icon: ClockCircleOutlined },
    { type: 'radio', label: '单选框组', icon: RadioIcon },
    { type: 'checkbox', label: '复选框组', icon: CheckSquareOutlined },
    { type: 'password', label: '密码输入', icon: Type },
    { type: 'upload', label: '单图上传', icon: UploadIcon, uploadType: 'single-image' },
    { type: 'upload', label: '多图上传', icon: UploadIcon, uploadType: 'multiple-image' },
    { type: 'upload', label: '文件上传', icon: UploadIcon, uploadType: 'file' },
    { type: 'alert', label: '提示', icon: AlertCircle },
 
    // { type: 'slider', label: '滑动条', icon: Hash },
    // { type: 'rate', label: '评分器', icon: Hash },
    // { type: 'treeselect', label: '树选择', icon: DownSquareOutlined },
  ],
  '布局组件': [
    { type: 'card', label: '卡片容器', icon: Layout },
    { type: 'grid', label: '双栏布局', icon: Grid, layoutColumns: 2 },
    // 三栏布局暂时隐藏
    // { type: 'grid', label: '三栏布局', icon: Grid, layoutColumns: 3 },
    { type: 'tabs', label: '选项卡', icon: FileText },
  ],
};

// 可拖拽的组件项
const DraggableComponent: React.FC<{ 
  type: FieldType; 
  label: string; 
  icon: any;
  uploadType?: 'single-image' | 'multiple-image' | 'file';
  layoutColumns?: number;
  onDrag: (type: FieldType, uploadType?: 'single-image' | 'multiple-image' | 'file', layoutColumns?: number, parentId?: string) => void;
}> = ({ type, label, icon: Icon, uploadType, layoutColumns, onDrag }) => {
  const [{ isDragging }, drag] = useDrag({
    type: 'component',
    item: () => {
      const dragItem = { type, uploadType, layoutColumns };
      console.log('Dragging component:', dragItem);
      return dragItem;
    },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
    end: (item, monitor) => {
      // 只有在没有成功 drop 到任何有效区域时，才添加到根级别
      // 这样可以支持从组件库直接拖到指定位置（如卡片容器）
      if (!monitor.didDrop()) {
        console.log('Component dropped outside valid area, adding to root');
        onDrag(item.type, item.uploadType, item.layoutColumns);
      } else {
        console.log('Component dropped in valid area, handled by drop event');
      }
    },
  });

  return (
    <div
      ref={drag}
      className={`flex flex-col items-center justify-center gap-2 p-3 rounded-lg cursor-move hover:bg-blue-50 transition-all border border-transparent hover:border-blue-200 ${
        isDragging ? 'opacity-50' : ''
      }`}
    >
      <div className="flex items-center justify-center w-10 h-10">
        <Icon className="w-5 h-5 text-gray-600" />
      </div>
      <span className="text-xs text-gray-700 text-center leading-tight whitespace-nowrap">{label}</span>
    </div>
  );
};

// 自定义拖拽预览层
const CustomDragLayer: React.FC<{ onDragEnd?: () => void }> = ({ onDragEnd }) => {
  const { itemType, isDragging, item, currentOffset } = useDragLayer((monitor) => ({
    item: monitor.getItem(),
    itemType: monitor.getItemType(),
    isDragging: monitor.isDragging(),
    currentOffset: monitor.getSourceClientOffset(),
  }));

  // 当拖拽结束时，清理预览状态
  const prevIsDraggingRef = React.useRef(isDragging);
  React.useEffect(() => {
    // 只在从拖拽状态变为非拖拽状态时调用
    if (prevIsDraggingRef.current && !isDragging && onDragEnd) {
      onDragEnd();
    }
    prevIsDraggingRef.current = isDragging;
  }, [isDragging, onDragEnd]);

  // 不显示预览标签，只处理拖拽结束回调
  return null;
};

// 可放置的画布区域
const CanvasDropZone: React.FC<{
  children: React.ReactNode;
  onDrop: (type: FieldType, uploadType?: 'single-image' | 'multiple-image' | 'file', layoutColumns?: number, parentId?: string) => void;
  onMoveField?: (fieldId: string, targetParentId?: string, targetIndex?: number, targetFieldId?: string) => void;
  parentId?: string;
  className?: string;
  style?: React.CSSProperties;
  fieldIndex?: number; // 用于排序的索引位置
  fieldId?: string; // 当前字段ID，用于悬停目标
  onHover?: (item: any, monitor: any) => void; // 添加 hover 回调用于实时预览
  onHoverTarget?: (fieldId: string | null) => void; // 悬停目标字段ID
}> = ({ children, onDrop, onMoveField, parentId, className = '', style, fieldIndex, fieldId, onHover, onHoverTarget }) => {
  const [{ isOver, canDrop }, drop] = useDrop({
    accept: ['component', 'field'],
    canDrop: (item: any) => {
      // 允许所有拖拽
      return true;
    },
    hover: (item: any, monitor) => {
      // 实时预览：当拖拽悬停时触发
      if (onHover && monitor.isOver({ shallow: true })) {
        onHover(item, monitor);
      }
      // 如果是拖拽字段，设置悬停目标（用于显示蓝色边框）
      if (monitor.getItemType() === 'field' && item?.fieldId && onHoverTarget) {
        // 如果悬停在一个字段上，设置该字段为悬停目标
        // 优先使用 fieldId（字段本身的ID），如果没有则使用 parentId（容器字段）
        const targetId = fieldId || (parentId && parentId !== 'root' ? parentId : null);
        if (targetId && targetId !== item.fieldId) {
          onHoverTarget(targetId);
        }
      }
    },
    drop: (item: any, monitor) => {
      // 使用 monitor.getItem() 获取原始 item，避免序列化问题
      const actualItem = monitor.getItem() || item;
      const dragType = monitor.getItemType();
      
      // 检查是否真的在这个 drop zone 上
      if (!monitor.isOver({ shallow: true })) {
        console.log('Drop ignored - not over this drop zone');
        return;
      }
      
      console.log('Drop event triggered:', { 
        item: actualItem, 
        itemType: dragType,
        itemKeys: Object.keys(actualItem || {}), 
        parentId, 
        fieldIndex,
        fieldId,
        hasFieldId: !!(actualItem?.fieldId), 
        hasType: !!(actualItem?.type),
        canDrop: monitor.canDrop(),
        didDrop: monitor.didDrop(),
        hasOnMoveField: !!onMoveField
      });
      
      // 如果是从组件库拖拽新组件
      if (dragType === 'component' && actualItem?.type && !actualItem?.fieldId) {
        console.log('Dropping new component:', actualItem.type, 'layoutColumns:', actualItem.layoutColumns, 'parentId:', parentId);
        onDrop(actualItem.type, actualItem.uploadType, actualItem.layoutColumns, parentId);
        return;
      }
      
      // 如果是拖拽已存在的字段
      if (dragType === 'field') {
        const draggedFieldId = actualItem?.fieldId;
        // 必须使用 fieldId，这是当前 drop zone 对应的字段ID
        const targetFieldId = fieldId;
        console.log('Drop field event:', { draggedFieldId, targetFieldId, parentId, fieldIndex, hasOnMoveField: !!onMoveField, fieldId });
        
        if (!draggedFieldId || !onMoveField) {
          console.warn('⚠️ Cannot move field - missing draggedFieldId or onMoveField');
          return;
        }
        
        // 如果拖拽的字段ID和目标字段ID都存在，且不相同，则进行互换
        if (targetFieldId && draggedFieldId !== targetFieldId) {
          console.log('✅ Moving field:', draggedFieldId, 'to target field:', targetFieldId, 'parent:', parentId);
          // 调用移动函数，传递目标字段ID进行互换
          console.log('✅ Calling onMoveField with:', { fieldId: draggedFieldId, targetFieldId, targetParentId: parentId });
          try {
            onMoveField(draggedFieldId, parentId, undefined, targetFieldId);
            console.log('✅ onMoveField called successfully');
          } catch (error) {
            console.error('❌ Error calling onMoveField:', error);
          }
          return;
        }
        
        // 如果没有目标字段ID，但有索引，则插入到指定位置
        if (fieldIndex !== undefined && fieldIndex >= 0) {
          console.log('✅ Moving field to index:', draggedFieldId, 'to index:', fieldIndex, 'parent:', parentId);
          try {
            onMoveField(draggedFieldId, parentId, fieldIndex);
            console.log('✅ onMoveField called successfully (by index)');
          } catch (error) {
            console.error('❌ Error calling onMoveField:', error);
          }
          return;
        }
        
        // 如果都没有，添加到末尾
        console.log('✅ Moving field to end:', draggedFieldId, 'parent:', parentId);
        try {
          onMoveField(draggedFieldId, parentId);
          console.log('✅ onMoveField called successfully (to end)');
        } catch (error) {
          console.error('❌ Error calling onMoveField:', error);
        }
      }
      
      console.log('Drop event ignored:', { dragType, hasFieldId: !!actualItem?.fieldId, hasType: !!actualItem?.type });
    },
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
    }),
  });

  return (
    <div
      ref={drop}
      className={`min-h-[80px] transition-colors ${className} ${
        isOver ? 'bg-blue-50 border-2 border-blue-300 border-dashed rounded' : ''
      }`}
      style={{ 
        ...style, 
        position: 'relative', 
        zIndex: 1,
        width: '100%',
        height: '100%',
        minHeight: '80px',
        // 确保 drop 区域能够接收事件
        pointerEvents: 'auto'
      }}
    >
      {children}
    </div>
  );
};

// 字段渲染组件（支持容器和嵌套）
const FieldRenderer: React.FC<{
  field: FormField;
  isSelected: boolean;
  onSelect: () => void;
  onDelete: () => void;
  onAddFieldToContainer?: (parentId: string, type: FieldType, uploadType?: 'single-image' | 'multiple-image' | 'file', layoutColumns?: number) => void;
  onMoveField?: (fieldId: string, targetParentId?: string, targetIndex?: number, targetFieldId?: string) => void;
  onUpdateField?: (fieldId: string, updates: Partial<FormField>) => void;
  onDeleteField?: (fieldId: string) => void;
  onSelectField?: (fieldId: string) => void;
  onCopyField?: (fieldId: string) => void;
  formConfig?: FormConfig;
  selectedFieldId?: string | null;
  allFields?: FormField[];
  draggingFieldId?: string | null;
  hoverTargetId?: string | null;
  onDragStart?: (fieldId: string) => void;
  onDragEnd?: () => void;
  onHoverTarget?: (fieldId: string | null) => void;
  dragPreview?: {
    targetParentId?: string;
    targetIndex?: number;
    show: boolean;
  };
  setDragPreview?: (preview: {
    targetParentId?: string;
    targetIndex?: number;
    show: boolean;
  }) => void;
}> = ({ 
  field, 
  isSelected, 
  onSelect, 
  onDelete,
  onAddFieldToContainer,
  onMoveField,
  onUpdateField,
  onDeleteField,
  onSelectField,
  onCopyField,
  formConfig,
  selectedFieldId,
  allFields = [],
  draggingFieldId,
  hoverTargetId,
  onDragStart,
  onDragEnd,
  onHoverTarget,
  dragPreview,
  setDragPreview
}) => {
  // 让字段可以拖拽
  const [{ isDragging }, drag, dragPreviewRef] = useDrag({
    type: 'field',
    item: () => {
      const dragItem = { fieldId: field.id };
      console.log('Dragging field:', field.id, 'item:', dragItem);
      // 在 item 函数中调用 onDragStart（替代已弃用的 begin）
      if (onDragStart) {
        onDragStart(field.id);
      }
      return dragItem;
    },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
    end: (item, monitor) => {
      if (onDragEnd) {
        onDragEnd();
      }
      if (onHoverTarget) {
        onHoverTarget(null);
      }
      if (monitor.didDrop()) {
        console.log('Drag dropped successfully:', item);
      } else {
        console.log('Drag cancelled or dropped outside');
      }
    },
  });

  // 拖拽时隐藏原位置的元素，使用自定义预览
  useEffect(() => {
    if (isDragging) {
      dragPreviewRef(<div style={{ display: 'none' }} />, { offsetX: 0, offsetY: 0 });
    }
  }, [isDragging, dragPreviewRef]);

  // 判断字段是否为选择类字段（包括单选和多选）
  const isSelectType = (type: FieldType): boolean => {
    return ['select', 'date', 'daterange', 'datetime', 'timepicker', 'cascader', 'radio', 'checkbox'].includes(type);
  };

  // 获取默认必填验证消息
  const getDefaultRequiredMessage = (field: FormField): string => {
    // 单选和多选组件明确使用"请选择"提示
    if (field.type === 'radio' || field.type === 'checkbox') {
      return `请选择${field.label}`;
    }
    if (isSelectType(field.type)) {
      return `请选择${field.label}`;
    }
    return `${field.label}不能为空`;
  };

  const renderField = () => {
    const baseProps = {
      disabled: field.disabled,
      size: field.size || 'middle',
    };

    switch (field.type) {
      case 'input':
        return (
          <Input 
            {...baseProps} 
            type={field.inputType || 'text'}
            placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
            allowClear={field.showClear}
            maxLength={field.maxLength}
            readOnly={field.readOnly}
          />
        );
      case 'textarea':
        return (
          <TextArea 
            {...baseProps} 
            rows={4} 
            placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
            allowClear={field.showClear}
            maxLength={field.maxLength}
            readOnly={field.readOnly}
          />
        );
      case 'password':
        return (
          <Input.Password 
            {...baseProps} 
            placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
            allowClear={field.showClear}
            maxLength={field.maxLength}
            readOnly={field.readOnly}
          />
        );
      case 'select':
        return (
          <Select 
            {...baseProps} 
            placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
            allowClear={field.showClear}
          >
            {field.options?.map((opt, idx) => (
              <Select.Option key={idx} value={opt.value}>{opt.label}</Select.Option>
            ))}
          </Select>
        );
      case 'date':
        return (
          <DatePicker 
            {...baseProps} 
            className="w-full" 
            placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
            allowClear={field.showClear}
          />
        );
      case 'daterange':
        return (
          <DatePicker.RangePicker 
            placeholder={Array.isArray(field.placeholder) ? field.placeholder as [string, string] : ['开始日期', '结束日期']}
            disabled={field.disabled}
            size={field.size || 'middle'}
            className="w-full"
            allowClear={field.showClear}
          />
        );
      case 'datetime':
        return (
          <DatePicker 
            {...baseProps} 
            className="w-full" 
            placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
            allowClear={field.showClear}
            showTime={{ format: 'HH:mm:ss' }}
            format="YYYY-MM-DD HH:mm:ss"
          />
        );
      case 'timepicker':
        return (
          <TimePicker 
            {...baseProps} 
            className="w-full" 
            placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
            allowClear={field.showClear}
            format="HH:mm:ss"
          />
        );
      case 'number':
        return (
          <InputNumber 
            {...baseProps} 
            className="w-full" 
            placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
            max={field.maxLength}
            readOnly={field.readOnly}
          />
        );
      case 'switch':
        return <Switch disabled={field.disabled} />;
      case 'radio':
        return (
          <Radio.Group disabled={field.disabled}>
            {field.options?.map((opt, idx) => (
              <Radio key={idx} value={opt.value}>{opt.label}</Radio>
            ))}
          </Radio.Group>
        );
      case 'checkbox':
        return (
          <Checkbox.Group disabled={field.disabled}>
            {field.options?.map((opt, idx) => (
              <Checkbox key={idx} value={opt.value}>{opt.label}</Checkbox>
            ))}
          </Checkbox.Group>
        );
      case 'cascader':
        return (
          <Cascader
            {...baseProps}
            placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
            options={field.cascaderOptions || []}
            className="w-full"
            allowClear={field.showClear}
          />
        );
      case 'upload':
        const uploadProps = {
          disabled: field.disabled,
          maxCount: field.uploadType === 'single-image' ? 1 : field.maxCount || (field.uploadType === 'multiple-image' ? 9 : undefined),
          accept: field.accept || (field.uploadType === 'single-image' || field.uploadType === 'multiple-image' ? 'image/*' : undefined),
          listType: (field.uploadType === 'file' ? 'text' : 'picture-card') as 'text' | 'picture-card' | 'picture',
          multiple: field.uploadType !== 'single-image',
        };
        return (
          <Upload {...uploadProps}>
            {field.uploadType === 'file' ? (
              <Button icon={<UploadOutlined />}>上传文件</Button>
            ) : (
              <div>
                <UploadOutlined />
                <div style={{ marginTop: 8 }}>上传</div>
              </div>
            )}
          </Upload>
        );
      case 'alert':
        const themeClass =
          field.alertTheme === 'dark'
            ? 'bg-gray-800 text-white border-gray-700'
            : '';
        return (
          <Alert
            message={field.alertTitle || field.label}
            description={field.alertDescription}
            type={field.alertType || 'info'}
            showIcon={field.alertShowIcon !== false}
            closable={field.alertClosable}
            closeText={field.alertCloseText}
            className={`${field.alertCentered ? 'text-center' : ''} ${themeClass}`}
            banner
            style={field.style}
          />
        );
      default:
        return <Input {...baseProps} placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined} />;
    }
  };


  const fieldContainerStyle: React.CSSProperties = {
    marginTop: field.margin?.top,
    marginRight: field.margin?.right,
    marginBottom: field.margin?.bottom,
    marginLeft: field.margin?.left,
    padding: field.padding ? `${field.padding.top || 0}px ${field.padding.right || 0}px ${field.padding.bottom || 0}px ${field.padding.left || 0}px` : undefined,
  };

  // 如果是容器组件（grid或card），渲染容器及其子字段
  if (field.type === 'grid') {
    const gridColumns = field.gridColumns || 2;
    const children = field.children || [];
    
    return (
      <div
        ref={drag}
        className={`relative border-2 rounded-lg transition-all cursor-move ${
          isSelected 
            ? 'border-blue-500 bg-blue-50 shadow-md' 
            : 'border-dashed border-gray-300 hover:border-blue-300 hover:bg-gray-50'
        } ${isDragging ? 'opacity-0' : ''}`}
        onClick={(e) => {
          // 如果点击的是容器头部区域，选中容器
          if ((e.target as HTMLElement).closest('.grid-header')) {
            e.stopPropagation();
            onSelect();
          }
        }}
        style={fieldContainerStyle}
      >
        <div 
          className="p-2 border-b border-gray-200 bg-gray-50 flex items-center justify-between grid-header"
          onClick={(e) => {
            e.stopPropagation();
            onSelect();
          }}
        >
          <span className="text-xs text-gray-600">{field.label || `${gridColumns}栏布局`}</span>
          {isSelected && (
            <Button
              type="text"
              size="small"
              icon={<Trash2 className="w-3 h-3" />}
              onClick={(e) => {
                e.stopPropagation();
                onDelete();
              }}
              danger
            />
          )}
        </div>
        <CanvasDropZone
          onDrop={(type, uploadType, layoutCols) => {
            if (onAddFieldToContainer) {
              onAddFieldToContainer(field.id, type, uploadType, layoutCols);
            }
          }}
          onMoveField={onMoveField}
          parentId={field.id}
          className="p-4"
          style={{ minHeight: '100px', width: '100%' }}
        >
          <div
            style={{
              display: 'grid',
              gridTemplateColumns: `repeat(${gridColumns}, minmax(0, 1fr))`,
              gap: '12px',
            }}
          >
            {children.length === 0 ? (
              // 如果还没有子字段，为每一列创建独立的拖拽区域
              Array.from({ length: gridColumns }).map((_, idx) => (
                <CanvasDropZone
                  key={idx}
                  onDrop={(type, uploadType, layoutCols) => {
                    if (onAddFieldToContainer) {
                      onAddFieldToContainer(field.id, type, uploadType, layoutCols);
                    }
                  }}
                  onMoveField={onMoveField}
                  parentId={field.id}
                  fieldIndex={idx}
                  className="min-h-[100px]"
                  style={{ minHeight: '100px', width: '100%' }}
                >
                  <div className="border-2 border-dashed border-gray-300 rounded p-4 min-h-[80px] flex items-center justify-center text-gray-400 text-xs">
                    拖拽组件到第 {idx + 1} 列
                  </div>
                </CanvasDropZone>
              ))
            ) : (
              // 如果有子字段，每个子字段占据相应的列，并且每个子字段都可以嵌套容器
              children.map((childField) => (
                <div
                  key={childField.id}
                  style={
                    gridColumns > 1
                      ? { gridColumn: `span ${Math.min(gridColumns, childField.span || 1)}` }
                      : undefined
                  }
                >
                  <FieldRenderer
                    field={childField}
                    isSelected={selectedFieldId === childField.id}
                    onSelect={() => onSelectField?.(childField.id)}
                    onDelete={() => onDeleteField?.(childField.id)}
                    onAddFieldToContainer={onAddFieldToContainer}
                    onMoveField={onMoveField}
                    onUpdateField={onUpdateField}
                    onDeleteField={onDeleteField}
                    onSelectField={onSelectField}
                    onCopyField={onCopyField}
                    formConfig={formConfig}
                    selectedFieldId={selectedFieldId}
                    allFields={allFields}
                    draggingFieldId={draggingFieldId}
                    hoverTargetId={hoverTargetId}
                    onDragStart={onDragStart}
                    onDragEnd={onDragEnd}
                    onHoverTarget={onHoverTarget}
                  />
                </div>
              ))
            )}
          </div>
        </CanvasDropZone>
      </div>
    );
  }

  if (field.type === 'card') {
    const children = field.children || [];
    // 优先使用 label（字段名称），如果没有则使用 cardTitle，最后使用默认值
    const cardTitle = field.label || field.cardTitle || '卡片容器';
    
    return (
      <div
        ref={drag}
        className={`relative border-2 rounded-lg transition-all cursor-move ${
          isSelected 
            ? 'border-blue-500 bg-blue-50 shadow-md' 
            : 'border-dashed border-gray-300 hover:border-blue-300 hover:bg-gray-50'
        } ${isDragging ? 'opacity-0' : ''}`}
        onClick={(e) => {
          // 如果点击的是容器头部区域，选中容器
          if ((e.target as HTMLElement).closest('.card-header')) {
            e.stopPropagation();
            onSelect();
          }
        }}
        style={fieldContainerStyle}
      >
        <div 
          className="p-2 border-b border-gray-200 bg-gray-50 flex items-center justify-between card-header"
          onClick={(e) => {
            e.stopPropagation();
            onSelect();
          }}
        >
          <span className="text-xs text-gray-600 font-medium">{cardTitle}</span>
          {isSelected && (
            <Button
              type="text"
              size="small"
              icon={<Trash2 className="w-3 h-3" />}
              onClick={(e) => {
                e.stopPropagation();
                onDelete();
              }}
              danger
            />
          )}
        </div>
        <CanvasDropZone 
          onDrop={(type, uploadType, layoutCols) => {
            console.log('Card container onDrop called:', { type, uploadType, layoutCols, parentId: field.id });
            if (onAddFieldToContainer) {
              console.log('Calling onAddFieldToContainer');
              onAddFieldToContainer(field.id, type, uploadType, layoutCols);
            } else {
              console.log('onAddFieldToContainer is not defined!');
            }
          }}
          onMoveField={onMoveField}
          parentId={field.id}
          className="p-4"
          style={{ minHeight: '100px', width: '100%', position: 'relative', zIndex: 10 }}
        >
          {children.length === 0 ? (
            <div className="border-2 border-dashed border-gray-300 rounded p-8 min-h-[100px] flex items-center justify-center text-gray-400 text-xs opacity-0 hover:opacity-100 transition-opacity">
              拖拽组件到此卡片容器内
            </div>
          ) : (
            <div className="space-y-4">
              {children.map((childField, idx) => (
                <React.Fragment key={childField.id}>
                  <CanvasDropZone
                    onDrop={(type, uploadType, layoutCols) => {
                      if (onAddFieldToContainer) {
                        onAddFieldToContainer(field.id, type, uploadType, layoutCols);
                      }
                      setDragPreview({ show: false });
                    }}
                    onMoveField={onMoveField}
                    onHover={(item, monitor) => {
                      if (monitor.getItemType() === 'field') {
                        // 拖拽到组件上时，设置悬停目标用于视觉反馈
                        if (onHoverTarget) {
                          onHoverTarget(childField.id);
                        }
                      }
                    }}
                    onHoverTarget={onHoverTarget}
                    fieldIndex={idx}
                    fieldId={childField.id}
                    parentId={field.id}
                    className="min-h-[50px] w-full"
                  >
                    <FieldRenderer
                      field={childField}
                      isSelected={selectedFieldId === childField.id}
                      onSelect={() => onSelectField?.(childField.id)}
                      onDelete={() => onDeleteField?.(childField.id)}
                      onAddFieldToContainer={onAddFieldToContainer}
                      onMoveField={onMoveField}
                      onUpdateField={onUpdateField}
                      onDeleteField={onDeleteField}
                      onSelectField={onSelectField}
                      onCopyField={onCopyField}
                      formConfig={formConfig}
                      selectedFieldId={selectedFieldId}
                      allFields={allFields}
                      draggingFieldId={draggingFieldId}
                      hoverTargetId={hoverTargetId}
                      onDragStart={onDragStart}
                      onDragEnd={onDragEnd}
                      onHoverTarget={onHoverTarget}
                      dragPreview={dragPreview}
                      setDragPreview={setDragPreview}
                    />
                  </CanvasDropZone>
                </React.Fragment>
              ))}
            </div>
          )}
        </CanvasDropZone>
      </div>
    );
  }

  // 普通字段的渲染
  const labelWidth = field.labelWidth || formConfig?.labelWidth || 100;
  
  // 判断是否显示占位符（当其他字段正在拖拽且悬停在此字段位置时）
  const isPlaceholder = draggingFieldId && draggingFieldId !== field.id && hoverTargetId === field.id;
  const isHovered = hoverTargetId === field.id && draggingFieldId && draggingFieldId !== field.id;
  
  return (
    <>
      {/* 拖拽占位符：当其他字段拖拽到此位置时显示 - 已移除，改用插入指示器 */}
      <div
        ref={drag}
        className={`relative p-4 border-2 rounded-lg transition-all cursor-move ${
          isSelected 
            ? 'border-blue-500 bg-blue-50 shadow-md' 
            : isHovered
            ? 'border-blue-400 bg-blue-50 shadow-sm'
            : 'border-gray-200 hover:border-gray-300 hover:bg-gray-50'
        } ${isDragging ? 'opacity-30' : ''}`}
        onClick={(e) => {
          e.stopPropagation();
          onSelect();
        }}
        style={{
          ...fieldContainerStyle,
          // 当正在拖拽其他字段时，禁用指针事件，让 drop 事件能够正确触发
          pointerEvents: (draggingFieldId && draggingFieldId !== field.id) ? 'none' : 'auto'
        }}
      >
      {field.type === 'alert' ? (
        <div>
          {renderField()}
          {field.hint && <div className="text-xs text-gray-400 mt-2">{field.hint}</div>}
        </div>
      ) : (
        <AntdForm.Item
          label={field.label + (formConfig?.labelSuffix || '')}
          required={field.required && !formConfig?.hideRequiredMark}
          labelCol={
            formConfig?.labelPosition === 'top'
              ? undefined
              : {
                  flex: `${labelWidth}px`,
                  style: {
                    minWidth: `${labelWidth}px`,
                    textAlign:
                      formConfig?.labelPosition === 'right'
                        ? 'right'
                        : 'left',
                  },
                }
          }
          wrapperCol={formConfig?.labelPosition === 'top' ? undefined : { flex: 'auto' }}
          className="mb-0"
          rules={(() => {
            const rules: any[] = [];
            
            // 必填规则
            if (field.required) {
              rules.push({
                required: true,
                message: field.requiredMessage || getDefaultRequiredMessage(field),
                trigger: 'blur'
              });
            }

            // 其他验证规则
            field.validationRules?.forEach(rule => {
              if (rule.type === 'min') {
                if (field.type === 'number') {
                  rules.push({
                    type: 'number',
                    min: rule.value,
                    message: rule.message || `值不能小于${rule.value}`,
                    trigger: rule.trigger || 'blur'
                  });
                } else {
                  rules.push({
                    validator: (_: any, value: any) => {
                      if (!value) return Promise.resolve();
                      const numValue = Number(value);
                      if (isNaN(numValue)) {
                        return Promise.reject(rule.message || `值不能小于${rule.value}`);
                      }
                      if (numValue < (rule.value as number)) {
                        return Promise.reject(rule.message || `值不能小于${rule.value}`);
                      }
                      return Promise.resolve();
                    },
                    trigger: rule.trigger || 'blur'
                  });
                }
              } else if (rule.type === 'max') {
                if (field.type === 'number') {
                  rules.push({
                    type: 'number',
                    max: rule.value,
                    message: rule.message || `值不能大于${rule.value}`,
                    trigger: rule.trigger || 'blur'
                  });
                } else {
                  rules.push({
                    validator: (_: any, value: any) => {
                      if (!value) return Promise.resolve();
                      const numValue = Number(value);
                      if (isNaN(numValue)) {
                        return Promise.reject(rule.message || `值不能大于${rule.value}`);
                      }
                      if (numValue > (rule.value as number)) {
                        return Promise.reject(rule.message || `值不能大于${rule.value}`);
                      }
                      return Promise.resolve();
                    },
                    trigger: rule.trigger || 'blur'
                  });
                }
              } else if (rule.type === 'len') {
                rules.push({
                  len: rule.value,
                  message: rule.message || `长度必须为${rule.value}`,
                  trigger: rule.trigger || 'blur'
                });
              } else if (rule.type === 'pattern') {
                try {
                  const pattern = new RegExp(rule.value as string);
                  rules.push({
                    pattern,
                    message: rule.message || '格式不正确',
                    trigger: rule.trigger || 'blur'
                  });
                } catch (e) {
                  console.error('正则表达式错误:', e);
                }
              } else if (rule.type === 'validator') {
                rules.push({
                  validator: (_: any, value: any) => {
                    if (rule.validator) {
                      try {
                        const fn = new Function('value', 'rule', rule.validator);
                        const result = fn(value, rule);
                        if (result === false || (result instanceof Error)) {
                          return Promise.reject(rule.message || '验证失败');
                        }
                        return Promise.resolve();
                      } catch (e) {
                        console.error('自定义验证函数错误:', e);
                        return Promise.reject(rule.message || '验证失败');
                      }
                    }
                    return Promise.resolve();
                  },
                  trigger: rule.trigger || 'blur'
                });
              }
            });

            return rules;
          })()}
        >
          <div 
            style={field.style} 
            className={field.className}
        >
          {renderField()}
          </div>
          {field.hint && (
            <div className="text-xs text-gray-400 mt-1">{field.hint}</div>
          )}
        </AntdForm.Item>
      )}
      {isSelected && (
        <Button
          type="text"
          size="small"
          icon={<Trash2 className="w-3 h-3" />}
          onClick={(e) => {
            e.stopPropagation();
            onDelete();
          }}
          danger
          className="absolute hover:bg-red-50"
          style={{ 
            position: 'absolute',
            bottom: '8px',
            right: '10px',
            zIndex: 10
          }}
        />
      )}
      </div>
    </>
  );
};

export default function FormDesigner() {
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const formType = searchParams.get('type') || 'create';
  const formId = searchParams.get('id');

  // 判断字段是否为选择类字段（包括单选和多选）
  const isSelectType = (type: FieldType): boolean => {
    return ['select', 'date', 'daterange', 'datetime', 'timepicker', 'cascader', 'radio', 'checkbox'].includes(type);
  };

  // 获取默认必填验证消息
  const getDefaultRequiredMessage = (field: FormField): string => {
    // 单选和多选组件明确使用"请选择"提示
    if (field.type === 'radio' || field.type === 'checkbox') {
      return `请选择${field.label}`;
    }
    if (isSelectType(field.type)) {
      return `请选择${field.label}`;
    }
    return `${field.label}不能为空`;
  };

  const [formName, setFormName] = useState('');
  const [formRemark, setFormRemark] = useState('');
  const [fields, setFields] = useState<FormField[]>([]);
  const [selectedFieldId, setSelectedFieldId] = useState<string | null>(null);
  const [draggingFieldId, setDraggingFieldId] = useState<string | null>(null); // 正在拖拽的字段ID
  const [hoverTargetId, setHoverTargetId] = useState<string | null>(null); // 悬停目标字段ID（用于显示蓝色边框）
  const [saving, setSaving] = useState(false);
  const [previewVisible, setPreviewVisible] = useState(false);
  const [codeVisible, setCodeVisible] = useState(false);
  const [saveModalVisible, setSaveModalVisible] = useState(false);
  const [previewForm] = AntdForm.useForm();
  
  // 拖拽预览状态：用于实时显示插入位置
  const [dragPreview, setDragPreview] = useState<{
    targetParentId?: string;
    targetIndex?: number;
    show: boolean;
  }>({ show: false });
  const [configTab, setConfigTab] = useState<'component' | 'form'>('form');
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);

  const markDirty = () => setHasUnsavedChanges(true);
  
  const backToFormManagementMenu = () => {
    // 默认返回：隔离作业 -> 表单管理
    let menuInfo = { menu: 'isolationWork', subMenu: 'formManagement' };
    try {
      const source = sessionStorage.getItem('formDesignerSource');
      if (source) {
        const parsed = JSON.parse(source);
        if (parsed?.menu && parsed?.subMenu) {
          menuInfo = { menu: parsed.menu, subMenu: parsed.subMenu };
        }
        sessionStorage.removeItem('formDesignerSource');
      }
    } catch (e) {
      console.error('解析 formDesignerSource 失败:', e);
    }

    sessionStorage.setItem('navigateToMenu', JSON.stringify(menuInfo));
    sessionStorage.setItem('lastActiveMenu', JSON.stringify(menuInfo));
    navigate('/dashboard');
  };

  const handleBack = () => {
    if (!hasUnsavedChanges || fields.length === 0) {
      backToFormManagementMenu();
      return;
    }
    Modal.confirm({
      title: '未保存提示',
      content: '当前表单尚未保存，离开将丢失更改，是否继续？',
      okText: '离开',
      okType: 'danger',
      cancelText: '取消',
      onOk: () => backToFormManagementMenu(),
    });
  };

  // 当没有字段时，自动切换到表单配置
  useEffect(() => {
    if (fields.length === 0 && configTab === 'component') {
      setConfigTab('form');
    }
    // 有字段时不强制切换，保留用户手动选择的标签
  }, [fields.length, configTab]);
  const defaultFormConfig: FormConfig = {
    name: '',
    labelPosition: 'right',
    formSize: 'default',
    labelSuffix: '',
    labelWidth: 100,
    hideRequiredMark: false,
    showValidationError: true,
    inlineValidation: false,
    showSubmitButton: true, // 预览默认显示提交按钮
    showResetButton: false,
    layoutColumns: 1,
    useCardLayout: true,
  };

  const [formConfig, setFormConfig] = useState<FormConfig>(defaultFormConfig);
  const [formStatus, setFormStatus] = useState<number>(0); // 0-开启 1-关闭（与后端约定保持一致）
  const [statusOptions, setStatusOptions] = useState(() => getIntDictOptions(DICT_TYPE.COMMON_STATUS));

  // 加载 COMMON_STATUS 字典数据
  const loadCommonStatusDict = async () => {
    try {
      const response = await dictDataApi.getDictDataPage({
        pageNo: 1,
        pageSize: -1,
        dictType: DICT_TYPE.COMMON_STATUS,
      });
      const data = (response as any)?.data || response;
      const dictList = data?.list || [];
      if (Array.isArray(dictList) && dictList.length > 0) {
        const dictOptions: DictDataType[] = dictList.map((item: any) => ({
          dictType: item.dictType,
          label: item.label,
          value: item.value,
          colorType: item.colorType || '',
          cssClass: item.cssClass || '',
        }));
        setDictOptions(DICT_TYPE.COMMON_STATUS, dictOptions);
        // 更新状态选项
        setStatusOptions(getIntDictOptions(DICT_TYPE.COMMON_STATUS));
        console.log('FormDesigner: 获取通用状态字典成功', dictOptions);
      }
    } catch (error) {
      console.error('加载通用状态字典数据失败:', error);
    }
  };

  // 组件挂载时加载字典数据
  useEffect(() => {
    loadCommonStatusDict();
  }, []);

  const updateFormConfig = (updater: Partial<FormConfig> | ((prev: FormConfig) => FormConfig)) => {
    setFormConfig(prev => {
      const next = typeof updater === 'function' ? (updater as (p: FormConfig) => FormConfig)(prev) : { ...prev, ...updater };
      return next;
    });
    markDirty();
  };

  // 加载表单数据
  React.useEffect(() => {
    if (formId && (formType === 'update' || formType === 'copy')) {
      loadFormData(Number(formId));
    }
  }, [formId, formType]);

  // 刷新/关闭页面提示
  useEffect(() => {
    const handler = (e: BeforeUnloadEvent) => {
      if (!hasUnsavedChanges) return;
      e.preventDefault();
      e.returnValue = '';
    };
    window.addEventListener('beforeunload', handler);
    return () => window.removeEventListener('beforeunload', handler);
  }, [hasUnsavedChanges]);

  const loadFormData = async (id: number) => {
    try {
      const data = await FormApi.getForm(id);
      // 如果是复制表单，清除 id 并修改表单名称
      if (formType === 'copy') {
        setFormName((data.name || '') + '_copy');
      } else {
        setFormName(data.name || '');
      }
      
      setFormRemark(data.remark || '');
      if (typeof data.status !== 'undefined') {
        setFormStatus(Number(data.status));
      }
      
      let parsedFields: FormField[] = [];
      if (data.fields) {
        try {
          const fieldsData = typeof data.fields === 'string' 
            ? JSON.parse(data.fields) 
            : data.fields;
          
          if (Array.isArray(fieldsData)) {
            parsedFields = fieldsData.map((field: any, index: number) => {
              let parsedField = field;
              if (typeof field === 'string') {
                try {
                  parsedField = JSON.parse(field);
                  console.log(`字段 ${index} - 从字符串解析:`, parsedField);
                } catch (err) {
                  console.error('单个字段解析失败:', err);
                  parsedField = {};
                }
              } else {
                console.log(`字段 ${index} - 直接使用对象:`, parsedField);
              }
              
              // 递归解析 children（支持嵌套结构）
              const parseChildren = (children: any[]): FormField[] => {
                if (!Array.isArray(children)) return [];
                return children.map((child: any) => {
                  let parsedChild = child;
                  if (typeof child === 'string') {
                    try {
                      parsedChild = JSON.parse(child);
                    } catch (err) {
                      console.error('解析子字段失败:', err);
                      parsedChild = {};
                    }
                  }
                  return {
                    id: parsedChild.id || `field_${Date.now()}_${Math.random()}`,
                    type: parsedChild.type || 'input',
                    label: parsedChild.label || parsedChild.title || '',
                    name: parsedChild.name || parsedChild.field || '',
                    required: parsedChild.required || false,
                    placeholder: parsedChild.placeholder || '',
                    options: parsedChild.options || [],
                    defaultValue: parsedChild.defaultValue,
                    span: parsedChild.span,
                    rules: parsedChild.rules,
                    disabled: parsedChild.disabled,
                    hidden: parsedChild.hidden,
                    width: parsedChild.width,
                    size: parsedChild.size,
                    uploadType: parsedChild.uploadType,
                    cascaderOptions: parsedChild.cascaderOptions,
                    maxCount: parsedChild.maxCount,
                    accept: parsedChild.accept,
                    readOnly: parsedChild.readOnly,
                    maxLength: parsedChild.maxLength,
                    showClear: parsedChild.showClear,
                    hint: parsedChild.hint,
                    labelWidth: parsedChild.labelWidth,
                    fieldId: parsedChild.fieldId,
                    inputType: parsedChild.inputType,
                    className: parsedChild.className,
                    style: parsedChild.style,
                    margin: parsedChild.margin,
                    padding: parsedChild.padding,
                    validationRules: parsedChild.validationRules,
                    events: parsedChild.events,
                    requiredMessage: parsedChild.requiredMessage,
                    alertTitle: parsedChild.alertTitle,
                    alertDescription: parsedChild.alertDescription,
                    alertType: parsedChild.alertType,
                    alertClosable: parsedChild.alertClosable,
                    alertCloseText: parsedChild.alertCloseText,
                    alertShowIcon: parsedChild.alertShowIcon,
                    alertCentered: parsedChild.alertCentered,
                    alertTheme: parsedChild.alertTheme,
                    // 容器类型特有字段
                    gridColumns: parsedChild.gridColumns,
                    cardTitle: parsedChild.cardTitle,
                    // 递归解析子字段
                    children: parsedChild.children ? parseChildren(parsedChild.children) : undefined,
                  };
                });
              };

              const mappedField = {
                id: parsedField.id || `field_${Date.now()}_${index}`, // 复制时生成新的 id
                type: parsedField.type || 'input',
                label: parsedField.label || parsedField.title || '',
                name: parsedField.name || parsedField.field || '',
                required: parsedField.required || false,
                placeholder: parsedField.placeholder || '',
                options: parsedField.options || [],
                defaultValue: parsedField.defaultValue,
                span: parsedField.span,
                rules: parsedField.rules,
                disabled: parsedField.disabled,
                hidden: parsedField.hidden,
                width: parsedField.width,
                size: parsedField.size,
                uploadType: parsedField.uploadType,
                cascaderOptions: parsedField.cascaderOptions,
                maxCount: parsedField.maxCount,
                accept: parsedField.accept,
                readOnly: parsedField.readOnly,
                maxLength: parsedField.maxLength,
                showClear: parsedField.showClear,
                hint: parsedField.hint,
                labelWidth: parsedField.labelWidth,
                fieldId: parsedField.fieldId,
                inputType: parsedField.inputType,
                className: parsedField.className,
                style: parsedField.style,
                margin: parsedField.margin,
                padding: parsedField.padding,
                validationRules: parsedField.validationRules,
                events: parsedField.events,
                requiredMessage: parsedField.requiredMessage,
                alertTitle: parsedField.alertTitle,
                alertDescription: parsedField.alertDescription,
                alertType: parsedField.alertType,
                alertClosable: parsedField.alertClosable,
                alertCloseText: parsedField.alertCloseText,
                alertShowIcon: parsedField.alertShowIcon,
                alertCentered: parsedField.alertCentered,
                alertTheme: parsedField.alertTheme,
                // 容器类型特有字段
                gridColumns: parsedField.gridColumns,
                cardTitle: parsedField.cardTitle,
                // 递归解析子字段
                children: parsedField.children ? parseChildren(parsedField.children) : undefined,
              };
              
              console.log(`字段 ${index} - 映射后的字段对象:`, mappedField);
              return mappedField;
            });
          }
          
        } catch (e) {
          console.error('解析字段数据失败:', e);
        }
      }
      setFields(parsedFields);
      setHasUnsavedChanges(false);
      
      // 加载表单配置
      if (data.conf) {
        try {
          const confData = typeof data.conf === 'string' ? JSON.parse(data.conf) : data.conf;
          
          if (confData.formConfig) {
            const mergedConfig = { 
              ...defaultFormConfig, 
              ...confData.formConfig,
              // 优先使用 data.name（表单本身的名称），如果没有则使用配置中的名称
              name: data.name || confData.formConfig.name || ''
            };
            setFormConfig(mergedConfig);
            
            // 如果表单配置中有名称且当前表单名称为空，则使用配置中的名称
            if (confData.formConfig.name && !formName) {
              if (formType === 'copy') {
                setFormName(confData.formConfig.name + '_copy');
              } else {
                setFormName(confData.formConfig.name);
              }
            }
          } else {
            // 如果没有 formConfig，但 data.name 存在，也应该设置到 formConfig 中
            if (data.name) {
              setFormConfig(prev => ({
                ...prev,
                name: data.name || ''
              }));
            }
          }
        } catch (e) {
          console.error('解析表单配置失败:', e);
          // 即使解析失败，也应该设置表单名称
          if (data.name) {
            setFormConfig(prev => ({
              ...prev,
              name: data.name || ''
            }));
          }
        }
      } else {
        // 如果没有 conf 数据，也应该设置表单名称到 formConfig 中
        if (data.name) {
          setFormConfig(prev => ({
            ...prev,
            name: data.name || ''
          }));
        }
      }
      
    } catch (error: any) {
      toast.error(error.message || '加载表单数据失败');
    }
  };

  // 递归查找字段
  const findField = (fields: FormField[], fieldId: string): FormField | null => {
    for (const field of fields) {
      if (field.id === fieldId) {
        return field;
      }
      if (field.children && field.children.length > 0) {
        const found = findField(field.children, fieldId);
        if (found) return found;
      }
    }
    return null;
  };

  // 递归更新字段
  const updateFieldRecursive = (fields: FormField[], fieldId: string, updates: Partial<FormField>): FormField[] => {
    return fields.map(field => {
      if (field.id === fieldId) {
        return { ...field, ...updates };
      }
      if (field.children && field.children.length > 0) {
        return { ...field, children: updateFieldRecursive(field.children, fieldId, updates) };
      }
      return field;
    });
  };

  // 递归删除字段
  const deleteFieldRecursive = (fields: FormField[], fieldId: string): FormField[] => {
    return fields.filter(field => {
      if (field.id === fieldId) {
        return false;
      }
      if (field.children && field.children.length > 0) {
        field.children = deleteFieldRecursive(field.children, fieldId);
      }
      return true;
    });
  };

  // 递归复制字段（深拷贝并生成新ID）
  const copyFieldRecursive = (field: FormField, parentFields: FormField[] = []): FormField => {
    const newId = `field_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    const copiedField: FormField = {
      ...field,
      id: newId,
    };
    
    // 如果有子字段，递归复制
    if (field.children && field.children.length > 0) {
      copiedField.children = field.children.map(child => copyFieldRecursive(child, []));
    }
    
    return copiedField;
  };

  // 复制字段
  const copyField = useCallback((fieldId: string) => {
    const field = findField(fields, fieldId);
    if (!field) {
      toast.error('字段不存在');
      return;
    }

    const copiedField = copyFieldRecursive(field);
    
    // 找到字段在列表中的位置
    const findFieldIndex = (fields: FormField[], id: string, parentId?: string, index: number = 0): { parentId?: string; index: number } | null => {
      for (let i = 0; i < fields.length; i++) {
        if (fields[i].id === id) {
          return { parentId, index: i };
        }
        if (fields[i].children && fields[i].children.length > 0) {
          const found = findFieldIndex(fields[i].children!, id, fields[i].id, 0);
          if (found) return found;
        }
      }
      return null;
    };

    const position = findFieldIndex(fields, fieldId);
    if (position) {
      if (position.parentId) {
        // 在容器内
        setFields(prevFields => {
          const newFields = [...prevFields];
          const addToContainer = (fields: FormField[]): FormField[] => {
            return fields.map(f => {
              if (f.id === position.parentId) {
                const newChildren = [...(f.children || [])];
                newChildren.splice(position.index + 1, 0, copiedField);
                return { ...f, children: newChildren };
              }
              if (f.children && f.children.length > 0) {
                return { ...f, children: addToContainer(f.children) };
              }
              return f;
            });
          };
          return addToContainer(newFields);
        });
      } else {
        // 在根级别
        setFields(prevFields => {
          const newFields = [...prevFields];
          newFields.splice(position.index + 1, 0, copiedField);
          return newFields;
        });
      }
      markDirty();
      toast.success('已复制字段');
    }
  }, [fields, markDirty]);

  // 递归添加字段到容器
  const addFieldToContainer = (fields: FormField[], parentId: string, newField: FormField): FormField[] => {
    console.log('addFieldToContainer called:', { parentId, newFieldType: newField.type, newFieldId: newField.id });
    return fields.map(field => {
      if (field.id === parentId) {
        console.log('Found parent field, adding child:', { parentId, childType: newField.type });
        return { ...field, children: [...(field.children || []), newField] };
      }
      if (field.children && field.children.length > 0) {
        return { ...field, children: addFieldToContainer(field.children, parentId, newField) };
      }
      return field;
    });
  };

  // 添加字段
  const addField = (type: FieldType, uploadType?: 'single-image' | 'multiple-image' | 'file', layoutColumns?: number, parentId?: string) => {
    const fieldConfig: Record<FieldType, Partial<FormField>> = {
      input: { placeholder: '请输入' },
      textarea: { placeholder: '请输入内容' },
      password: { placeholder: '请输入密码' },
      select: { 
        placeholder: '请选择',
        options: [{ label: '选项1', value: 'option1' }, { label: '选项2', value: 'option2' }]
      },
      date: { placeholder: '请选择日期' },
      daterange: { placeholder: ['开始日期', '结束日期'] },
      datetime: { placeholder: '请选择日期时间' },
      number: { placeholder: '请输入数字' },
      switch: {},
      radio: { 
        options: [{ label: '选项1', value: 'option1' }, { label: '选项2', value: 'option2' }]
      },
      checkbox: { 
        options: [{ label: '选项1', value: 'option1' }, { label: '选项2', value: 'option2' }]
      },
      upload: { 
        uploadType: uploadType || 'file',
        maxCount: uploadType === 'single-image' ? 1 : uploadType === 'multiple-image' ? 9 : undefined,
        accept: uploadType === 'single-image' || uploadType === 'multiple-image' ? 'image/*' : undefined,
      },
      slider: {},
      rate: {},
      cascader: { 
        cascaderOptions: [
          {
            value: 'zhejiang',
            label: '浙江',
            children: [
              {
                value: 'hangzhou',
                label: '杭州',
                children: [
                  { value: 'xihu', label: '西湖' },
                ],
              },
            ],
          },
          {
            value: 'jiangsu',
            label: '江苏',
            children: [
              {
                value: 'nanjing',
                label: '南京',
                children: [
                  { value: 'zhonghuamen', label: '中华门' },
                ],
              },
            ],
          },
        ],
      },
      treeselect: {},
      timepicker: { placeholder: '请选择时间' },
      card: { 
        children: [],
        cardTitle: '卡片容器'
      },
      grid: { 
        children: [],
        gridColumns: (layoutColumns || 2) as 1 | 2 | 3,
        label: layoutColumns === 3 ? '三栏布局' : '双栏布局'
      },
      tabs: {},
      collapse: {},
      alert: {
        alertTitle: '提示',
        alertDescription: '',
        alertType: 'success',
        alertClosable: true,
        alertShowIcon: true,
        alertCentered: true,
        alertTheme: 'light',
      },
    };

    const newField: FormField = {
      id: `field_${Date.now()}`,
      type,
      label: type === 'grid' ? (layoutColumns === 3 ? '三栏布局' : '双栏布局') : type === 'card' ? '卡片容器' : `字段${fields.length + 1}`,
      name: `field${Date.now()}`,
      required: false,
      ...fieldConfig[type],
    };
    
    // 如果指定了父容器ID，添加到容器中
    if (parentId) {
      console.log('Adding field to container:', { parentId, fieldType: type, fieldId: newField.id, layoutColumns });
      setFields(addFieldToContainer(fields, parentId, newField));
    } else {
      console.log('Adding field to root:', { fieldType: type, fieldId: newField.id, layoutColumns });
      setFields([...fields, newField]);
    }
    setSelectedFieldId(newField.id);
    // 添加字段后，自动切换到组件配置标签页
    setConfigTab('component');
    markDirty();
  };

  // 删除字段（支持递归删除）
  const deleteField = (id: string) => {
    setFields(deleteFieldRecursive(fields, id));
    if (selectedFieldId === id) {
      setSelectedFieldId(null);
    }
    markDirty();
  };

  // 更新字段（支持递归更新）
  const updateField = (id: string, updates: Partial<FormField>) => {
    setFields(updateFieldRecursive(fields, id, updates));
    markDirty();
  };

  // 移动字段（按钮控制的上移下移）
  const moveField = (id: string, direction: 'up' | 'down') => {
    const index = fields.findIndex(f => f.id === id);
    if (index === -1) return;
    
    const newFields = [...fields];
    if (direction === 'up' && index > 0) {
      [newFields[index - 1], newFields[index]] = [newFields[index], newFields[index - 1]];
    } else if (direction === 'down' && index < fields.length - 1) {
      [newFields[index], newFields[index + 1]] = [newFields[index + 1], newFields[index]];
    }
    setFields(newFields);
    markDirty();
  };

  // 查找字段及其父容器
  const findFieldAndParent = (fields: FormField[], fieldId: string, parentId?: string): { field: FormField | null; parent: FormField | null; parentId: string | null; index: number } => {
    for (let i = 0; i < fields.length; i++) {
      if (fields[i].id === fieldId) {
        return { field: fields[i], parent: null, parentId: parentId || null, index: i };
      }
      if (fields[i].children && fields[i].children.length > 0) {
        const result = findFieldAndParent(fields[i].children!, fieldId, fields[i].id);
        if (result.field) {
          return result;
        }
      }
    }
    return { field: null, parent: null, parentId: null, index: -1 };
  };

  // 从字段列表中移除字段（返回新数组，不修改原数组）
  const removeFieldFromList = (fields: FormField[], fieldId: string): FormField[] => {
    return fields.filter(f => {
      if (f.id === fieldId) {
        return false;
      }
      return true;
    }).map(f => {
      if (f.children && f.children.length > 0) {
        return { ...f, children: removeFieldFromList(f.children, fieldId) };
      }
      return f;
    });
  };

  // 在指定位置插入字段
  const insertFieldAtPosition = (fields: FormField[], field: FormField, targetParentId: string | null, targetIndex: number): FormField[] => {
    if (!targetParentId) {
      // 插入到根级别
      const newFields = [...fields];
      newFields.splice(targetIndex, 0, field);
      return newFields;
    }
    
    // 插入到容器中
    return fields.map(f => {
      if (f.id === targetParentId) {
        const newChildren = [...(f.children || [])];
        newChildren.splice(targetIndex, 0, field);
        return { ...f, children: newChildren };
      }
      if (f.children && f.children.length > 0) {
        return { ...f, children: insertFieldAtPosition(f.children, field, targetParentId, targetIndex) };
      }
      return f;
    });
  };

  // 拖拽移动字段到指定位置（支持互换位置）
  const moveFieldToPosition = useCallback((fieldId: string, targetParentId?: string, targetIndex?: number, targetFieldId?: string) => {
    console.log('=== moveFieldToPosition START ===');
    console.log('Parameters:', { fieldId, targetParentId, targetIndex, targetFieldId });
    
    setFields((currentFields) => {
      console.log('Current fields in setState:', currentFields.length, 'field IDs:', currentFields.map(f => f.id));
      
      const { field: sourceField, parentId: sourceParentId, index: sourceIndex } = findFieldAndParent(currentFields, fieldId);
      if (!sourceField) {
        console.log('ERROR: Source field not found:', fieldId);
        return currentFields;
      }
      console.log('Source field found:', { fieldId, sourceParentId, sourceIndex });

      // 如果提供了目标字段ID，进行互换位置
      if (targetFieldId && targetFieldId !== fieldId) {
        const { field: targetField, parentId: targetParentId, index: targetIndex } = findFieldAndParent(currentFields, targetFieldId);
        if (!targetField) {
          console.log('ERROR: Target field not found:', targetFieldId);
          return currentFields;
        }
        console.log('Target field found:', { targetFieldId, targetParentId, targetIndex });

        // 防止拖拽到自己的子元素中（递归检查所有嵌套层级）
        const checkIfDescendant = (parentFieldId: string, checkId: string, allFields: FormField[]): boolean => {
          // 递归查找字段
          const findFieldRecursive = (fields: FormField[], id: string): FormField | null => {
            for (const field of fields) {
              if (field.id === id) return field;
              if (field.children && field.children.length > 0) {
                const found = findFieldRecursive(field.children, id);
                if (found) return found;
              }
            }
            return null;
          };
          
          const parentField = findFieldRecursive(allFields, parentFieldId);
          if (!parentField || !parentField.children) return false;
          if (parentField.children.some(f => f.id === checkId)) return true;
          return parentField.children.some(f => checkIfDescendant(f.id, checkId, allFields));
        };
        
        // 检查是否试图拖拽到自己的子元素中
        if (checkIfDescendant(fieldId, targetFieldId, currentFields)) {
          console.log('ERROR: Cannot drop field into its own descendant');
          return currentFields;
        }

        // 如果两个字段在同一个父容器中，直接交换位置
        if (sourceParentId === targetParentId) {
          // 找到父容器
          if (!sourceParentId) {
            // 根级别，直接交换
            // 验证索引有效性
            if (sourceIndex < 0 || targetIndex < 0 || sourceIndex >= currentFields.length || targetIndex >= currentFields.length) {
              console.error('ERROR: Invalid indices for root swap', { sourceIndex, targetIndex, fieldsLength: currentFields.length });
              return currentFields;
            }
            
            const newFields = [...currentFields];
            const temp = newFields[sourceIndex];
            newFields[sourceIndex] = newFields[targetIndex];
            newFields[targetIndex] = temp;
            
            console.log('=== moveFieldToPosition END (root swap) ===', { 
              sourceIndex, 
              targetIndex, 
              newFieldsLength: newFields.length,
              sourceFieldId: newFields[targetIndex]?.id,
              targetFieldId: newFields[sourceIndex]?.id,
              before: currentFields.map(f => f.id),
              after: newFields.map(f => f.id)
            });
            
            // 返回新数组，确保 React 检测到变化
            return newFields;
          } else {
            // 在容器中，找到容器并交换
            // 验证索引有效性
            const parentField = currentFields.find(f => f.id === sourceParentId);
            if (!parentField || !parentField.children) {
              console.error('ERROR: Parent field not found or has no children', { sourceParentId });
              return currentFields;
            }
            
            if (sourceIndex < 0 || targetIndex < 0 || sourceIndex >= parentField.children.length || targetIndex >= parentField.children.length) {
              console.error('ERROR: Invalid indices for container swap', { sourceIndex, targetIndex, childrenLength: parentField.children.length });
              return currentFields;
            }
            
            return currentFields.map(f => {
              if (f.id === sourceParentId && f.children) {
                const newChildren = [...f.children];
                const temp = newChildren[sourceIndex];
                newChildren[sourceIndex] = newChildren[targetIndex];
                newChildren[targetIndex] = temp;
                
                console.log('=== moveFieldToPosition END (container swap) ===', { 
                  sourceIndex, 
                  targetIndex, 
                  childrenLength: newChildren.length,
                  sourceFieldId: newChildren[targetIndex]?.id,
                  targetFieldId: newChildren[sourceIndex]?.id,
                  before: f.children.map(c => c.id),
                  after: newChildren.map(c => c.id)
                });
                
                // 返回新对象和数组，确保 React 检测到变化
                return { ...f, children: newChildren };
              }
              return f;
            });
          }
        } else {
          // 不同父容器，需要真正的互换：先记录原始位置，移除两个字段，然后互换位置插入
          // 先记录原始位置（在移除前）
          const originalSourceIndex = sourceIndex;
          const originalSourceParentId = sourceParentId;
          const originalTargetIndex = targetIndex;
          const originalTargetParentId = targetParentId;
          
          // 先移除源字段和目标字段
          let newFields = removeFieldFromList(currentFields, fieldId);
          newFields = removeFieldFromList(newFields, targetFieldId);
          
          // 计算调整后的索引（因为移除了字段，索引会变化）
          let adjustedTargetIndex = originalTargetIndex;
          let adjustedSourceIndex = originalSourceIndex;
          
          // 如果两个字段在同一个父容器中（虽然这种情况应该不会发生，因为我们已经检查了 sourceParentId !== targetParentId）
          // 但为了安全，还是处理一下
          if (originalSourceParentId === originalTargetParentId) {
            // 如果目标字段在源字段之后，移除源字段后目标索引需要减1
            if (originalSourceIndex < originalTargetIndex) {
              adjustedTargetIndex = originalTargetIndex - 1;
            }
            // 如果源字段在目标字段之后，移除目标字段后源索引需要减1
            if (originalTargetIndex < originalSourceIndex) {
              adjustedSourceIndex = originalSourceIndex - 1;
            }
          }
          
          // 先插入源字段到目标位置
          newFields = insertFieldAtPosition(newFields, sourceField, originalTargetParentId || null, adjustedTargetIndex);
          // 再插入目标字段到源位置
          newFields = insertFieldAtPosition(newFields, targetField, originalSourceParentId || null, adjustedSourceIndex);
          
          console.log('=== moveFieldToPosition END (cross-parent swap) ===', {
            sourceFieldId: sourceField.id,
            targetFieldId: targetField.id,
            originalSourceParentId,
            originalTargetParentId,
            adjustedSourceIndex,
            adjustedTargetIndex,
            newFieldsLength: newFields.length
          });
          // 确保返回新数组引用
          return newFields;
        }
      }

      // 如果没有提供目标字段ID，使用原来的插入逻辑
      const targetParent = targetParentId || null;
      let adjustedTargetIndex = targetIndex;
      if (sourceParentId === targetParent && targetIndex !== undefined) {
        if (sourceIndex === targetIndex) {
          console.log('Same position, skipping');
          return currentFields;
        }
        if (sourceIndex < targetIndex) {
          adjustedTargetIndex = targetIndex - 1;
        }
      }

      let newFields = removeFieldFromList(currentFields, fieldId);
      
      let finalTargetIndex: number;
      if (adjustedTargetIndex !== undefined && adjustedTargetIndex >= 0) {
        finalTargetIndex = adjustedTargetIndex;
      } else {
        if (targetParentId) {
          const targetParentField = newFields.find((f: FormField) => f.id === targetParentId);
          finalTargetIndex = targetParentField?.children?.length || 0;
        } else {
          finalTargetIndex = newFields.length;
        }
      }

      newFields = insertFieldAtPosition(newFields, sourceField, targetParent, finalTargetIndex);
      
      console.log('=== moveFieldToPosition END (insert) ===');
      return newFields;
    });
    
    markDirty();
  }, [markDirty]);

  // 点击保存 - 先弹出“保存表单”弹框（只校验是否有字段）
  const handleSave = () => {
    if (fields.length === 0) {
      message.error('请至少添加一个字段');
      return;
    }

    setSaveModalVisible(true);
  };

  // 确认保存，真正调用接口
  const doSave = async () => {
    // 在这里再统一校验表单名称
    // 优先使用 formName（保存弹窗中的名称），如果没有则使用 formConfig.name
    const finalName = (formName || formConfig.name || '').trim();
    if (!finalName) {
      message.error('请输入表单名称');
      return;
    }
    // 同步更新 formName 和 formConfig.name
    if (finalName !== formName) {
      setFormName(finalName);
    }
    if (finalName !== formConfig.name) {
      setFormConfig({ ...formConfig, name: finalName });
    }

    setSaving(true);
    try {
      const formData: FormApi.FormVO = {
        name: finalName,
        remark: formRemark,
        // conf 只存储表单配置；字段列表单独放入 fields
        conf: JSON.stringify({ formConfig }),
        // 后端要求 string[]，每个字段单独序列化
        fields: fields.map(field => JSON.stringify(field)),
        status: formStatus,
      };

      if (formType === 'create' || formType === 'copy') {
        await FormApi.createForm(formData);
        toast.success('创建成功');
      } else if (formType === 'update' && formId) {
        formData.id = Number(formId);
        await FormApi.updateForm(formData);
        toast.success('更新成功');
      }
      setHasUnsavedChanges(false);

      // 保存成功后返回表单列表页
      backToFormManagementMenu();
    } catch (error: any) {
      toast.error(error.message || '保存失败');
    } finally {
      setSaveModalVisible(false);
      setSaving(false);
    }
  };
  // 清空表单
  const handleClear = () => {
    Modal.confirm({
      title: '确认清空',
      content: '确定要清空所有字段吗？此操作不可撤销。',
      okText: '确定',
      cancelText: '取消',
      okType: 'danger',
      onOk: () => {
        setFields([]);
        setSelectedFieldId(null);
        toast.success('已清空所有字段');
        markDirty();
      },
    });
  };
  // 使用递归查找函数来支持嵌套字段的查找
  const selectedField = selectedFieldId ? findField(fields, selectedFieldId) : null;
  const selectedIndex = selectedFieldId ? fields.findIndex(f => f.id === selectedFieldId) : -1;

  // 使用 useMemo 确保 backend 实例在组件生命周期内保持一致
  const backend = useMemo(() => getHTML5Backend(), []);
  const layoutColumns = formConfig.layoutColumns || 1;
  const cardEnabled = formConfig.useCardLayout !== false;
  const gridStyle = layoutColumns > 1 ? {
    display: 'grid', 
    gridTemplateColumns: `repeat(${layoutColumns}, minmax(0, 1fr))`
  } : undefined;

  // 使用 useCallback 稳定 onDragEnd 函数引用，避免无限循环
  const handleDragEnd = useCallback(() => {
    setDragPreview({ show: false });
  }, []);

  // 渲染预览字段的函数
  const renderPreviewField = (field: FormField, formConfig: FormConfig, layoutColumns: number) => {
    const baseProps = {
      disabled: field.disabled,
      size: field.size || 'middle',
    };

    const renderFieldComponent = () => {
      switch (field.type) {
        case 'input':
          return (
            <Input 
              {...baseProps} 
              type={field.inputType || 'text'}
              placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
              allowClear={field.showClear}
              maxLength={field.maxLength}
              readOnly={field.readOnly}
            />
          );
        case 'textarea':
          return (
            <TextArea 
              {...baseProps} 
              rows={4} 
              placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
              allowClear={field.showClear}
              maxLength={field.maxLength}
              readOnly={field.readOnly}
            />
          );
        case 'password':
          return (
            <Input.Password 
              {...baseProps} 
              placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
              allowClear={field.showClear}
              maxLength={field.maxLength}
              readOnly={field.readOnly}
            />
          );
        case 'select':
          return (
            <Select 
              {...baseProps} 
              placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
              allowClear={field.showClear}
            >
              {field.options?.map((opt, idx) => (
                <Select.Option key={idx} value={opt.value}>{opt.label}</Select.Option>
              ))}
            </Select>
          );
        case 'date':
          return (
            <DatePicker 
              {...baseProps} 
              className="w-full" 
              placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
              allowClear={field.showClear}
            />
          );
        case 'daterange':
          return (
            <DatePicker.RangePicker 
              placeholder={Array.isArray(field.placeholder) ? field.placeholder as [string, string] : ['开始日期', '结束日期']}
              disabled={field.disabled}
              size={field.size || 'middle'}
              className="w-full"
              allowClear={field.showClear}
            />
          );
        case 'datetime':
          return (
            <DatePicker 
              {...baseProps} 
              className="w-full" 
              placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
              allowClear={field.showClear}
              showTime={{ format: 'HH:mm:ss' }}
              format="YYYY-MM-DD HH:mm:ss"
            />
          );
        case 'timepicker':
          return (
            <TimePicker 
              {...baseProps} 
              className="w-full" 
              placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
              allowClear={field.showClear}
              format="HH:mm:ss"
            />
          );
        case 'number':
          return (
            <InputNumber 
              {...baseProps} 
              className="w-full" 
              placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
              max={field.maxLength}
              readOnly={field.readOnly}
            />
          );
        case 'switch':
          return <Switch disabled={field.disabled} />;
        case 'radio':
          return (
            <Radio.Group disabled={field.disabled}>
              {field.options?.map((opt, idx) => (
                <Radio key={idx} value={opt.value}>{opt.label}</Radio>
              ))}
            </Radio.Group>
          );
        case 'checkbox':
          return (
            <Checkbox.Group disabled={field.disabled}>
              {field.options?.map((opt, idx) => (
                <Checkbox key={idx} value={opt.value}>{opt.label}</Checkbox>
              ))}
            </Checkbox.Group>
          );
        case 'cascader':
          return (
            <Cascader
              {...baseProps}
              placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}
              options={field.cascaderOptions || []}
              className="w-full"
              allowClear={field.showClear}
            />
          );
        case 'upload':
          return (
            <FormUploadField
              uploadType={field.uploadType}
              maxCount={field.maxCount}
              accept={field.accept}
              disabled={field.disabled}
            />
          );
        case 'alert':
          const themeClass =
            field.alertTheme === 'dark'
              ? 'bg-gray-800 text-white border-gray-700'
              : '';
          return (
            <Alert
              message={field.alertTitle || field.label}
              description={field.alertDescription}
              type={field.alertType || 'info'}
              showIcon={field.alertShowIcon !== false}
              closable={field.alertClosable}
              closeText={field.alertCloseText}
              className={`${field.alertCentered ? 'text-center' : ''} ${themeClass}`}
              banner
              style={field.style}
            />
          );
        default:
          return <Input {...baseProps} placeholder={typeof field.placeholder === 'string' ? field.placeholder : undefined} />;
      }
    };

    // 处理 alert 类型，不需要 Form.Item
    if (field.type === 'alert') {
      return renderFieldComponent();
    }

    // 构建验证规则
    const rules: any[] = [];
    if (field.required) {
      rules.push({
        required: true,
        message: field.requiredMessage || getDefaultRequiredMessage(field),
        trigger: 'blur'
      });
    }

    // 其他验证规则
    field.validationRules?.forEach(rule => {
      if (rule.type === 'min') {
        if (field.type === 'number') {
          rules.push({
            type: 'number',
            min: rule.value,
            message: rule.message || `值不能小于${rule.value}`,
            trigger: rule.trigger || 'blur'
          });
        } else {
          rules.push({
            validator: (_: any, value: any) => {
              if (!value) return Promise.resolve();
              const numValue = Number(value);
              if (isNaN(numValue)) {
                return Promise.reject(rule.message || `值不能小于${rule.value}`);
              }
              if (numValue < (rule.value as number)) {
                return Promise.reject(rule.message || `值不能小于${rule.value}`);
              }
              return Promise.resolve();
            },
            trigger: rule.trigger || 'blur'
          });
        }
      } else if (rule.type === 'max') {
        if (field.type === 'number') {
          rules.push({
            type: 'number',
            max: rule.value,
            message: rule.message || `值不能大于${rule.value}`,
            trigger: rule.trigger || 'blur'
          });
        } else {
          rules.push({
            validator: (_: any, value: any) => {
              if (!value) return Promise.resolve();
              const numValue = Number(value);
              if (isNaN(numValue)) {
                return Promise.reject(rule.message || `值不能大于${rule.value}`);
              }
              if (numValue > (rule.value as number)) {
                return Promise.reject(rule.message || `值不能大于${rule.value}`);
              }
              return Promise.resolve();
            },
            trigger: rule.trigger || 'blur'
          });
        }
      } else if (rule.type === 'len') {
        rules.push({
          len: rule.value,
          message: rule.message || `长度必须为${rule.value}`,
          trigger: rule.trigger || 'blur'
        });
      } else if (rule.type === 'pattern') {
        try {
          const pattern = new RegExp(rule.value as string);
          rules.push({
            pattern,
            message: rule.message || '格式不正确',
            trigger: rule.trigger || 'blur'
          });
        } catch (e) {
          console.error('正则表达式错误:', e);
        }
      } else if (rule.type === 'validator') {
        rules.push({
          validator: (_: any, value: any) => {
            if (rule.validator) {
              try {
                const fn = new Function('value', 'rule', rule.validator);
                const result = fn(value, rule);
                if (result === false || (result instanceof Error)) {
                  return Promise.reject(rule.message || '验证失败');
                }
                return Promise.resolve();
              } catch (e) {
                console.error('自定义验证函数错误:', e);
                return Promise.reject(rule.message || '验证失败');
              }
            }
            return Promise.resolve();
          },
          trigger: rule.trigger || 'blur'
        });
      }
    });

    // 预览与设计器一致：每个字段使用 field.labelWidth ?? formConfig.labelWidth ?? 100，保证长标签不堆叠
    const rawLabelWidth = field.labelWidth ?? formConfig?.labelWidth ?? 100;
    const effectiveLabelWidth = (typeof rawLabelWidth === 'number' && rawLabelWidth > 0) ? rawLabelWidth : 100;
    const isTopLabel = formConfig?.labelPosition === 'top';
    const previewLabelCol = isTopLabel
      ? undefined
      : {
          flex: `${effectiveLabelWidth}px`,
          style: {
            minWidth: `${effectiveLabelWidth}px`,
            textAlign: formConfig?.labelPosition === 'right' ? 'right' : 'left',
          },
        };
    const previewWrapperCol = isTopLabel ? undefined : { flex: 'auto', style: { minWidth: 0 } };

    return (
      <AntdForm.Item
        label={field.label + (formConfig?.labelSuffix || '')}
        required={field.required && !formConfig?.hideRequiredMark}
        rules={rules}
        name={field.id}
        labelCol={previewLabelCol}
        wrapperCol={previewWrapperCol}
      >
        {renderFieldComponent()}
        {field.hint && (
          <div className="text-xs text-gray-400 mt-1">{field.hint}</div>
        )}
      </AntdForm.Item>
    );
  };

  return (
    <DndProvider backend={backend}>
      <CustomDragLayer onDragEnd={handleDragEnd} />
      <div className="h-screen flex flex-col bg-gray-50">
        {/* 顶部工具栏 */}
 
           <div className="bg-white border-b border-gray-200 px-6 py-3 flex items-center gap-4 shadow-sm">
          <Button
            icon={<ArrowLeft className="w-4 h-4" />}
            onClick={handleBack}
          >
            返回
          </Button>
          <Divider type="vertical" />
          <Button type="primary" ghost icon={<Eye className="w-4 h-4" />} onClick={() => setPreviewVisible(true)}>
            预览
          </Button>
          <Button type="primary" ghost icon={<Code className="w-4 h-4" />} onClick={() => setCodeVisible(true)}>
            代码
          </Button>
          <Button 
            type="primary" 
            icon={<Save className="w-4 h-4" />} 
            onClick={handleSave} 
            loading={saving}
          >
            保存
          </Button>
          <Button 
            danger
            icon={<Trash2 className="w-4 h-4" />} 
            onClick={handleClear}
          >
            清空
          </Button>
        </div>

        <div className="flex-1 flex overflow-hidden" style={{ height: 'calc(100vh - 64px)' }}>
          {/* 左侧：组件库 */}
          <div className="w-80 bg-white border-r border-gray-200 overflow-y-auto">
            <div className="p-4 border-b border-gray-200">
              <h3 className="text-sm font-semibold text-gray-700">基础组件</h3>
            </div>
            <div className="p-4">
              {Object.entries(componentLibrary).map(([category, components]) => (
                <div key={category} className="mb-4">
                  <div className="text-xs font-medium text-gray-500 mb-3 px-1">{category}</div>
                  <div className="grid grid-cols-3 gap-2">
                    {components.map((comp, idx) => (
                      <DraggableComponent
                        key={`${comp.type}-${comp.label}-${idx}`}
                        type={comp.type}
                        label={comp.label}
                        icon={comp.icon}
                        uploadType={comp.uploadType}
                        layoutColumns={comp.layoutColumns}
                        onDrag={addField}
                      />
                    ))}
                  </div>
                </div>
              ))}
            </div>
          </div>

          {/* 中间：设计画布 */}
          <div className="flex-1 overflow-hidden">
            <CanvasDropZone 
              onDrop={(type, uploadType, layoutCols, parentId) => {
                console.log('Main canvas onDrop:', { type, uploadType, layoutCols, parentId });
                addField(type, uploadType, layoutCols, parentId);
              }}
              onMoveField={moveFieldToPosition}
              style={{ height: '100%', display: 'flex', flexDirection: 'column' }}
            >
              <div className="w-full p-8" style={{ minHeight: '100%', overflow: 'auto' }}>
                {formConfig.useCardLayout !== false ? (
                  <Card 
                    title={formConfig.name || "表单设计"} 
                    className="flex flex-col flex-1"
                    style={{ height: '100%', display: 'flex', flexDirection: 'column' }}
                    bodyStyle={{ flex: 1, overflow: 'auto', height: 0 }}
                  >
                  {fields.length === 0 ? (
                    <div className="pt-8 w-full text-center">
                      <p className="text-sm text-gray-400">从左侧拖拽组件到此处开始设计</p>
                    </div>
                  ) : (
                      <AntdForm
                        layout={formConfig.labelPosition === 'top' ? 'vertical' : formConfig.labelPosition === 'left' ? 'horizontal' : 'horizontal'}
                        size={formConfig.formSize === 'default' ? 'middle' : formConfig.formSize}
                        requiredMark={formConfig.hideRequiredMark ? false : undefined}
                        labelCol={
                          formConfig.labelPosition === 'top' || !formConfig.labelWidth
                            ? undefined
                            : {
                                flex: `${formConfig.labelWidth}px`,
                                style: {
                                  minWidth: `${formConfig.labelWidth}px`,
                                  textAlign: formConfig.labelPosition === 'right' ? 'right' : 'left',
                                },
                              }
                        }
                        wrapperCol={formConfig.labelPosition === 'top' ? undefined : { flex: 'auto' }}
                      >
                        <div style={gridStyle} className={layoutColumns === 1 ? 'space-y-4' : ''}>
                          {fields.map((field, index) => (
                            <div
                              key={field.id}
                              style={
                                layoutColumns > 1
                                  ? { 
                                      gridColumn: `span ${Math.min(layoutColumns, field.span || 1)}`,
                                      position: 'relative',
                                      minHeight: '80px'
                                    }
                                  : { position: 'relative', minHeight: '80px' }
                              }
                            >
                              <CanvasDropZone
                                onDrop={(type, uploadType, layoutCols) => {
                                  addField(type, uploadType, layoutCols);
                                }}
                                onMoveField={moveFieldToPosition}
                                onHover={(item, monitor) => {
                                  if (monitor.getItemType() === 'field') {
                                    // 拖拽到组件上时，设置悬停目标用于视觉反馈
                                    setHoverTargetId(field.id);
                                  }
                                }}
                                onHoverTarget={(targetFieldId) => {
                                  // 设置悬停目标，用于显示视觉反馈
                                  setHoverTargetId(targetFieldId);
                                }}
                                fieldIndex={index}
                                fieldId={field.id}
                                className="w-full h-full"
                                style={{ width: '100%', height: '100%', minHeight: '80px' }}
                              >
                                <FieldRenderer
                                  field={field}
                                  isSelected={selectedFieldId === field.id}
                                  onSelect={() => setSelectedFieldId(field.id)}
                                  onDelete={() => deleteField(field.id)}
                                  onAddFieldToContainer={(parentId, type, uploadType, layoutCols) => {
                                    addField(type, uploadType, layoutCols, parentId);
                                  }}
                                  onMoveField={moveFieldToPosition}
                                  onUpdateField={updateField}
                                  onDeleteField={deleteField}
                                  onSelectField={setSelectedFieldId}
                                  onCopyField={copyField}
                                  formConfig={formConfig}
                                  selectedFieldId={selectedFieldId}
                                  allFields={fields}
                                  draggingFieldId={draggingFieldId}
                                  hoverTargetId={hoverTargetId}
                                  onDragStart={(fieldId) => setDraggingFieldId(fieldId)}
                                  onDragEnd={() => {
                                    setDraggingFieldId(null);
                                    setHoverTargetId(null);
                                  }}
                                  onHoverTarget={(fieldId) => setHoverTargetId(fieldId)}
                                />
                              </CanvasDropZone>
                            </div>
                          ))}
                        </div>
                      </AntdForm>
                    )}
                  </Card>
                ) : (
                  <div className="flex-1 flex flex-col" style={{ height: '100%', overflow: 'auto' }}>
                    {fields.length === 0 ? (
                      <div className="pt-8 w-full text-center">
                        <p className="text-sm text-gray-400">从左侧拖拽组件到此处开始设计</p>
                      </div>
                    ) : (
                      <AntdForm
                        layout={formConfig.labelPosition === 'top' ? 'vertical' : formConfig.labelPosition === 'left' ? 'horizontal' : 'horizontal'}
                        size={formConfig.formSize === 'default' ? 'middle' : formConfig.formSize}
                        requiredMark={formConfig.hideRequiredMark ? false : undefined}
                        labelCol={
                          formConfig.labelPosition === 'top' || !formConfig.labelWidth
                            ? undefined
                            : {
                                flex: `${formConfig.labelWidth}px`,
                                style: {
                                  minWidth: `${formConfig.labelWidth}px`,
                                  textAlign: formConfig.labelPosition === 'right' ? 'right' : 'left',
                                },
                              }
                        }
                        wrapperCol={formConfig.labelPosition === 'top' ? undefined : { flex: 'auto' }}
                      >
                        <CanvasDropZone
                          onDrop={(type, uploadType, layoutCols) => {
                            addField(type, uploadType, layoutCols);
                            setDragPreview({ show: false });
                          }}
                          onMoveField={moveFieldToPosition}
                          onHover={(item, monitor) => {
                            if (monitor.getItemType() === 'field') {
                              setDragPreview({ 
                                targetParentId: undefined, 
                                targetIndex: fields.length,
                                show: true 
                              });
                            }
                          }}
                          className="min-h-[200px] p-2"
                        >
                          <div style={gridStyle} className={layoutColumns === 1 ? 'space-y-4' : 'gap-4'}>
                            {fields.map((field, index) => (
                              <React.Fragment key={field.id}>
                                <div
                                  style={
                                    layoutColumns > 1
                                      ? { 
                                          gridColumn: `span ${Math.min(layoutColumns, field.span || 1)}`,
                                          position: 'relative',
                                          minHeight: '80px'
                                        }
                                      : { position: 'relative', minHeight: '80px' }
                                  }
                                >
                                  <CanvasDropZone
                                    onDrop={(type, uploadType, layoutCols) => {
                                      addField(type, uploadType, layoutCols);
                                      setDragPreview({ show: false });
                                    }}
                                    onMoveField={moveFieldToPosition}
                                    onHover={(item, monitor) => {
                                      if (monitor.getItemType() === 'field') {
                                        // 拖拽到组件上时，设置悬停目标用于视觉反馈
                                        setHoverTargetId(field.id);
                                      }
                                    }}
                                    onHoverTarget={(targetFieldId) => {
                                      // 设置悬停目标，用于显示视觉反馈
                                      setHoverTargetId(targetFieldId);
                                    }}
                                    fieldIndex={index}
                                    fieldId={field.id}
                                    className="w-full h-full"
                                    style={{ width: '100%', height: '100%', minHeight: '80px' }}
                                  >
                                    <FieldRenderer
                                      field={field}
                                      isSelected={selectedFieldId === field.id}
                                      onSelect={() => setSelectedFieldId(field.id)}
                                      onDelete={() => deleteField(field.id)}
                                      formConfig={formConfig}
                                      onAddFieldToContainer={(parentId, type, uploadType, layoutCols) => {
                                        addField(type, uploadType, layoutCols, parentId);
                                      }}
                                      onMoveField={moveFieldToPosition}
                                      onUpdateField={updateField}
                                      onDeleteField={deleteField}
                                      onSelectField={setSelectedFieldId}
                                      selectedFieldId={selectedFieldId}
                                      allFields={fields}
                                      dragPreview={dragPreview}
                                      setDragPreview={setDragPreview}
                                    />
                                  </CanvasDropZone>
                                </div>
                              </React.Fragment>
                            ))}
                          </div>
                        </CanvasDropZone>
                      </AntdForm>
                    )}
                  </div>
                )}
              </div>
            </CanvasDropZone>
          </div>

          {/* 右侧：属性配置面板 */}
          <div className="w-80 bg-white border-l border-gray-200 overflow-y-auto flex flex-col">
            <Tabs
              activeKey={configTab}
              centered={true}
              size="large"
              tabBarGutter={85}
              onChange={(key) => setConfigTab(key as 'form' | 'component')}
              items={[
                {
                  key: 'form',
                  label: '表单配置',
                  children: (
                    <div className="flex-1 overflow-y-auto p-4 space-y-4">
                <div>
                  <label className="text-xs text-gray-600 mb-1 block">表单名称</label>
                  <Input
                    value={formConfig.name}
                    onChange={(e) => updateFormConfig({ name: e.target.value })}
                    size="small"
                    placeholder="请输入表单名称"
                  />
                </div>
                <div>
                  <label className="text-xs text-gray-600 mb-1 block">标签的位置</label>
                  <Radio.Group
                    value={formConfig.labelPosition}
                    onChange={(e) => updateFormConfig({ labelPosition: e.target.value })}
                    size="small"
                  >
                    <Radio value="left">左对齐</Radio>
                    <Radio value="right">右对齐</Radio>
                    <Radio value="top">顶部</Radio>
                  </Radio.Group>
                </div>
                <div>
                  <label className="text-xs text-gray-600 mb-1 block">表单的尺寸</label>
                  <Radio.Group
                    value={formConfig.formSize}
                    onChange={(e) => updateFormConfig({ formSize: e.target.value })}
                    size="small"
                  >
                    <Radio value="large">大</Radio>
                    <Radio value="default">默认</Radio>
                    <Radio value="small">小</Radio>
                  </Radio.Group>
                </div>
                <div>
                  <label className="text-xs text-gray-600 mb-1 block">标签的后缀</label>
                  <Input
                    value={formConfig.labelSuffix}
                    onChange={(e) => updateFormConfig({ labelSuffix: e.target.value })}
                    size="small"
                    placeholder="例如：:"
                  />
                </div>
                <div>
                  <label className="text-xs text-gray-600 mb-1 block">标签的宽度</label>
                  <InputNumber
                    value={formConfig.labelWidth}
                    onChange={(value) => updateFormConfig({ labelWidth: value || 100 })}
                    size="small"
                    className="w-full"
                    min={0}
                    addonAfter="px"
                  />
                </div>
                <div>
                  <label className="text-xs text-gray-600 mb-1 block">表单布局</label>
                  <Radio.Group
                    value={layoutColumns}
                    onChange={(e) => updateFormConfig({ layoutColumns: e.target.value as 1 | 2 | 3 })}
                    size="small"
                  >
                    <Radio value={1}>单栏</Radio>
                    <Radio value={2}>双栏</Radio>
                    {/* 三栏选项暂时隐藏 */}
                    {/* <Radio value={3}>三栏</Radio> */}
                  </Radio.Group>
                </div>
                <div className="flex items-center justify-between">
                  <label className="text-xs text-gray-600">使用卡片容器</label>
                  <Switch
                    checked={formConfig.useCardLayout !== false}
                    onChange={(checked) => updateFormConfig({ useCardLayout: checked })}
                    size="small"
                  />
                </div>
                <Divider className="my-2" />
                <div className="space-y-3">
                  <div className="flex items-center justify-between">
                    <label className="text-xs text-gray-600">隐藏必填字段的标签旁边的红色星号</label>
                    <Switch
                      checked={formConfig.hideRequiredMark}
                      onChange={(checked) => updateFormConfig({ hideRequiredMark: checked })}
                      size="small"
                    />
                  </div>
                  <div className="flex items-center justify-between">
                    <label className="text-xs text-gray-600">显示校验错误信息</label>
                    <Switch
                      checked={formConfig.showValidationError}
                      onChange={(checked) => updateFormConfig({ showValidationError: checked })}
                      size="small"
                    />
                  </div>
                  <div className="flex items-center justify-between">
                    <label className="text-xs text-gray-600">以行内形式展示校验信息</label>
                    <Switch
                      checked={formConfig.inlineValidation}
                      onChange={(checked) => updateFormConfig({ inlineValidation: checked })}
                      size="small"
                    />
                  </div>
                  <div className="flex items-center justify-between">
                    <label className="text-xs text-gray-600">是否显示表单提交按钮</label>
                    <Switch
                      checked={formConfig.showSubmitButton}
                      onChange={(checked) => updateFormConfig({ showSubmitButton: checked })}
                      size="small"
                    />
                  </div>
                  <div className="flex items-center justify-between">
                    <label className="text-xs text-gray-600">是否显示表单重置按钮</label>
                    <Switch
                      checked={formConfig.showResetButton}
                      onChange={(checked) => updateFormConfig({ showResetButton: checked })}
                      size="small"
                    />
                  </div>
                </div>
                <Divider className="my-2" />
                <div>
                  <label className="text-xs font-semibold text-gray-700 mb-2 block">表单事件</label>
                  <Button
                    type="primary"
                    size="small"
                    block
                    onClick={() => {
                      toast.info('事件配置功能开发中');
                    }}
                  >
                    设置事件
                  </Button>
                </div>
                    </div>
                  ),
                },
                ...(fields.length > 0
                  ? [
                      {
                        key: 'component',
                        label: '组件配置',
                        children: selectedField ? (() => {
              const field = selectedField; // 创建局部变量确保类型安全
              return (
                <div className="flex-1 overflow-y-auto">
              <div className="p-4 space-y-4">
                    {/* 组件类型 */}
                <div>
                      <label className="text-xs text-gray-600 mb-1 block">组件类型</label>
                      <Select
                        value={field.type}
                        size="small"
                        className="w-full"
                        disabled
                      >
                        <Select.Option value={field.type}>
                          {componentLibrary['输入控件'].find(c => c.type === field.type)?.label || field.type}
                        </Select.Option>
                      </Select>
                    </div>

                    {/* 编号 */}
                    <div>
                      <label className="text-xs text-gray-600 mb-1 block">编号</label>
                      <div className="flex gap-2">
                  <Input
                          value={field.id}
                    size="small"
                          readOnly
                          className="flex-1"
                        />
                        <Button
                          size="small"
                          icon={<Plus className="w-3 h-3" />}
                          onClick={() => {
                            navigator.clipboard.writeText(field.id);
                            toast.success('已复制编号');
                          }}
                        />
                      </div>
                    </div>

                    <Divider className="my-2" />

                    {/* 基础配置 */}
                    <div>
                      <label className="text-xs font-semibold text-gray-700 mb-2 block">基础配置</label>
                      <div className="space-y-3">
                        <div>
                          <label className="text-xs text-gray-600 mb-1 block">字段ID</label>
                          <div className="flex gap-2">
                            <Input
                              value={field.fieldId || field.id}
                              onChange={(e) => updateField(field.id, { fieldId: e.target.value })}
                              size="small"
                              className="flex-1"
                            />
                            <Button
                              size="small"
                              icon={<Plus className="w-3 h-3" />}
                              onClick={() => {
                                navigator.clipboard.writeText(field.fieldId || field.id);
                                toast.success('已复制字段ID');
                              }}
                            />
                          </div>
                </div>
                <div>
                  <label className="text-xs text-gray-600 mb-1 block">字段名称</label>
                  <Input
                            value={field.label}
                            onChange={(e) => updateField(field.id, { label: e.target.value })}
                    size="small"
                  />
                </div>
                <div>
                          <label className="text-xs text-gray-600 mb-1 block">提示信息</label>
                  <Input
                            value={field.hint || ''}
                            onChange={(e) => updateField(field.id, { hint: e.target.value })}
                    size="small"
                            placeholder="请输入提示信息"
                  />
                </div>
                        {field.type === 'alert' && (
                          <>
                            <div>
                              <label className="text-xs text-gray-600 mb-1 block">提示内容</label>
                              <Input
                                value={field.alertTitle || ''}
                                onChange={(e) => updateField(field.id, { alertTitle: e.target.value })}
                                size="small"
                                placeholder="提示"
                              />
                            </div>
                            <div>
                              <label className="text-xs text-gray-600 mb-1 block">辅助性文字</label>
                              <Input
                                value={field.alertDescription || ''}
                                onChange={(e) => updateField(field.id, { alertDescription: e.target.value })}
                                size="small"
                                placeholder="说明文字"
                              />
                            </div>
                            <div>
                              <label className="text-xs text-gray-600 mb-1 block">主题</label>
                              <Select
                                value={field.alertType || 'success'}
                                onChange={(value) => updateField(field.id, { alertType: value })}
                                size="small"
                                className="w-full"
                              >
                                <Select.Option value="success">success</Select.Option>
                                <Select.Option value="info">info</Select.Option>
                                <Select.Option value="warning">warning</Select.Option>
                                <Select.Option value="error">error</Select.Option>
                              </Select>
                            </div>
                            <div className="flex items-center justify-between">
                              <label className="text-xs text-gray-600">是否可关闭</label>
                              <Switch
                                checked={field.alertClosable !== false}
                                onChange={(checked) => updateField(field.id, { alertClosable: checked })}
                                size="small"
                              />
                            </div>
                            <div className="flex items-center justify-between">
                              <label className="text-xs text-gray-600">文字是否居中</label>
                              <Switch
                                checked={!!field.alertCentered}
                                onChange={(checked) => updateField(field.id, { alertCentered: checked })}
                                size="small"
                              />
                            </div>
                            <div>
                              <label className="text-xs text-gray-600 mb-1 block">关闭按钮自定义文本</label>
                              <Input
                                value={field.alertCloseText || ''}
                                onChange={(e) => updateField(field.id, { alertCloseText: e.target.value })}
                                size="small"
                                placeholder="例如：知道了"
                              />
                            </div>
                            <div className="flex items-center justify-between">
                              <label className="text-xs text-gray-600">是否显示图标</label>
                              <Switch
                                checked={field.alertShowIcon !== false}
                                onChange={(checked) => updateField(field.id, { alertShowIcon: checked })}
                                size="small"
                              />
                            </div>
                            <div>
                              <label className="text-xs text-gray-600 mb-1 block">主题风格</label>
                              <Select
                                value={field.alertTheme || 'light'}
                                onChange={(value) => updateField(field.id, { alertTheme: value })}
                                size="small"
                                className="w-full"
                              >
                                <Select.Option value="light">light</Select.Option>
                                <Select.Option value="dark">dark</Select.Option>
                              </Select>
                            </div>
                          </>
                        )}
                        <div>
                          <label className="text-xs text-gray-600 mb-1 block">标签的宽度</label>
                          <InputNumber
                            value={field.labelWidth || formConfig.labelWidth}
                            onChange={(value) => updateField(field.id, { labelWidth: value || undefined })}
                            size="small"
                            className="w-full"
                            min={0}
                            addonAfter="px"
                          />
                        </div>
                      </div>
                    </div>

                    <Divider className="my-2" />

                    {/* 属性配置 */}
                    <div>
                      <label className="text-xs font-semibold text-gray-700 mb-2 block">属性配置</label>
                      <div className="space-y-3">
                <div className="flex items-center justify-between">
                          <label className="text-xs text-gray-600">是否禁用</label>
                  <Switch
                            checked={field.disabled}
                            onChange={(checked) => updateField(field.id, { disabled: checked })}
                    size="small"
                  />
                </div>
                <div className="flex items-center justify-between">
                          <label className="text-xs text-gray-600">是否只读</label>
                  <Switch
                            checked={field.readOnly}
                            onChange={(checked) => updateField(field.id, { readOnly: checked })}
                            size="small"
                          />
                        </div>
                        {(field.type === 'input' || field.type === 'textarea' || field.type === 'password') && (
                          <>
                            {field.type === 'input' && (
                              <div>
                                <label className="text-xs text-gray-600 mb-1 block">类型</label>
                                <Select
                                  value={field.inputType || 'text'}
                                  onChange={(value) => updateField(field.id, { inputType: value })}
                                  size="small"
                                  className="w-full"
                                >
                                  <Select.Option value="text">文本</Select.Option>
                                  <Select.Option value="password">密码</Select.Option>
                                  <Select.Option value="number">数字</Select.Option>
                                  <Select.Option value="email">邮箱</Select.Option>
                                  <Select.Option value="url">URL</Select.Option>
                                </Select>
                              </div>
                            )}
                            <div>
                              <label className="text-xs text-gray-600 mb-1 block">最大输入长度</label>
                              <InputNumber
                                value={field.maxLength}
                                onChange={(value) => updateField(field.id, { maxLength: value || undefined })}
                                size="small"
                                className="w-full"
                                min={0}
                              />
                            </div>
                            <div>
                              <label className="text-xs text-gray-600 mb-1 block">占位文本</label>
                              <Input
                                value={typeof field.placeholder === 'string' ? field.placeholder : ''}
                                onChange={(e) => updateField(field.id, { placeholder: e.target.value })}
                                size="small"
                              />
                            </div>
                            <div className="flex items-center justify-between">
                              <label className="text-xs text-gray-600">是否显示清除按钮</label>
                              <Switch
                                checked={field.showClear}
                                onChange={(checked) => updateField(field.id, { showClear: checked })}
                                size="small"
                              />
                            </div>
                          </>
                        )}
                        {!(field.type === 'input' || field.type === 'textarea' || field.type === 'password') && (
                          <div>
                            <label className="text-xs text-gray-600 mb-1 block">占位符</label>
                            <Input
                              value={typeof field.placeholder === 'string' ? field.placeholder : ''}
                              onChange={(e) => updateField(field.id, { placeholder: e.target.value })}
                              size="small"
                            />
                          </div>
                        )}
                <div>
                  <label className="text-xs text-gray-600 mb-1 block">尺寸</label>
                  <Select
                            value={field.size || 'middle'}
                            onChange={(value) => updateField(field.id, { size: value })}
                    size="small"
                    className="w-full"
                  >
                    <Select.Option value="small">小</Select.Option>
                    <Select.Option value="middle">中</Select.Option>
                    <Select.Option value="large">大</Select.Option>
                  </Select>
                </div>
                        {layoutColumns > 1 && (
                          <div>
                            <label className="text-xs text-gray-600 mb-1 block">跨列数</label>
                            <InputNumber
                              value={field.span || 1}
                              min={1}
                              max={layoutColumns}
                              onChange={(value) => updateField(field.id, { span: value || 1 })}
                              size="small"
                              className="w-full"
                            />
                          </div>
                        )}
                      </div>
                    </div>

                    {/* 选项配置（针对select/radio/checkbox） */}
                    {(field.type === 'select' || 
                      field.type === 'radio' || 
                      field.type === 'checkbox') && (
                      <>
                        <Divider className="my-2" />
                  <div>
                          <label className="text-xs font-semibold text-gray-700 mb-2 block">选项配置</label>
                    <div className="space-y-2">
                            {(field.options || []).map((option, idx) => (
                        <div key={idx} className="flex gap-2">
                          <Input
                            value={option.label}
                            onChange={(e) => {
                                    const newOptions = [...(field.options || [])];
                              newOptions[idx].label = e.target.value;
                                    updateField(field.id, { options: newOptions });
                            }}
                            placeholder="标签"
                            size="small"
                            className="flex-1"
                          />
                          <Input
                            value={option.value}
                            onChange={(e) => {
                                    const newOptions = [...(field.options || [])];
                              newOptions[idx].value = e.target.value;
                                    updateField(field.id, { options: newOptions });
                            }}
                            placeholder="值"
                            size="small"
                            className="flex-1"
                          />
                          <Button
                            type="text"
                            size="small"
                            danger
                            icon={<Trash2 className="w-3 h-3" />}
                            onClick={() => {
                                    const newOptions = field.options?.filter((_, i) => i !== idx) || [];
                                    updateField(field.id, { options: newOptions });
                            }}
                          />
                        </div>
                      ))}
                      <Button
                        type="dashed"
                        size="small"
                        block
                        icon={<Plus className="w-3 h-3" />}
                        onClick={() => {
                          const newOptions = [
                                  ...(field.options || []),
                                  { label: `选项${(field.options?.length || 0) + 1}`, value: `option${(field.options?.length || 0) + 1}` }
                          ];
                                updateField(field.id, { options: newOptions });
                        }}
                      >
                        添加选项
                      </Button>
                    </div>
                  </div>
                      </>
                    )}

                    {/* 级联选择器配置 */}
                    {field.type === 'cascader' && (
                      <>
                        <Divider className="my-2" />
                        <div>
                          <label className="text-xs font-semibold text-gray-700 mb-2 block">级联选项配置</label>
                          <TextArea
                            value={JSON.stringify(field.cascaderOptions || [], null, 2)}
                            onChange={(e) => {
                              try {
                                const parsed = JSON.parse(e.target.value);
                                updateField(field.id, { cascaderOptions: parsed });
                              } catch (err) {
                                // 无效JSON时不做处理
                              }
                            }}
                            rows={6}
                            size="small"
                            placeholder='[{"value":"zhejiang","label":"浙江","children":[{"value":"hangzhou","label":"杭州"}]}]'
                          />
                          <div className="text-xs text-gray-400 mt-1">
                            提示：级联选择器选项为树形结构，请使用JSON格式配置
                          </div>
                        </div>
                      </>
                    )}

                    {/* 上传组件配置 */}
                    {field.type === 'upload' && (
                      <>
                        <Divider className="my-2" />
                        <div>
                          <label className="text-xs font-semibold text-gray-700 mb-2 block">上传配置</label>
                          <div className="space-y-3">
                            <div>
                              <label className="text-xs text-gray-600 mb-1 block">上传类型</label>
                              <Select
                                value={field.uploadType || 'file'}
                                onChange={(value) => {
                                  const updates: Partial<FormField> = { uploadType: value };
                                  if (value === 'single-image') {
                                    updates.maxCount = 1;
                                    updates.accept = 'image/*';
                                  } else if (value === 'multiple-image') {
                                    updates.maxCount = 9;
                                    updates.accept = 'image/*';
                                  } else {
                                    updates.maxCount = undefined;
                                    updates.accept = undefined;
                                  }
                                  updateField(field.id, updates);
                                }}
                                size="small"
                                className="w-full"
                              >
                                <Select.Option value="single-image">单图上传</Select.Option>
                                <Select.Option value="multiple-image">多图上传</Select.Option>
                                <Select.Option value="file">文件上传</Select.Option>
                              </Select>
                            </div>
                            {field.uploadType !== 'single-image' && (
                              <div>
                                <label className="text-xs text-gray-600 mb-1 block">最大数量</label>
                                <InputNumber
                                  value={field.maxCount}
                                  onChange={(value) => updateField(field.id, { maxCount: value || undefined })}
                                  min={1}
                                  size="small"
                                  className="w-full"
                                  placeholder="不限制"
                                />
                              </div>
                            )}
                            <div>
                              <label className="text-xs text-gray-600 mb-1 block">接受的文件类型</label>
                              <Input
                                value={field.accept}
                                onChange={(e) => updateField(field.id, { accept: e.target.value || undefined })}
                                size="small"
                                placeholder="例如: image/*, .pdf, .doc"
                              />
                            </div>
                          </div>
                        </div>
                      </>
                    )}

                    {/* 验证配置 */}
                    <Divider className="my-2" />
                    <div>
                      <label className="text-xs font-semibold text-gray-700 mb-2 block">验证配置</label>
                      <div className="space-y-3">
                        {/* 是否必填 */}
                        <div className="flex items-center gap-2">
                          <label className="text-xs text-gray-600 flex-1">是否必填</label>
                          <Switch
                            checked={field.required}
                            onChange={(checked) => updateField(field.id, { required: checked })}
                            size="small"
                          />
                          {field.required && (
                            <Input
                              value={field.requiredMessage || ''}
                              onChange={(e) => updateField(field.id, { requiredMessage: e.target.value })}
                              placeholder="请输入提示语"
                              size="small"
                              className="flex-1"
                              style={{ maxWidth: '200px' }}
                            />
                          )}
                        </div>

                        {/* 验证规则列表 */}
                        <div>
                          <label className="text-xs font-semibold text-gray-700 mb-2 block">验证规则</label>
                          <div className="space-y-3">
                            {(field.validationRules || []).map((rule, ruleIdx) => (
                              <div key={rule.id || ruleIdx} className="border border-gray-200 rounded p-3 bg-gray-50">
                                <div className="flex items-center justify-between mb-2">
                                  <div className="flex items-center gap-2">
                                    <span className="w-5 h-5 rounded-full bg-gray-300 text-white text-xs flex items-center justify-center">
                                      {ruleIdx + 1}
                                    </span>
                                    <span className="text-xs text-gray-700">
                                      {rule.type === 'min' && '最小值'}
                                      {rule.type === 'max' && '最大值'}
                                      {rule.type === 'len' && '长度'}
                                      {rule.type === 'pattern' && '正则表达式'}
                                      {rule.type === 'validator' && '自定义验证'}
                                    </span>
                                  </div>
                                  <Button
                                    type="text"
                                    size="small"
                                    danger
                                    icon={<Trash2 className="w-3 h-3" />}
                                    onClick={() => {
                                      const newRules = field.validationRules?.filter((_, i) => i !== ruleIdx) || [];
                                      updateField(field.id, { validationRules: newRules });
                                    }}
                                  />
                                </div>
                                
                                <div className="space-y-2">
                                  {/* 验证方式 */}
                                  <div>
                                    <label className="text-xs text-gray-600 mb-1 block">验证方式</label>
                                    <Select
                                      value={rule.trigger || 'blur'}
                                      onChange={(value) => {
                                        const newRules = [...(field.validationRules || [])];
                                        newRules[ruleIdx].trigger = value;
                                        updateField(field.id, { validationRules: newRules });
                                      }}
                                      size="small"
                                      className="w-full"
                                    >
                                      <Select.Option value="blur">失去焦点</Select.Option>
                                      <Select.Option value="change">值改变</Select.Option>
                                      <Select.Option value="submit">提交时</Select.Option>
                                    </Select>
                                  </div>

                                  {/* 规则值输入 */}
                                  {(rule.type === 'min' || rule.type === 'max' || rule.type === 'len') && (
                                    <div>
                                      <label className="text-xs text-gray-600 mb-1 block">
                                        {rule.type === 'min' && '最小值'}
                                        {rule.type === 'max' && '最大值'}
                                        {rule.type === 'len' && '长度'}
                                      </label>
                                      <InputNumber
                                        value={typeof rule.value === 'number' ? rule.value : undefined}
                                        onChange={(value) => {
                                          const newRules = [...(field.validationRules || [])];
                                          newRules[ruleIdx].value = value ?? 0;
                                          updateField(field.id, { validationRules: newRules });
                                        }}
                                        size="small"
                                        className="w-full"
                                        min={0}
                                      />
                                    </div>
                                  )}

                                  {rule.type === 'pattern' && (
                                    <div>
                                      <label className="text-xs text-gray-600 mb-1 block">正则表达式</label>
                                      <Input
                                        value={typeof rule.value === 'string' ? rule.value : ''}
                                        onChange={(e) => {
                                          const newRules = [...(field.validationRules || [])];
                                          newRules[ruleIdx].value = e.target.value;
                                          updateField(field.id, { validationRules: newRules });
                                        }}
                                        placeholder="请输入正则表达式"
                                        size="small"
                                        className="w-full"
                                      />
                                    </div>
                                  )}

                                  {rule.type === 'validator' && (
                                    <div>
                                      <label className="text-xs text-gray-600 mb-1 block">自定义验证</label>
                                      <Button
                                        type="primary"
                                        size="small"
                                        onClick={() => {
                                          toast.info('自定义验证功能开发中');
                                        }}
                                      >
                                        自定义验证
                                      </Button>
                                    </div>
                                  )}

                                  {/* 错误信息 */}
                                  <div>
                                    <label className="text-xs text-gray-600 mb-1 block">错误信息</label>
                                    <Input
                                      value={rule.message || ''}
                                      onChange={(e) => {
                                        const newRules = [...(field.validationRules || [])];
                                        newRules[ruleIdx].message = e.target.value;
                                        updateField(field.id, { validationRules: newRules });
                                      }}
                                      placeholder="请输入提示语"
                                      size="small"
                                      className="w-full"
                                    />
                                  </div>
                                </div>
                              </div>
                            ))}
                          </div>
                        </div>

                        {/* 添加验证规则按钮 */}
                        <div>
                          <Dropdown
                            menu={{
                              items: [
                                {
                                  key: 'min',
                                  label: '最小值',
                                  onClick: () => {
                                    const newRule = {
                                      id: `rule_${Date.now()}`,
                                      type: 'min' as const,
                                      trigger: 'blur' as const,
                                      value: 0,
                                      message: '',
                                    };
                                    const newRules = [
                                      ...(field.validationRules || []),
                                      newRule
                                    ];
                                    updateField(field.id, { validationRules: newRules });
                                  }
                                },
                                {
                                  key: 'max',
                                  label: '最大值',
                                  onClick: () => {
                                    const newRule = {
                                      id: `rule_${Date.now()}`,
                                      type: 'max' as const,
                                      trigger: 'blur' as const,
                                      value: 0,
                                      message: '',
                                    };
                                    const newRules = [
                                      ...(field.validationRules || []),
                                      newRule
                                    ];
                                    updateField(field.id, { validationRules: newRules });
                                  }
                                },
                                {
                                  key: 'len',
                                  label: '长度',
                                  onClick: () => {
                                    const newRule = {
                                      id: `rule_${Date.now()}`,
                                      type: 'len' as const,
                                      trigger: 'blur' as const,
                                      value: 0,
                                      message: '',
                                    };
                                    const newRules = [
                                      ...(field.validationRules || []),
                                      newRule
                                    ];
                                    updateField(field.id, { validationRules: newRules });
                                  }
                                },
                                {
                                  key: 'pattern',
                                  label: '正则表达式',
                                  onClick: () => {
                                    const newRule = {
                                      id: `rule_${Date.now()}`,
                                      type: 'pattern' as const,
                                      trigger: 'blur' as const,
                                      value: '',
                                      message: '',
                                    };
                                    const newRules = [
                                      ...(field.validationRules || []),
                                      newRule
                                    ];
                                    updateField(field.id, { validationRules: newRules });
                                  }
                                },
                                {
                                  type: 'divider',
                                },
                                {
                                  key: 'validator',
                                  label: '自定义验证',
                                  onClick: () => {
                                    toast.info('自定义验证功能开发中');
                                  }
                                },
                              ],
                            }}
                          >
                            <Button type="dashed" size="small" block icon={<Plus className="w-3 h-3" />}>
                              添加验证规则
                            </Button>
                          </Dropdown>
                        </div>
                      </div>
                    </div>
              </div>
              </div>
                          );
                        })() : (
                          <div className="flex-1 overflow-y-auto p-4 text-center text-gray-400 text-sm">
                            请选择一个字段进行配置
                          </div>
                        ),
                      },
                    ]
                  : []),
              ]}
            />
          </div>
        </div>

        {/* 预览弹窗：宽度与表单管理预览弹框一致 */}
        <Modal
          title="表单预览"
          open={previewVisible}
          onCancel={() => setPreviewVisible(false)}
          footer={[
            <div key="footer-wrapper" style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: '12px', width: '100%' }}>
              <span style={{ color: '#ff4d4f', fontSize: '14px' }}>仅为表单预览,点击提交无效</span>
              <div style={{ display: 'flex', gap: '8px' }}>
                {formConfig.showSubmitButton && (
                  <Button
                    key="submit"
                    type="primary"
                    onClick={() => {
                      previewForm.validateFields().then(() => {
                        toast.success('提交成功');
                        setPreviewVisible(false);
                      }).catch(() => {
                        // 验证失败
                      });
                    }}
                  >
                    提交
                  </Button>
                )}
                {formConfig.showResetButton && (
                  <Button
                    key="reset"
                    onClick={() => {
                      previewForm.resetFields();
                    }}
                  >
                    重置
                  </Button>
                )}
              </div>
            </div>
          ]}
          width={960}
        >
          <div className="p-2">
            {(() => {
              const previewLayoutColumns = formConfig.layoutColumns || 1;
              const gridStyle = previewLayoutColumns > 1 ? {
                display: 'grid',
                gridTemplateColumns: `repeat(${previewLayoutColumns}, minmax(0, 1fr))`,
                gap: '12px',
                rowGap: '16px',
              } : undefined;

              return (
                <AntdForm
                  form={previewForm}
                  layout={formConfig.labelPosition === 'top' ? 'vertical' : formConfig.labelPosition === 'left' ? 'horizontal' : 'horizontal'}
                  size={formConfig.formSize === 'default' ? 'middle' : formConfig.formSize}
                  requiredMark={formConfig.hideRequiredMark ? false : undefined}
                  labelCol={
                    formConfig.labelPosition === 'top' || !formConfig.labelWidth
                      ? undefined
                      : {
                          flex: `${formConfig.labelWidth}px`,
                          style: {
                            minWidth: `${formConfig.labelWidth}px`,
                            textAlign: formConfig.labelPosition === 'right' ? 'right' : 'left',
                          },
                        }
                  }
                  wrapperCol={
                    formConfig.labelPosition === 'top'
                      ? undefined
                      : {
                          flex: 'auto',
                          style: { minWidth: 0 },
                        }
                  }
                >
                  <div 
                    style={gridStyle} 
                    className={previewLayoutColumns === 1 ? 'space-y-4' : 'form-preview-grid'}
                  >
                    <style>{`
                      .form-preview-grid .ant-form-item {
                        margin-bottom: 12px;
                      }
                      .form-preview-grid .ant-form-item-control {
                        min-width: 0;
                      }
                      .form-preview-grid .ant-form-item-control-input-content {
                        min-width: 0;
                      }
                    `}</style>
                    {fields.map((field) => {
                      const spanStyle: React.CSSProperties | undefined = previewLayoutColumns > 1 
                        ? { gridColumn: `span ${Math.min(previewLayoutColumns, field.span || 1)}` } 
                        : undefined;

                      // 处理 grid 类型
                      if (field.type === 'grid') {
                        const gridColumns = field.gridColumns || 2;
                        const children = field.children || [];
                        return (
                          <div key={field.id} style={spanStyle} className="mb-4">
                            <div
                              style={{
                                display: 'grid',
                                gridTemplateColumns: `repeat(${gridColumns}, minmax(0, 1fr))`,
                                gap: '12px',
                                rowGap: '16px',
                              }}
                            >
                              {children.map((childField) => {
                                if (!childField) return null;
                                const childSpanStyle = gridColumns > 1 
                                  ? { gridColumn: `span ${Math.min(gridColumns, childField.span || 1)}` } 
                                  : undefined;
                                return (
                                  <div key={childField.id} style={childSpanStyle}>
                                    {renderPreviewField(childField, formConfig, previewLayoutColumns)}
                                  </div>
                                );
                              })}
                            </div>
                          </div>
                        );
                      }

                      // 处理 card 类型
                      if (field.type === 'card') {
                        const cardTitle = field.label || field.cardTitle || '卡片容器';
                        const children = field.children || [];
                        return (
                          <div key={field.id} style={spanStyle} className="mb-4">
                            <Card title={cardTitle} className="w-full">
                              <div className="space-y-4">
                                {children.map((childField) => {
                                  if (!childField) return null;
                                  return (
                                    <div key={childField.id}>
                                      {renderPreviewField(childField, formConfig, previewLayoutColumns)}
                                    </div>
                                  );
                                })}
                              </div>
                            </Card>
                          </div>
                        );
                      }

                      // 处理 tabs 类型
                      if (field.type === 'tabs') {
                        return (
                          <div key={field.id} style={spanStyle} className="mb-4">
                            <Tabs
                              items={field.tabs?.map((tab: any) => ({
                                key: tab.key,
                                label: tab.label,
                                children: (
                                  <div className="space-y-4">
                                    {tab.children?.map((child: string) => {
                                      const childField = fields.find(f => f.id === child);
                                      if (!childField) return null;
                                      return (
                                        <div key={childField.id}>
                                          {renderPreviewField(childField, formConfig, previewLayoutColumns)}
                                        </div>
                                      );
                                    })}
                                  </div>
                                ),
                              }))}
                            />
                          </div>
                        );
                      }

                      // 处理 alert 类型
                      if (field.type === 'alert') {
                        const themeClass =
                          field.alertTheme === 'dark'
                            ? 'bg-gray-800 text-white border-gray-700'
                            : '';
                        return (
                          <div key={field.id} className="mb-4" style={spanStyle}>
                            <Alert
                              message={field.alertTitle || field.label}
                              description={field.alertDescription}
                              type={field.alertType || 'info'}
                              showIcon={field.alertShowIcon !== false}
                              closable={field.alertClosable}
                              closeText={field.alertCloseText}
                              className={`${field.alertCentered ? 'text-center' : ''} ${themeClass}`}
                              banner
                              style={field.style}
                            />
                            {field.hint && <div className="text-xs text-gray-400 mt-1">{field.hint}</div>}
                          </div>
                        );
                      }

                      // 处理普通字段
                      return (
                        <div key={field.id} style={spanStyle}>
                          {renderPreviewField(field, formConfig, previewLayoutColumns)}
                        </div>
                      );
                    })}
                  </div>
                </AntdForm>
              );
            })()}
          </div>
        </Modal>

        {/* 保存弹窗 */}
        <Modal
          title="保存表单"
          open={saveModalVisible}
          onCancel={() => setSaveModalVisible(false)}
          footer={[
            <Button key="cancel" onClick={() => setSaveModalVisible(false)}>
              取消
            </Button>,
            <Button key="save" type="primary" onClick={doSave} loading={saving}>
              保存
            </Button>,
          ]}
          width={600}
        >
          <div className="space-y-4">
            <div>
              <label className="text-xs text-gray-600 mb-1 block">表单名称</label>
              <Input
                value={formName}
                onChange={(e) => {
                  setFormName(e.target.value);
                  markDirty();
                }}
                size="small"
                placeholder="请输入表单名称"
              />
            </div>
            <div>
              <label className="text-xs text-gray-600 mb-1 block">表单状态</label>
              <Select
                value={formStatus}
                onChange={(value) => {
                  setFormStatus(value);
                  markDirty();
                }}
                size="small"
                className="w-full"
              >
                {statusOptions.map((option) => (
                  <Select.Option key={option.value} value={option.value}>
                    {option.label}
                  </Select.Option>
                ))}
              </Select>
            </div>
            <div>
              <label className="text-xs text-gray-600 mb-1 block">备注</label>
              <TextArea
                value={formRemark}
                onChange={(e) => {
                  setFormRemark(e.target.value);
                  markDirty();
                }}
                rows={3}
                size="small"
                placeholder="请输入备注"
              />
            </div>
          </div>
        </Modal>

        {/* 代码弹窗 */}
        <Modal
          title="表单代码"
          open={codeVisible}
          onCancel={() => setCodeVisible(false)}
          footer={[
            <Button key="close" onClick={() => setCodeVisible(false)}>
              关闭
            </Button>
          ]}
          width={800}
        >
          <div>
            <pre style={{ background: '#f5f5f5', padding: '16px', borderRadius: '4px', overflow: 'auto' }}>
              {JSON.stringify({ fields, formName, formRemark, formConfig }, null, 2)}
            </pre>
          </div>
        </Modal>
      </div>
    </DndProvider>
  );
}; 

