export interface FormDefine {
  /**
   * Todo: page
   */
  type?: 'flat'|'page'|'group',
  props?: any;
  propNestType?: 'flat'|'nest'|'array',
  items: FormDefineItem[];
}


/**
 * 表单动态属性定义
 */
export declare type IFormItemCallback<T> = {
  /**
   * 预留，暂未使用
   */
  type?: string;
  /**
   * @param model 当前表单条目的值
   * @param rawModel 整个 form 的值 （最常用，当两个关联组件距离较远时，可以从顶层的 rawModel 里获取）
   * @param parentModel 父表单元素的值 （上一级的值，只在列表场景的使用，例如列表某个元素的父级就是整个 item）
   * @param item 当前表单条目信息
   */
  callback: (model: any, rawModel: any, parentModel: any, formGlobalParams: any, item: FormDefineItem) => T;
};
export type IFormItemCallbackAdditionalProps<T> = { [P in keyof T]?: T[P]|IFormItemCallback<T[P]> }

export interface FormRulesItem {
  /**
   * 是否必填，默认false
   */
  required?: boolean;
  /**
   * 数组至少要有一个元素，且数组内的每一个元素都是唯一的。
   */
  range?: any[];
  /**
   * 内置校验规则，如这些规则无法满足需求，可以使用正则匹配或者自定义规则
   */
  format?: string;
  /**
   * 正则表达式，注意事项见下方说明
   */
  pattern?: RegExp;
  /**
   * 校验最大值(大于)
   */
  maximum?: number;
  /**
   * 校验最小值(小于)
   */
  minimum?: number;
  /**
   * 校验数据最小长度
   */
  minLength?: number;
  /**
   * 校验数据最大长度
   */
  maxLength?: number;
  /**
   * 校验失败提示信息语，可添加属性占位符，当前表格内属性都可用作占位符
   */
  errorMessage?: string;
  /**
   * 自定义校验规则
   */
  validateFunction?: (rule: any, value: any, data: any, callback: (e: any) => void) => boolean|undefined|void;
}

export interface FormDefineItem {
  /**
   * 表单项显示标签
   */
  label?: string|IFormItemCallback<string>;
  /**
   * 属性名称
   */
  name: string;
  fullName?: string;
  /**
   * 表单项组件类型
   */
  type?: string;
  /**
   * 传递给条目组件的参数。（允许动态回调）
   */
  params?: Record<string, unknown|IFormItemCallback<unknown>>|unknown;
  /**
   * 传递给FormItem组件的参数
   */
  itemParams?: any;
  /**
   * 默认值，用于默认数据生成
   */
  defaultValue?: any;
  /**
   * 当前条目的校验规则
   */
  rules?: FormRulesItem[],
  /**
   * 子条目，在对象中为对象子属性，在数组中为数组条目(单条目按单项控制，多条目按对象看待控制)
   */
  children?: FormDefine,

  //todo：联动

  /**
   * 是否显示。当为undefined时，默认显示。
   */
  show?: boolean|IFormItemCallback<boolean>|undefined,

  /**
   * 当前条目组件加载时发生事件
   * @param topModel 顶层数据对象
   * @param ref 组件实例
   * @returns 
   */
  onMounted?: (topModel: any, ref: any) => void;

  /**
   * 当前条目组件卸载时发生事件
   * @param topModel 顶层数据对象
   * @param ref 组件实例
   * @returns 
   */
  onBeforeUnMount?: (topModel: any, ref: any) => void;

  /**
   * 当前条目数据更改时发生事件
   * @param oldValue 旧值
   * @param newValue 新值
   * @param topModel 顶层数据对象
   * @param ref 组件实例
   * @returns 
   */
  onChange?: (oldValue: any, newValue: any, topModel: any, ref: any) => void;
}
export interface FormExport {
  /**
   * 初始化表单数据对象
   */
  initFormData(data: () => any): void;
  /**
   * 加载表单数据
   * @param value 表单数据
   */
  loadFormData(value?: Record<string, any>): void;
  /**
   * 提交表单
   */
  submitForm<T = Record<string, any>>(): Promise<T|null>;
  /**
   * 重置整个表单数据
   */
  resetForm(): void;
}