import type { ColProps } from "antd/es/col";
import type { FormItemProps, Rule } from "antd/es/form";
import type { FormListFieldData } from "antd/es/form/FormList";
import type { Gutter } from "antd/es/grid/row";
import type { NamePath } from "rc-field-form/lib/interface";
import type { CSSProperties, ReactElement, ReactNode } from "react";
import type { FORM_ITEM_RENDER_TYPE_MAP } from "../../enum/formItemRender";
import type { DeepPartial } from "./FormBuilder";

/**
 * Form.List name 类型
 */
export type FormListOptionName<Values> = [number, NamePath<Values>];

/**
 * Form.List 依赖项类型
 */
export type FormListOptionDependencies<Values> = NamePath<Values>;

/**
 * 选择项数据类型
 */
export interface OptionItem {
  /** ID字段 */
  bianma?: any;
  /** 名称字段 */
  name?: string | ReactNode;
  /** 是否禁用 */
  disabled?: boolean;
  [key: string]: any;
}

/**
 * 字段键配置
 */
export interface ItemsFieldConfig {
  /** 值字段的键名，默认 'bianma' */
  valueKey?: string;
  /** 标签字段的键名，默认 'name' */
  labelKey?: string | ((item: Record<string, any>) => ReactNode);
}

/**
 * Form.List 操作项
 */
export interface FormListOperations<Values = any> {
  /** 当前表单项的数据字段信息 */
  field: FormListFieldData;
  /** 当前项在列表中的索引位置 */
  fieldIndex: number;
  /** 新增方法 */
  add: (defaultValue?: DeepPartial<Values>, insertIndex?: number) => void;
  /** 删除方法 */
  remove: (index: number | number[]) => void;
  /** 移动方法 */
  move: (from: number, to: number) => void;
}

/**
 * Form.List 独有的属性
 */
export interface FormListUniqueProps<Values = any, AllValues = Values> {
  /** 是否显示新增按钮，默认 true */
  showAddButton?: boolean;
  /** 是否显示删除按钮，默认 true */
  showRemoveButton?: boolean;
  /** 新增按钮的文本，默认 '添加' */
  addButtonText?: string;
  /** 删除按钮的文本，默认 '删除' */
  removeButtonText?: string;
  /** 表单配置项 */
  options: (field: FormListFieldData, fieldIndex: number, operations: FormListOperations<Values>) => FormListOption<Values, AllValues>[];
  /** 点击新增按钮时的默认值 */
  addDefaultValue?: DeepPartial<Values>;
  /** 点击新增按钮时插入的索引位置 */
  addInsertIndex?: number;
}

/**
 * 条件类型辅助工具
 */
export type WhenTrue<Condition extends boolean, T> = Condition extends true ? never : T;

/**
 * 表单配置项属性类型辅助工具
 */
export type FormOptionProperty<IsOnlyForLabel extends boolean, IsCustomizeRender extends boolean, T> = WhenTrue<IsOnlyForLabel, WhenTrue<IsCustomizeRender, T>>;

/**
 * 表单配置项公共字段
 */
export interface FormOptionBase<
  Values = any,
  AllValues = Values,
  IsOnlyForLabel extends boolean = false,
  IsCustomizeRender extends boolean = false,
  Name = NamePath<Values>,
  Dependencies = NamePath<Values>,
