import { TAny, TPlainObject } from '@flatbiz/utils';
import { FormItemProps, FormListFieldData, FormListOperation, FormProps } from 'antd';
import { FormListProps } from 'antd/es/form/FormList.js';
import { CSSProperties, ReactElement, ReactNode } from 'react';

declare const PresetDefaultGrid: {
	xs: number;
	sm: number;
	md: number;
	lg: number;
	xl: number;
	xxl: number;
};
export type TBoxBreakpoint = "xs" | "sm" | "md" | "lg" | "xl" | "xxl";
export type Gutter = number | undefined | Partial<Record<TBoxBreakpoint, number>>;
export type GutterParams = Gutter | [
	Gutter,
	Gutter
];
export interface BoxRowProps {
	/**
	 * 在不同响应尺寸下的元素占位格数
	 * 应用到所有Col子元素上
	 */
	defaultGrid?: Partial<typeof PresetDefaultGrid>;
	/** 间距 */
	gutter?: GutterParams;
	/** flex 布局的垂直对齐方式 */
	align?: "top" | "middle" | "bottom" | "stretch";
	/** flex 布局的水平排列方式 */
	justify?: "start" | "end" | "center" | "space-around" | "space-between" | "space-evenly";
	/** 尺寸变化回调 */
	onBoxBreakpointChange?: (breakpoint: TBoxBreakpoint) => void;
}
export type TFormLayoutPreClassNameProps = {
	/**
	 * label宽度，Form内部所有FormItem label都生效
	 * ```
	 * 1. 可设置数值
	 * 2. 可设置`auto`自适应
	 * ```
	 */
	labelWidth?: "auto" | "70" | "80" | "90" | "100" | "110" | "120" | "130" | "140" | "150" | "160" | "170" | "180" | "190" | "200";
	/** labelItem 竖直布局 */
	labelItemVertical?: boolean;
	/** label 对齐方式 */
	labelAlign?: "left" | "right";
	/** formItem之间竖直间距，默认值：24 */
	formItemGap?: "24" | "15" | "8" | "5" | "0";
	/**
	 * className 中可能会包含 preDefinedClassName.form.xx，优先级大于 labelWidth、labelItemVertical、labelAlign、formItemGap
	 */
	className?: string;
};
export type TFormItemLayoutPreClassNameProps = {
	/**
	 * label宽度，Form内部所有FormItem label都生效
	 * ```
	 * 1. 可设置数值
	 * 2. 可设置`auto`自适应
	 * ```
	 */
	labelWidth?: "auto" | "70" | "80" | "90" | "100" | "110" | "120" | "130" | "140" | "150" | "160" | "170" | "180" | "190" | "200";
	/** labelItem 竖直布局 */
	labelItemVertical?: boolean;
	/** label 对齐方式 */
	labelAlign?: "left" | "right";
	/**
	 * className 中可能会包含 preDefinedClassName.formItem.xx，优先级大于 labelWidth、labelItemVertical、labelAlign
	 */
	className?: string;
};
export type FormWrapperProps<Values = any> = TFormLayoutPreClassNameProps & FormProps<Values> & {
	children: ReactNode;
};
export type EasyFormProps = Omit<FormWrapperProps, "children"> & {
	/**
	 * 定义一行显示几列（当外层宽度尺寸大于 992px（lg） 时，一行显示几列）, 默认值：3
	 * ```
	 * 1. 当外层宽度尺寸小于992px（lg），为xs、sm、md情况下不受column值影响（column=1除外）
	 * 2. 宽度尺寸定义
	 *    xs: 宽度 < 576px
	 *    sm: 宽度 ≥ 576px
	 *    md: 宽度 ≥ 768px
	 *    lg: 宽度 ≥ 992px
	 *    xl: 宽度 ≥ 1200px
	 *    xxl: 宽度 ≥ 1600px
	 * 3. 列数尺寸定义
	 *  {
	 *    1: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 },
	 *    2: { xs: 24, sm: 12, md: 12, lg: 12, xl: 12, xxl: 12 },
	 *    3: { xs: 24, sm: 12, md: 12, lg: 8, xl: 8, xxl: 8 },
	 *    4: { xs: 24, sm: 12, md: 12, lg: 6, xl: 6, xxl: 6 },
	 *  };
	 * ```
	 */
	column?: 1 | 2 | 3 | 4;
	/**
	 * 强制定义一行显示几列，不考虑响应式
	 * ```
	 * 1. 优先级大于column
	 * 2. 建议优先使用column配置
	 * ```
	 */
	forceColumn?: 1 | 2 | 3 | 4;
	/**
	 * Form显示宽度，可数值、可百分比；在小屏幕尺寸（xs、sm）上无效
	 */
	width?: number | string;
	/** 网格间距 */
	gridGutter?: BoxRowProps["gutter"];
	children: ReactNode;
	/**
	 * 是否为纯净模式，对EasyForm的子节点不做任何包装处理
	 */
	isPure?: boolean;
	/**
	 * true: 当前EasyForm组件不使用Antd Form包裹，可在Form、EasyForm、FormWrapper内部使用
	 */
	nonuseFormWrapper?: boolean;
	/**
	 * 栅格占位格数，最大值：24
	 * ```
	 * 1. 当前EasyForm处在 EasyForm 直接子节点中有效，即当前EasyForm在EasyForm栅格中的占位格数；
	 * 2. 父节点使用属性值，当前节点不使用属性值
	 * ```
	 */
	span?: number;
};
export type FormItemWrapperProps = Omit<FormItemProps, "hidden" | "children" | "noStyle"> & TFormItemLayoutPreClassNameProps & {
	wrapper?: (children: ReactNode) => ReactElement;
	/** 设置wrapper后，before、after失效 */
	before?: ReactNode;
	/** 设置wrapper后，before、after失效 */
	after?: ReactNode;
	/** 设置 before、after 属性的包装结构style */
	beforeAfterStyle?: CSSProperties;
	/** value 序列化处理 */
	inputNormalize?: (value?: TAny) => TAny;
	/**
	 * onChange 参数序列化处理
	 * 如果设置 normalize 属性，outputNormalize将失效
	 */
	outputNormalize?: (value?: TAny) => TAny;
	/**
	 * 隐藏 Form.Item，同时清除 Form.Item 值
	 * ```
	 * 1.与 dependencies 属性配合使用，可实现当前FormItemWrapper的显示隐藏
	 * 2.提交不校验rules
	 * ```
	 */
	isClear?: boolean | ((formValues: TPlainObject) => boolean);
	/**
	 * 隐藏 Form.Item，不会清除 Form.Item 值
	 * ```
	 * 1.与 dependencies 属性配合使用，可实现当前FormItemWrapper的显示隐藏
	 * 2.提交会校验rules
	 * ```
	 */
	hidden?: boolean | ((formValues: TPlainObject) => boolean);
	/**
	 * 栅格占位格数，最大值：24
	 * ```
	 * 1. 当前FormItemWrapper处在 EasyForm 直接子节点中有效，即FormItemWrapper在EasyForm栅格中的占位格数；
	 * 2. 父节点使用属性值，当前节点不使用属性值
	 * ```
	 */
	span?: number;
	/** 不支持函数式写法，如果需要使用dependencies获取表单值，可使用FormItemWrapperDependencies 组件  */
	children?: ReactNode;
	/**
	 * ```
	 * 1. 设置noStyle后，可能会导致 FromItemWrapper 在 EasyFrom 内部渲染网格布局时出现异常
	 * 2. 在FormItemWrapper中使用 dependencies 逻辑不需要设置 noStyle
	 * ```
	 */
	noStyle?: boolean;
};
export type EditableCardDataIndex = string | string[];
export interface EditableCardOperation {
	index: number;
	add: (defaultValue: TPlainObject, insertIndex?: number) => void;
	remove: (index: number) => void;
	/** 同一级内移动 */
	move: (fromIndex: number, toIndex: number) => void;
	/** 是否可编辑 */
	editable: boolean;
	/**
	 * 设置当前卡片指定字段值
	 */
	setCurrentRowField: (dataIndexConfigs: {
		name: EditableCardDataIndex;
		value?: TAny;
	}[]) => void;
	/** 获取当前卡片表单数据 */
	getCurrentRowData: () => TPlainObject;
	/**
	 * 当前卡片表单 name
	 * ```
	 * 值为 field.name
	 * ```
	 */
	rowFormItemName: string | number;
	/**
	 * 当前卡片表单完整 name
	 * ```
	 * 例如：['dataList', 0]
	 * ```
	 */
	rowFormItemCompleteName: Array<string | number>;
	/** 当前卡片表单验证，需要自行指定nameList（dataIndex数组） */
	validateRowFields: (nameList: EditableCardDataIndex[]) => Promise<void>;
	forceUpdate: () => void;
}
/** 卡片内字段配置 */
export type EditableCardColumnItem = {
	/**
	 * 字段key值
	 * ```
	 * 例如：
	 * dataIndex： 'abc'
	 * dataIndex： ['abc', 'xyz']
	 * ```
	 */
	dataIndex: EditableCardDataIndex;
	/** 是否可编辑 */
	editable: boolean | ((operation: Pick<EditableCardOperation, "index" | "getCurrentRowData">, index: number) => boolean);
	/**
	 * 布局占用网格数目（最大数值24）
	 * ```
	 * 1. 一行总共等分24份
	 * ```
	 */
	gridNumber?: number;
	/** 标题 */
	title?: ReactElement | string;
	/**
	 * Form.Item props
	 */
	formItemProps?: Omit<FormItemWrapperProps, "children" | "name"> | ((operation: EditableCardOperation) => Omit<FormItemWrapperProps, "children" | "name">);
	/**
	 * 通过 operation.editable 来判断渲染结构，其中render返回的根节点会作为 Form.Item 的children
	 * ```
	 *  例如
	 *  render: (operation) => {
	 *    if (operation.editable) {
	 *      return <Input placeholder="请输入" />;
	 *    }
	 *    return <Tag>{value}</Tag>;
	 *  }
	 *
	 *  如果需要额外布局，可通过 formItemProps.wrapper 实现
	 *  formItemProps: (operation) => {
	 *    return {
	 *      wrapper: (children) => {
	 *        return (
	 *          <FlexLayout fullIndex={[0]} direction="horizontal" gap={10}>
	 *            <div>{children}</div>
	 *            <div>额外布局</div>
	 *          </FlexLayout>
	 *        );
	 *      },
	 *    };
	 *  },
	 *  render: (operation) => {
	 *    if (operation.editable) {
	 *      return <Input placeholder="请输入" />;
	 *    }
	 *    return <Tag>{value}</Tag>;
	 *  }
	 * ```
	 */
	render?: (operation: EditableCardOperation) => ReactElement;
	/**
	 * 会在 title 之后展示一个 icon
	 */
	tips?: string;
	/** 为表格header中的字段添加必填标识，如果未配置 formItemProps.rules，内部会新增一条required rule  */
	required?: boolean;
	/**
	 * 隐藏域设置
	 * ```
	 * 如果是动态隐藏，并且在逻辑切换后无效果，可尝试执行 operation.forceUpdate()
	 * ```
	 */
	hidden?: (operation: EditableCardOperation, index: number) => boolean;
	/** 移除设置，优先级高于 hidden */
	remove?: (operation: EditableCardOperation, index: number) => boolean;
	formItemContainer?: (formItem: ReactElement) => ReactElement | null;
};
export type EditableCardProps = {
	className?: string;
	style?: CSSProperties;
	/** 卡片内字段配置 */
	columns: EditableCardColumnItem[];
	/**
	 * 当前Edittable处在formList内部时（必填），完整formItem的name
	 * ```
	 * 例如 处在formList内部
	 * 1. formListName=[0,dataList]
	 * 2. formListCompleteName=[xxxList, 0, dataList]
	 * ```
	 */
	formListCompleteName?: Array<string | number>;
	/** Form.List name */
	formListName: Array<string | number> | string;
	/** 初始化值 */
	initialValue?: TPlainObject[];
	/**
	 * Form.List rules
	 * ```
	 rules={[
		{
		  validator: async (_, names) => {
			if (!names || names.length < 2) {
			  return Promise.reject(new Error('At least 2 passengers'));
			}
		  },
		},
	  ]}
	 * ```
	 */
	rules?: FormListProps["rules"];
	/**`默认新增按钮`新增行默认值，hiddenFooterBtn != true 有效 */
	addRowDefaultValues?: () => TPlainObject;
	/** 自定义新增按钮名称 */
	addRowBtnName?: ReactNode;
	/** 隐藏底部`新增`按钮 */
	hiddenFooterBtn?: boolean;
	/** 隐藏默认删除按钮 */
	hiddenDeleteBtn?: boolean;
	/** 顶部区域渲染 */
	contentBeforeRender?: (formListOperation: FormListOperation, nextRowIndex: number) => ReactElement | null;
	/** 底部区域渲染 */
	contentAfterRender?: (formListOperation: FormListOperation, nextRowIndex: number) => ReactElement | null;
	/** 设置默认卡片名称，设置 onCustomWrapper 后失效 */
	onCustomGroupName?: (index: number) => string | ReactElement;
	/** 自定义卡片包裹，同时可自定义删除按钮、新增按钮 */
	onCustomWrapper?: (children: ReactElement, extraData: {
		operation: FormListOperation;
		fields: FormListFieldData[];
		fieldItem: FormListFieldData;
		index: number;
		required?: boolean;
		key: string;
	}) => ReactElement;
	/** 设置必填，但只有一条数据时，隐藏默认删除按钮 */
	required?: boolean;
	/** 默认卡片样式 */
	cardClassName?: string;
	/** 默认卡片样式 */
	cardStyle?: CSSProperties;
	/**
	 * 每个卡片内容都使用了 EasyForm 包裹，此处可设置 EasyFormProps
	 * ```
	 * 可使用 EasyForm 中 FormItem布局
	 * ```
	 */
	cardEasyFormProps?: Omit<EasyFormProps, "nonuseFormWrapper" | "isPure" | "children">;
	/**
	 * 默认卡片右侧布局，设置 onCustomWrapper 后失效
	 * ```
	 * 1. 通过before 、after自定义删除按钮左右布局
	 * cardExtraRender={(extraData)=>{
	 *   return {
	 *      before: [<div>1</div>, <div>2</div>],
	 *      after: [<div>3</div>, <div>4</div>],
	 *    }
	 *  }}
	 * 2. 返回ReactElement，可自定义右侧布局
	 * cardExtraRender={(extraData)=>{
	 *   return <div>111</div>
	 *  }}
	 * ```
	 */
	cardExtraRender?: (extraData: {
		operation: FormListOperation;
		fields: FormListFieldData[];
		fieldItem: FormListFieldData;
		index: number;
		required?: boolean;
		key: string;
	}) => {
		before?: ReactElement[];
		after?: ReactElement[];
	} | ReactElement;
};
/**
 * 使用FormList实现可编辑卡片
 * ```
 * 1. 必须在外部包裹Form组件或者EasyForm组件
 * 2. 行内需要联动逻辑可使用 column.render.operation.setCurrentRowField 方法
 * 3. 可使用DragEditableCard组件实现拖拽排序
 *
 * demo
 * https://fex.qa.tcshuke.com/docs/admin/main/form/grid
 * ```
 */
export declare const EditableCard: (props: EditableCardProps) => import("react").JSX.Element;

export {};
