/**
 * 表单设计器主入口
 * 
 * 功能：
 * - 左侧：组件面板
 * - 中间：设计画布
 * - 右侧：属性配置
 * - 导入/导出 JSON Schema
 */

import React, { useState, useCallback } from 'react';
import { Button, Space, message, Modal } from 'antd';
import {
  SaveOutlined,
  DownloadOutlined,
  UploadOutlined,
  EyeOutlined,
  ClearOutlined,
} from '@ant-design/icons';
import { DndContext, DragEndEvent, DragOverlay, PointerSensor, useSensor, useSensors } from '@dnd-kit/core';
import { arrayMove } from '@dnd-kit/sortable';
import ComponentPanel from './components/ComponentPanel';
import DesignCanvas from './components/DesignCanvas';
import PropertyPanel from './components/PropertyPanel';
import FormPreview from './components/FormPreview';
import { COMPONENT_LIST } from './config';
import type { FieldConfig, FormConfig, FormSchema } from './types';

const FormDesigner: React.FC = () => {
  // 表单字段列表
  const [fields, setFields] = useState<FieldConfig[]>([]);
  
  // 选中的字段
  const [selectedFieldId, setSelectedFieldId] = useState<string>();
  
  // 表单配置
  const [formConfig, setFormConfig] = useState<FormConfig>({
    labelAlign: 'right',
    size: 'middle',
    formWidth: 600, // 表单弹窗宽度（像素）
  });

  // 预览模式
  const [previewVisible, setPreviewVisible] = useState(false);

  // 拖拽传感器
  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: {
        distance: 8,
      },
    })
  );

  // 生成唯一 ID
  const generateId = () => `field_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

  // 处理拖拽结束
  const handleDragEnd = useCallback((event: DragEndEvent) => {
    const { active, over } = event;

    if (!over) return;

    const overId = over.id.toString();

    // 从组件面板拖入新组件
    if (active.data.current?.isNew) {
      const componentType = active.id.toString().replace('new-', '');
      const componentMeta = COMPONENT_LIST.find(c => c.type === componentType);
      
      if (componentMeta) {
        const newField: FieldConfig = {
          id: generateId(),
          type: componentMeta.type,
          label: componentMeta.label,
          name: componentType + '_' + Date.now(),
          ...componentMeta.defaultConfig,
        };

        // 检测是否拖入栅格列
        if (overId.startsWith('grid-') && overId.includes('-col-')) {
          const match = overId.match(/grid-(.+)-col-(\d+)/);
          if (match) {
            const [, gridId, colIndexStr] = match;
            const colIndex = parseInt(colIndexStr, 10);

            setFields(prev => prev.map(field => {
              if (field.id === gridId && field.type === 'grid') {
                const newChildren = [...(field.children || [])];
                if (!newChildren[colIndex]) {
                  newChildren[colIndex] = [];
                }
                newChildren[colIndex] = [...newChildren[colIndex], newField];
                return { ...field, children: newChildren };
              }
              return field;
            }));
            setSelectedFieldId(newField.id);
            message.success(`已添加${componentMeta.label}到栅格列`);
            return;
          }
        }

        // 拖入主画布
        setFields(prev => [...prev, newField]);
        setSelectedFieldId(newField.id);
        message.success(`已添加${componentMeta.label}`);
      }
    }
    // 画布内拖拽排序
    else if (over.id === 'canvas' || fields.some(f => f.id === over.id)) {
      const oldIndex = fields.findIndex(f => f.id === active.id);
      const newIndex = fields.findIndex(f => f.id === over.id);

      if (oldIndex !== -1 && newIndex !== -1 && oldIndex !== newIndex) {
        setFields(arrayMove(fields, oldIndex, newIndex));
      }
    }
  }, [fields]);

  // 选中字段
  const handleSelectField = useCallback((fieldId: string) => {
    setSelectedFieldId(fieldId);
  }, []);

  // 删除字段（支持删除栅格内的字段）
  const handleDeleteField = useCallback((fieldId: string) => {
    let deleted = false;

    // 递归删除函数
    const deleteFieldRecursive = (fieldList: FieldConfig[]): FieldConfig[] => {
      return fieldList
        .filter(f => {
          if (f.id === fieldId) {
            deleted = true;
            return false;
          }
          return true;
        })
        .map(f => {
          // 如果是栅格布局，递归处理其子字段
          if (f.type === 'grid' && f.children) {
            return {
              ...f,
              children: f.children.map(columnFields => 
                deleteFieldRecursive(columnFields)
              ),
            };
          }
          return f;
        });
    };

    setFields(prev => deleteFieldRecursive(prev));

    if (deleted) {
      if (selectedFieldId === fieldId) {
        setSelectedFieldId(undefined);
      }
      message.success('已删除字段');
    }
  }, [selectedFieldId]);

  // 更新字段属性（支持更新栅格内的字段）
  const handleFieldChange = useCallback((updatedField: FieldConfig) => {
    // 递归更新函数
    const updateFieldRecursive = (fieldList: FieldConfig[]): FieldConfig[] => {
      return fieldList.map(f => {
        if (f.id === updatedField.id) {
          return updatedField;
        }
        // 如果是栅格布局，递归处理其子字段
        if (f.type === 'grid' && f.children) {
          return {
            ...f,
            children: f.children.map(columnFields => 
              updateFieldRecursive(columnFields)
            ),
          };
        }
        return f;
      });
    };

    setFields(prev => updateFieldRecursive(prev));
  }, []);

  // 保存表单
  const handleSave = useCallback(() => {
    if (fields.length === 0) {
      message.warning('表单为空，请先添加字段');
      return;
    }

    const schema: FormSchema = {
      formConfig,
      fields,
    };

    console.log('保存的表单 Schema:', JSON.stringify(schema, null, 2));
    message.success('表单已保存！请查看控制台');
    
    // TODO: 调用后端 API 保存
  }, [fields, formConfig]);

  // 导出 JSON
  const handleExport = useCallback(() => {
    if (fields.length === 0) {
      message.warning('表单为空，无法导出');
      return;
    }

    const schema: FormSchema = {
      formConfig,
      fields,
    };

    const dataStr = JSON.stringify(schema, null, 2);
    const dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);
    const exportFileDefaultName = `form-schema-${Date.now()}.json`;

    const linkElement = document.createElement('a');
    linkElement.setAttribute('href', dataUri);
    linkElement.setAttribute('download', exportFileDefaultName);
    linkElement.click();

    message.success('JSON Schema 已导出');
  }, [fields, formConfig]);

  // 导入 JSON
  const handleImport = useCallback(() => {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.json';

    input.onchange = (e: any) => {
      const file = e.target.files[0];
      if (file) {
        const reader = new FileReader();
        reader.onload = (event: any) => {
          try {
            const schema: FormSchema = JSON.parse(event.target.result);

            if (!schema.fields || !Array.isArray(schema.fields)) {
              message.error('无效的表单 Schema 格式');
              return;
            }

            setFields(schema.fields);
            setFormConfig(schema.formConfig || formConfig);
            setSelectedFieldId(undefined);
            message.success('JSON Schema 导入成功');
          } catch (error) {
            message.error('JSON 格式错误');
            console.error('导入错误:', error);
          }
        };
        reader.readAsText(file);
      }
    };

    input.click();
  }, [formConfig]);

  // 清空表单
  const handleClear = useCallback(() => {
    Modal.confirm({
      title: '确认清空',
      content: '确定要清空所有字段吗？此操作不可恢复。',
      onOk: () => {
        setFields([]);
        setSelectedFieldId(undefined);
        message.info('表单已清空');
      },
    });
  }, []);

  // 递归查找选中的字段（包括栅格内的字段）
  const findFieldById = (fieldList: FieldConfig[], id?: string): FieldConfig | undefined => {
    if (!id) return undefined;
    
    for (const field of fieldList) {
      if (field.id === id) {
        return field;
      }
      // 如果是栅格布局，递归查找子字段
      if (field.type === 'grid' && field.children) {
        for (const columnFields of field.children) {
          const found = findFieldById(columnFields, id);
          if (found) return found;
        }
      }
    }
    return undefined;
  };

  const selectedField = findFieldById(fields, selectedFieldId);

  return (
    <div style={{ height: '100vh', width: '100%', display: 'flex', flexDirection: 'column' }}>
      {/* 顶部工具栏 */}
      <div
        style={{
          padding: '12px 24px',
          background: '#fff',
          borderBottom: '1px solid #e8e8e8',
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          zIndex: 1000,
        }}
      >
        <h2 style={{ margin: 0, fontSize: '18px', fontWeight: 500 }}>
          表单设计器
        </h2>
        <Space>
          <Button icon={<UploadOutlined />} onClick={handleImport}>
            导入 JSON
          </Button>
          <Button icon={<DownloadOutlined />} onClick={handleExport}>
            导出 JSON
          </Button>
          <Button icon={<EyeOutlined />} onClick={() => setPreviewVisible(true)}>
            预览
          </Button>
          <Button icon={<ClearOutlined />} danger onClick={handleClear}>
            清空
          </Button>
          <Button type="primary" icon={<SaveOutlined />} onClick={handleSave}>
            保存
          </Button>
        </Space>
      </div>

      {/* 主体区域 */}
      <DndContext sensors={sensors} onDragEnd={handleDragEnd}>
        <div style={{ flex: 1, display: 'flex', overflow: 'hidden' }}>
          {/* 左侧组件面板 */}
          <div style={{ width: 280 }}>
            <ComponentPanel />
          </div>

          {/* 中间设计画布 */}
          <DesignCanvas
            fields={fields}
            selectedFieldId={selectedFieldId}
            onSelectField={handleSelectField}
            onDeleteField={handleDeleteField}
            labelAlign={formConfig.labelAlign}
          />

          {/* 右侧属性面板 */}
          <PropertyPanel
            selectedField={selectedField}
            formConfig={formConfig}
            onFieldChange={handleFieldChange}
            onFormConfigChange={setFormConfig}
          />
        </div>

        <DragOverlay>{/* 拖拽时的视觉反馈 */}</DragOverlay>
      </DndContext>

      {/* 预览模态框 */}
      <Modal
        title="表单预览"
        open={previewVisible}
        onCancel={() => setPreviewVisible(false)}
        width={formConfig.formWidth || 600}
        footer={null}
      >
        <FormPreview fields={fields} formConfig={formConfig} />
      </Modal>
    </div>
  );
};

export default FormDesigner;