> {
  /** React 需要的 key，如果传递了唯一的 name，则不需要 */
  key?: string;
  /** 表单项字段名 */
  name?: Name;
  /** 表单项标签 */
  label?: ReactNode;
  /** 占据栅格列数，默认 12 */
  span?: WhenTrue<IsOnlyForLabel, number>;
  /** 是否必填，默认 true，支持函数动态计算 */
  required?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, boolean | ((formValues: AllValues) => boolean)>;
  /** 验证规则 */
  rules?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, Rule | Rule[]>;
  /** 是否使用字符验证限制 */
  useConstraints?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, boolean>;
  /** 占位符文本，默认会根据传入的 render 类型自动判断（请选择、请输入）和 label 组合 */
  placeholder?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, ReactNode>;
  /** 提示信息，传入将在 label 右侧生成图标展示 tooltip */
  tip?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, ReactNode>;
  /** 是否隐藏，默认 false，支持函数动态计算 */
  hidden?: WhenTrue<IsOnlyForLabel, boolean | ((formValues: AllValues) => boolean)>;
  /** 是否自定义渲染，完全交给外部控制渲染，默认 false */
  customizeRender?: IsCustomizeRender;
  /** 传递给 Form.Item 的属性，支持函数动态计算 */
  formItemProps?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, FormItemProps | ((formValues: AllValues) => FormItemProps)>;
  /** label 栅格配置，默认直接使用外层的 labelCol，如果 span 等于 24，是外层的 labelCol.span 一半 */
  labelCol?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, ColProps>;
  /** wrapper 栅格配置，默认 24 - labelCol.span */
  wrapperCol?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, ColProps>;
  /** 是否应该更新（用于表单联动） */
  shouldUpdate?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, boolean | ((prevValues: AllValues, nextValues: AllValues, info: { source?: string }) => boolean)>;
  /** 依赖字段（用于表单联动） */
  dependencies?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, Dependencies[]>;
  /** 是否仅用于保存标签，不渲染到页面上，只在表单中保存数据，默认 false */
  onlyForLabel?: IsOnlyForLabel;
  /** Col 的内联样式，会合并到 Col 的 style 上，支持函数动态计算 */
  colStyle?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, CSSProperties | ((formValues: AllValues) => CSSProperties)>;
  /** Col 内部、Form.Item 之前渲染的标题节点，支持函数动态计算 */
  colTitle?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, ReactNode | ((formValues: AllValues) => ReactNode)>;
}

/**
 * 按 render 类型区分的表单项
 */
export type FormOptionByRender<
  RenderType extends keyof FORM_ITEM_RENDER_TYPE_MAP,
  Values = any,
  AllValues = Values,
  IsOnlyForLabel extends boolean = false,
  IsCustomizeRender extends boolean = false,
  Name = NamePath<Values>,
  Dependencies = NamePath<Values>,
> = FormOptionBase<Values, AllValues, IsOnlyForLabel, IsCustomizeRender, Name, Dependencies> & {
  /** 渲染类型（写字面量时 componentProps 会按该类型推导） */
  render: RenderType;
  /** 传递给表单控件的属性，类型由 render 决定 */
  componentProps?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, FORM_ITEM_RENDER_TYPE_MAP[RenderType] | ((formValues: AllValues) => FORM_ITEM_RENDER_TYPE_MAP[RenderType])>;
  /** 选项数据（用于 select、radio、checkbox） */
  items?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, RenderType extends "select" | "radio" | "checkbox" ? OptionItem[] : never>;
  /** 字段键配置 */
  itemsField?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, RenderType extends "select" | "radio" | "checkbox" ? ItemsFieldConfig : never>;
  /** checkbox 的栅格数量，如果不传入不使用栅格，传入才使用 */
  checkboxCol?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, RenderType extends "checkbox" ? number : never>;
  /** Form.List 独有的属性 */
  formListUniqueProps?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, RenderType extends "formList" ? FormListUniqueProps | ((formValues: AllValues) => FormListUniqueProps) : never>;
  /** FormList 每行的内联样式，仅 render 为 formList 时可用，支持函数按行计算 */
  rowStyle?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, RenderType extends "formList" ? CSSProperties | ((field: FormListFieldData, fieldIndex: number) => CSSProperties) : never>;
  /** FormList 每行起始位置渲染的标题节点，仅 render 为 formList 时可用，支持函数按行计算 */
  rowTitle?: FormOptionProperty<IsOnlyForLabel, IsCustomizeRender, RenderType extends "formList" ? ReactNode | ((field: FormListFieldData, fieldIndex: number) => ReactNode) : never>;
};

/**
 * 不写 render 或 render 为 input 时的表单项（默认按输入框）
 */
export type FormOptionDefault<
  Values = any,
  AllValues = Values,
  IsOnlyForLabel extends boolean = false,
  IsCustomizeRender extends boolean = false,
  Name = NamePath<Values>,
  Dependencies = NamePath<Values>,
> = FormOptionBase<Values, AllValues, IsOnlyForLabel, IsCustomizeRender, Name, Dependencies> & {
  /** 渲染类型，默认 input */
  render?: "input" | undefined;
  /** 传递给 Input 的属性 */
  componentProps?: FORM_ITEM_RENDER_TYPE_MAP["input"] | ((formValues: AllValues) => FORM_ITEM_RENDER_TYPE_MAP["input"]);
  /** 选项数据（用于 select、radio、checkbox），input 时不需要 */
  items?: never;
  /** 字段键配置，input 时不需要 */
  itemsField?: never;
  /** checkbox 的栅格数量，input 时不需要 */
  checkboxCol?: never;
  /** Form.List 独有的属性，input 时不需要 */
  formListUniqueProps?: never;
};

