import { FormItemJSON } from '../element-easy-form';
import { AttrType, ComponentType } from './enum';
import { WatchOptions } from 'vue';

/**
 * ========================================
 * 拖拽表单设计器类型定义
 * ========================================
 * 本文件定义了用于可视化表单设计器的类型和工厂函数。
 * DragFormType 是设计器中每个组件的数据结构，扩展了基础的 FormItemJSON。
 *
 * 与 FormItemJSON 的区别：
 * - FormItemJSON: 运行时表单渲染用的轻量级配置
 * - DragFormType: 设计器用的增强配置，包含额外的设计时信息（id、active、attrsJson等）
 */
/**
 * Watch 监听器配置接口
 *
 * 用于在设计器中为组件添加响应式监听
 * 监听某个属性的变化并执行相应操作
 *
 * @example 监听 prop 变化
 * {
 *   "prop": "attrs.disabled",
 *   "immediate": true,
 *   "handler": (value, children) => {
 *     console.log('disabled 变为:', value);
 *   }
 * }
 *
 * @example 监听并联动子组件
 * {
 *   "prop": "attrs.value",
 *   "handler": (value, children) => {
 *     children.forEach(child => {
 *       child.attrs.placeholder = value;
 *     });
 *   }
 * }
 */
interface WatchHandler {
    /**
     * 监听的属性路径
     * 支持点号访问嵌套属性
     *
     * @example "attrs.disabled" - 监听组件的 disabled 属性
     * @example "attrs.value" - 监听组件的 value 属性
     * @example "attrsJson[0].defaultValue" - 监听属性配置数组中某项的默认值
     */
    prop: string;
    /**
     * 是否立即执行一次监听器
     * - true: 组件初始化时立即调用 handler
     * - false: 只在属性变化时调用
     *
     * 默认: false
     */
    immediate?: boolean;
    /**
     * Vue watch 配置选项
     * 用于精细控制监听行为
     *
     * 可选配置：
     * - deep: 是否深度监听对象/数组
     * - flush: 回调的触发时机（'pre'/'post'/'sync'）
     *
     * @example { "deep": true } - 深度监听对象变化
     * @example { "deep": false, "flush": "post" } - 不深度监听，回调在 DOM 更新后触发
     */
    options?: WatchOptions;
    /**
     * 属性变化时的回调函数
     * 在监听的属性值改变时执行
     *
     * @param value - 属性的新值
     * @param children - 组件的子组件数组（可选）
     *
     * 使用场景：
     * 1. 联动更新子组件属性
     * 2. 根据某个属性值的变化执行自定义逻辑
     * 3. 属性间的复杂联动关系
     *
     * @example 简单日志输出
     * handler: (value) => {
     *   console.log('值变为:', value);
     * }
     *
     * @example 联动更新子组件
     * handler: (value, children) => {
     *   if (children) {
     *     children.forEach(child => {
     *       if (child.componentName === 'ElOption') {
     *         child.attrs.disabled = value;
     *       }
     *     });
     *   }
     * }
     */
    handler: (value: any, children?: any[]) => void;
}
/**
 * 拖拽表单组件类型
 *
 * 扩展自 FormItemJSON，在运行时表单配置的基础上增加了设计器所需的属性
 * 用于拖拽表单设计器中每个组件的内部表示
 *
 * 继承自 FormItemJSON 的属性：
 * - label, prop, componentName, attrs, events, defaultValue, hidden, children, rules 等
 *
 * 新增的设计器专属属性：
 * - id: 组件唯一标识（设计器中生成）
 * - type: 组件分类（布局/组件/表单项）
 * - attrsJson: 属性配置元数据（用于生成右侧属性面板）
 * - title: 设计器中的显示标题
 * - active: 当前选中状态
 * - formType: 支持的表单类型
 * - parentId: 父组件 ID
 * - watch: 属性监听配置
 *
 * 使用场景：
 * 1. 左侧组件列表：定义可拖拽的组件模板
 * 2. 中间画布：定义已拖入的组件实例
 * 3. 右侧属性面板：通过 attrsJson 生成属性编辑表单
 * 4. 拖拽交互：通过 id、parentId 管理组件树结构
 *
 * @example 设计器中的输入框组件
 * {
 *   // 继承自 FormItemJSON 的运行时属性
 *   "label": "用户名",
 *   "prop": "username",
 *   "componentName": "ElInput",
 *   "attrs": { "type": "text", "placeholder": "请输入" },
 *
 *   // 设计器专属属性
 *   "id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
 *   "title": "输入框",
 *   "type": "COMPONENT",
 *   "active": false,
 *   "formType": "all",
 *   "parentId": "parent-row-id",
 *
 *   // 属性配置元数据（用于生成右侧属性编辑面板）
 *   "attrsJson": [
 *     {
 *       "label": "类型",
 *       "prop": "attrs.type",
 *       "componentName": "ElSelect",
 *       "type": "COMPONENT",
 *       "defaultValue": "text",
 *       "children": [
 *         { "componentName": "ElOption", "value": "text", "label": "文本" },
 *         { "componentName": "ElOption", "value": "password", "label": "密码" }
 *       ]
 *     },
 *     {
 *       "label": "占位符",
 *       "prop": "attrs.placeholder",
 *       "componentName": "ElInput",
 *       "type": "COMPONENT",
 *       "defaultValue": "请输入"
 *     }
 *   ],
 *
 *   // 属性监听器
 *   "watch": [
 *     {
 *       "prop": "attrs.type",
 *       "handler": (value) => {
 *         console.log('输入框类型变为:', value);
 *       }
 *     }
 *   ]
 * }
 *
 * @example 设计器中的栅格列组件
 * {
 *   "id": "col-1",
 *   "title": "列",
 *   "componentName": "ElCol",
 *   "type": "LAYOUT",
 *   "attrs": { "span": 12 },
 *   "parentId": "row-1",
 *   "children": [...],
 *   "attrsJson": [...]
 * }
 */