/**
 * 自定义渲染时的表单项（render 为 ReactNode 时使用）
 */
export type FormOptionCustomRender<
  Values = any,
  AllValues = Values,
  IsOnlyForLabel extends boolean = false,
  IsCustomizeRender extends boolean = false,
  Name = NamePath<Values>,
  Dependencies = NamePath<Values>,
> = FormOptionBase<Values, AllValues, IsOnlyForLabel, IsCustomizeRender, Name, Dependencies> & {
  /** 渲染类型，默认 ReactNode */
  render: ReactNode;
  /** 传递给表单控件的属性，自定义渲染时不需要 */
  componentProps?: never;
  /** 选项数据（用于 select、radio、checkbox），自定义渲染时不需要 */
  items?: never;
  /** 字段键配置，自定义渲染时不需要 */
  itemsField?: never;
  /** checkbox 的栅格数量，自定义渲染时不需要 */
  checkboxCol?: never;
  /** Form.List 独有的属性，自定义渲染时不需要 */
  formListUniqueProps?: never;
};

/**
 * 根据 render 类型映射生成表单项联合类型
 */
export type FormOptionByRenderUnion<
  Values = any,
  AllValues = Values,
  IsOnlyForLabel extends boolean = false,
  IsCustomizeRender extends boolean = false,
  Name = NamePath<Values>,
  Dependencies = NamePath<Values>,
> = { [K in keyof FORM_ITEM_RENDER_TYPE_MAP]: FormOptionByRender<K, Values, AllValues, IsOnlyForLabel, IsCustomizeRender, Name, Dependencies> }[keyof FORM_ITEM_RENDER_TYPE_MAP];

/**
 * 表单配置项联合类型组合
 */
export type FormOptionGroup<
  Values = any,
  AllValues = Values,
  Name = NamePath<Values>,
  Dependencies = NamePath<Values>,
>
  = | FormOptionDefault<Values, AllValues, false, false, Name, Dependencies>
    | FormOptionDefault<Values, AllValues, false, true, Name, Dependencies>
    | FormOptionDefault<Values, AllValues, true, false, Name, Dependencies>
    | FormOptionByRenderUnion<Values, AllValues, false, false, Name, Dependencies>
    | FormOptionByRenderUnion<Values, AllValues, false, true, Name, Dependencies>
    | FormOptionByRenderUnion<Values, AllValues, true, false, Name, Dependencies>
    | FormOptionCustomRender<Values, AllValues, false, false, Name, Dependencies>
    | FormOptionCustomRender<Values, AllValues, false, true, Name, Dependencies>
    | FormOptionCustomRender<Values, AllValues, true, false, Name, Dependencies>;

/**
 * 普通表单配置项
 */
export type FormOption<Values = any, AllValues = Values> = FormOptionGroup<Values, AllValues>;

/**
 * Form.List 子项表单配置项
 */
export type FormListOption<Values = any, AllValues = Values> = FormOptionGroup<Values, AllValues, FormListOptionName<Values>, FormListOptionDependencies<AllValues>>;

/**
 * FormItemsRenderer 组件属性
 */
export interface FormItemsRendererProps<Values = any> {
  /** 表单配置项数组 */
  options: FormOption<Values>[];
  /** 默认栅格占据列数，默认 12 */
  span?: number;
  /** 是否折叠（仅显示前3项），默认 false */
  collapse?: boolean;
  /** 自动生成必填规则，默认 true */
  useAutoGenerateRequired?: boolean;
  /** 初始值，用于在表单未初始化时提供默认值 */
  initialValues?: DeepPartial<Values>;
  /** 栅格间距，继承自 FormBuilder */
  gutter?: Gutter | [Gutter, Gutter];
  /** label 栅格配置，继承自 FormBuilder */
  labelCol?: ColProps;
}

/**
 * 表单项渲染器组件
 */
declare const FormItemsRenderer: <Values = any>(props: FormItemsRendererProps<Values>) => ReactElement;

export default FormItemsRenderer;