export interface DragFormType extends FormItemJSON {
    /**
     * 组件唯一标识符
     * 设计器中每个组件实例的唯一 ID
     * - 使用 UUID 生成
     * - 用于在拖拽操作中识别组件
     * - 用于建立父子关系（parentId）
     * - 用于选中组件时的状态管理
     *
     * 使用场景：
     * 1. 拖拽时克隆组件生成新 ID
     * 2. 右侧属性面板选中组件时通过 id 查找
     * 3. 删除组件时通过 id 从数组中移除
     * 4. 导出 JSON 时保留组件层级关系
     *
     * 注意：
     * - 生成最终表单 JSON 时，运行时不需要这些 ID
     * - 只在设计器中使用
     *
     * @example "550e8400-e29b-41d4-a716-446655440000"
     */
    id?: string;
    /**
     * 组件分类类型
     * 标识组件在设计器中的分类和用途
     *
     * 可选值（参考 AttrType 枚举）：
     * - "COMPONENT": 表单组件（输入框、选择器等）
     * - "LAYOUT": 布局组件（ElRow、ElCol）
     * - "FORMITEM": 表单项容器属性
     *
     * 使用场景：
     * 1. 过滤左侧组件列表（按 formType 显示不同类型）
     * 2. 控制拖拽规则（某些组件只能拖入特定容器）
     * 3. 右侧属性面板渲染不同的表单项
     *
     * @example "COMPONENT" - 表单字段组件
     * @example "LAYOUT" - 栅格布局组件
     * @example "FORMITEM" - FormItem 属性配置
     */
    type?: string;
    /**
     * 属性配置元数据数组
     * 定义了该组件在右侧属性面板中可配置的所有属性
     * - 数组中每个元素是一个 FormItemJSON
     * - 用于动态生成属性编辑表单
     * - 与 attrs 是不同的概念：attrs 是组件本身的属性，attrsJson 是如何配置这些属性的元数据
     *
     * 属性配置项结构：
     * - prop: 要配置的组件属性路径（如 "attrs.type"）
     * - label: 属性显示名称
     * - componentName: 用于编辑该属性的组件（ElInput、ElSelect 等）
     * - defaultValue: 默认值
     * - children: 对于需要子组件的属性（如 ElSelect 需要 ElOption）
     * - type: 属性分类（COMPONENT/FORMITEM/LAYOUT）
     *
     * 使用场景：
     * 1. 设计器右侧属性面板自动生成
     * 2. 可视化配置组件的所有可配置属性
     * 3. 属性面板的表单验证
     *
     * @example ElInput 的 attrsJson
     * attrsJson: [
     *   {
     *     "label": "类型",
     *     "prop": "attrs.type",
     *     "type": "COMPONENT",
     *     "componentName": "ElSelect",
     *     "defaultValue": "text",
     *     "children": [
     *       { "componentName": "ElOption", "value": "text", "label": "文本" },
     *       { "componentName": "ElOption", "value": "password", "label": "密码" }
     *     ]
     *   },
     *   {
     *     "label": "占位符",
     *     "prop": "attrs.placeholder",
     *     "type": "COMPONENT",
     *     "componentName": "ElInput",
     *     "defaultValue": "请输入"
     *   },
     *   {
     *     "label": "是否禁用",
     *     "prop": "attrs.disabled",
     *     "type": "COMPONENT",
     *     "componentName": "ElSwitch",
     *     "defaultValue": false
     *   }
     * ]
     *
     * @example ElRow 的 attrsJson（配置列的 span）
     * attrsJson: [
     *   {
     *     "label": "栅格列配置",
     *     "prop": "attrsJson",
     *     "type": "FORMITEM",
     *     "componentName": "ElRowAttrs",
     *     "defaultValue": [
     *       { "attrs": { "span": 12 } },
     *       { "attrs": { "span": 12 } }
     *     ]
     *   }
     * ]
     */
    attrsJson?: FormItemJSON[];
    /**
     * 组件显示标题
     * 在设计器中展示给用户的组件名称
     * - 固定值，用户不可更改
     * - 用于左侧组件列表按钮的文字
     * - 用于中间画布组件的标题显示
     * - 不同于 label（label 是表单字段的标签，title 是设计器中的组件名）
     *
     * @example "输入框"
     * @example "下拉选择"
     * @example "日期选择器"
     * @example "栅格行"
     */
    title?: string;
    /**
     * 当前激活状态
     * 标识组件是否被用户选中
     * - true: 组件被选中（在画布上高亮，右侧显示属性面板）
     * - false: 组件未被选中
     *
     * 使用场景：
     * 1. 点击画布中的组件，设置 active = true
     * 2. 点击画布空白处，清除所有组件的 active 状态
     * 3. 根据 active 状态渲染高亮样式（边框、阴影等）
     * 4. 右侧属性面板根据 active 组件显示对应属性
     *
     * 注意：
     * - 同一时间只能有一个组件处于 active 状态
     * - 切换组件选中时需要更新其他组件的 active 为 false
     * - 最终导出的 JSON 中不包含此字段
     *
     * @example 被选中的组件: { "active": true, ... }
     * @example 未选中的组件: { "active": false, ... }
     */
    active?: boolean;
    /**
     * 支持的表单类型
     * 标识该组件在哪种表单模式下可用
     *
     * 可选值（参考 JSONType 枚举）：
     * - "drag-form": 仅在拖拽表单模式下可用
     * - "element-easy-form": 仅在二开表单模式下可用
     * - "all": 在两种模式下都可用
     *
     * 使用场景：
     * 1. 切换表单类型时过滤左侧组件列表
     * 2. 控制不同模式下显示不同的可用组件
     *
     * @example "all" - 两种表单类型都支持
     * @example "drag-form" - 仅拖拽表单模式支持
     * @example "element-easy-form" - 仅二开表单模式支持
     */
    formType?: string;
    /**
     * 父组件唯一标识符
     * 标识当前组件的父组件，用于构建组件树结构
     * - 对于根级组件，parentId 可能为空
     * - 对于子组件，parentId 指向其父组件的 id
     *
     * 使用场景：
     * 1. 建立组件层级关系（树形结构）
     * 2. 拖拽时判断组件是否可以放置到某个容器内
     * 3. 删除父组件时同时删除所有子组件
     * 4. 查找组件的父级或兄弟组件
     * 5. 导出 JSON 时重建嵌套结构
     *
     * @example 顶层组件: parentId = undefined 或 ""
     * @example ElOption: parentId = "el-select-id"
     * @example ElCol: parentId = "el-row-id"
     */
    parentId?: string;
    /**
     * 属性监听器配置
     * 用于监听组件自身属性的变化并执行回调
     * - 可以配置单个监听器或监听器数组
     * - 监听器在属性值变化时自动触发
     *
     * 使用场景：
     * 1. 联动更新子组件的属性（如改变 Select 的值，影响 Option 的状态）
     * 2. 属性之间的依赖关系（如改变某个属性，自动调整其他属性）
     * 3. 属性变化时的自定义业务逻辑
     * 4. 组件初始化时的默认设置（使用 immediate: true）
     *
     * @example 监听单个属性
     * watch: {
     *   "prop": "attrs.disabled",
     *   "immediate": true,
     *   "handler": (value) => {
     *     console.log('disabled 变为:', value);
     *   }
     * }
     *
     * @example 监听多个属性（数组形式）
     * watch: [
     *   {
     *     "prop": "attrs.type",
     *     "handler": (value) => {
     *       // 输入框类型改变时的处理
     *     }
     *   },
     *   {
     *     "prop": "attrs.placeholder",
     *     "handler": (value) => {
     *       // 占位符改变时的处理
     *     }
     *   }
     * ]
     *
     * @example 联动更新子组件
     * watch: {
     *   "prop": "attrs.value",
     *   "handler": (value, children) => {
     *     if (children) {
     *       children.forEach(child => {
     *         child.attrs.label = `选项 ${value}`;
     *       });
     *     }
     *   }
     * }
     */
    watch?: WatchHandler | WatchHandler[];
}
/**
 * 创建 ElCol 栅格列数据工厂函数
 *
 * 生成 ElCol 组件在设计器中的标准配置
 * 常用于 ElRow 的子组件创建
 *
 * @param span - 栅格占位格数，默认使用 SPANDEFAULT
 * @param parentId - 父组件 ID，默认为空字符串
 *
 * @returns DragFormType - ElCol 组件配置对象
 *
 * @example 创建一个占12格的列
 * const col1 = ElColDragFormData(12, "row-1");
 * // 结果: { title: "列", type: "LAYOUT", componentName: "ElCol", attrs: { span: 12 }, ... }
 *
 * @example 创建一个占8格的列
 * const col2 = ElColDragFormData(8, "row-1");
 * // 结果: { title: "列", type: "LAYOUT", componentName: "ElCol", attrs: { span: 8 }, ... }
 *
 * @example 使用默认 span
 * const col3 = ElColDragFormData(undefined, "row-1");
 * // 结果: { title: "列", type: "LAYOUT", componentName: "ElCol", attrs: { span: SPANDEFAULT }, ... }
 */
export declare const ElColDragFormData: (span?: number, parentId?: string) => {
    title: string;
    type: AttrType;
    componentName: ComponentType;
    attrs: {
        span: number;
    };
    parentId: string;
    children: never[];
    attrsJson: DragFormType[];
};
/**
 * 创建表格列数据工厂函数
 *
 * 生成 ElDragTable 组件的列配置
 * 用于动态表格的列定义
 *
 * @param span - （未使用）保留参数，未来可能扩展
 *
 * @returns DragFormType - 表格列配置对象
 *
 * @example 创建一个表格列
 * const column = ElTableColumnsData();
 * // 结果: { title: "列", type: "COMPONENT", componentName: "ElDragTableColumns", ... }
 *
 * 注意：
 * - 此函数返回的列配置是一个模板
 * - 实际使用时需要设置 prop、label 等属性
 * - 表格组件的 children 数组包含多个列配置
 */
export declare const ElTableColumnsData: (span?: number) => {
    title: string;
    type: AttrType;
    componentName: ComponentType;
    attrs: {};
    children: never[];
    attrsJson: never[];
};
export {};
