import { ProCardProps } from '@ant-design/pro-card/es/ProCard';
import {
	ActionType,
	DragTableProps,
	DrawerFormProps,
	ModalFormProps,
	PageContainerProps,
	ProColumns,
	ProDescriptionsItemProps,
	ProTableProps,
} from '@ant-design/pro-components';
import { ProListMetas, ProListProps } from '@ant-design/pro-list';
import { TourStepProps } from 'antd';
import { TabsProps } from 'antd/es/tabs';
import { Dayjs } from 'dayjs';
import React, { MutableRefObject } from 'react';

export type BizValueType =
	| 'user'
	| 'customField'
	| 'status'
	| 'remark'
	| 'order'
	| 'dealer'
	| 'supplier';
export type FormType = 'modal' | 'drawer' | 'step';
export type ModeType =
	| 'tree'
	| 'page'
	| 'drag'
	| 'list'
	| 'calender'
	| 'detail'
	| 'create'
	| 'update'
	| 'import'
	| 'destroy';

export interface ApiProps<Func extends Record<string, any>> {
	rowKey?: string;
	permission?: string;
	intlPrefix?: string;
	func?: Func;
	method?: string;
	methodUpper?: string;
	isMobile?: boolean;
}

export type BizFormType<BizCreateCmd extends Record<string, any>> =
	| ({ formType: 'modal' } & { fieldProps?: ModalFormProps<BizCreateCmd> })
	| ({ formType: 'drawer' } & { fieldProps?: DrawerFormProps<BizCreateCmd> })
	| ({ formType: 'step' } & { fieldProps?: DrawerFormProps<BizCreateCmd> });

export type BizCreateProps<
	BizVO extends Record<string, any>,
	BizCreateCmd extends Record<string, any>,
	Func extends Record<string, any>,
> = {
	formType?: FormType;
	formContext?: React.ReactNode;
	initValues?: Record<string, any>;
	onFinish?: (record: BizVO) => void;
	trigger?: () => React.ReactNode;
	showNextCreate?: boolean;
	showUserCard?: boolean;
	request?: (formData: BizCreateCmd) => Promise<boolean | undefined>;
	display?: (record?: BizVO) => boolean;
} & ApiProps<Func> &
	BizFormType<BizCreateCmd>;

export type BizImportProps<
	BizVO extends Record<string, any>,
	BizCreateCmd extends Record<string, any>,
	Func extends Record<string, any>,
> = {
	formType?: FormType;
	columns: ProColumns<BizVO, BizValueType>[];
	transformData: (record: Record<string, any>) => Promise<BizCreateCmd>;
	initValues?: Record<string, any>;
	onFinish?: () => void;
	trigger?: () => React.ReactNode;
	tips?: string;
	display?: () => boolean;
} & ApiProps<Func> &
	BizFormType<BizCreateCmd>;

export type BizUpdateProps<
	BizVO extends Record<string, any>,
	BizUpdateCmd extends Record<string, any>,
	Func extends Record<string, any>,
> = {
	rowId?: string;
	row?: BizVO;
	formType?: FormType;
	formContext?: React.ReactNode;
	initValues?: Record<string, any>;
	onFinish?: (record: BizUpdateCmd) => void;
	transform?: (record: BizVO) => Promise<Record<string, any>>;
	trigger?: (record?: BizVO) => React.ReactNode;
	request?: (formData: BizUpdateCmd) => Promise<boolean | undefined>;
	display?: (record?: BizVO) => boolean;
	positionKey?: string;
} & ApiProps<Func> &
	BizFormType<BizUpdateCmd>;

export type BizListProps<
	BizVO extends Record<string, any>,
	BizPageQry extends Record<string, any>,
	Func extends Record<string, any>,
> = {
	columns: ProColumns<BizVO, BizValueType>[];
	metas: ProListMetas<BizVO>;
	options?: (
		record: BizVO,
		actionRef: MutableRefObject<ActionType | undefined>,
	) => React.ReactNode;
	fieldProps?: ProListProps<BizVO, BizPageQry>;
	trigger?: () => React.ReactNode;
} & ApiProps<Func>;

export type BizPageProps<
	BizVO extends Record<string, any>,
	BizPageQry extends Record<string, any>,
	Func extends Record<string, any>,
> = {
	columns: ProColumns<BizVO, BizValueType>[];
	options?: (
		record: BizVO,
		actionRef: MutableRefObject<ActionType | undefined>,
	) => React.ReactNode;
	fieldProps?: ProTableProps<BizVO, BizPageQry, BizValueType>;
	trigger?: () => React.ReactNode;
} & ApiProps<Func>;

export interface BizTreeProps<
	BizVO extends Record<string, any>,
	BizPageQry extends Record<string, any>,
	Func extends Record<string, any>,
> extends ApiProps<Func> {
	columns: ProColumns<BizVO, BizValueType>[];
	options?: (
		record: BizVO,
		actionRef: MutableRefObject<ActionType | undefined>,
	) => React.ReactNode;
	fieldProps?: ProTableProps<BizVO, BizPageQry, BizValueType>;
	trigger?: () => React.ReactNode;
}

export interface BizDragProps<
	BizVO extends Record<string, any>,
	BizPageQry extends Record<string, any>,
	Func extends Record<string, any>,
> extends ApiProps<Func> {
	columns: ProColumns<BizVO, BizValueType>[];
	options?: (
		record: BizVO,
		actionRef: MutableRefObject<ActionType | undefined>,
	) => React.ReactNode;
	fieldProps?: DragTableProps<BizVO, BizPageQry>;
	trigger?: () => React.ReactNode;
	mode?: ModeType;
}

export interface BizCalenderProps<
	BizVO extends Record<string, any>,
	BizPageQry extends Record<string, any>,
	Func extends Record<string, any>,
> extends ApiProps<Func> {
	fieldProps: {
		rowKey: string;
		cardProps?: ProCardProps;
		rowName?: string;
		params?: BizPageQry;
		detailRender?: (record: BizVO, value: Dayjs) => React.ReactNode;
		actionRef?: MutableRefObject<{ reload: () => void } | undefined>;
	};
	trigger?: () => React.ReactNode;
}

export type FormContextMode = 'tab' | 'flat';

export type BizDetailProps<
	BizVO extends Record<string, any>,
	Func extends Record<string, any>,
> = {
	rowId?: string;
	row?: BizVO;
	formType: FormType;
	formContext?: (
		record: BizVO,
		onValueChange: () => void,
	) => TabsProps['items'];
	formContextMode?: FormContextMode;
	initValues?: (rowId: string) => Record<string, any>;
	onFinish?: (record: BizVO) => void;
	trigger?: (record?: BizVO) => React.ReactNode;
	display?: (record?: BizVO) => boolean;
	columns?: ProDescriptionsItemProps<BizVO, BizValueType>[];
	positionKey?: string;
	showDetail?: boolean;
} & ApiProps<Func> &
	BizFormType<BizVO>;

export interface BizDestroyProps<
	BizVO extends Record<string, any>,
	Func extends Record<string, any>,
> extends ApiProps<Func> {
	rowId?: string;
	row?: BizVO;
	onFinish?: () => void;
	display?: (record?: BizVO) => boolean;
	disable?: (record?: BizVO) => boolean;
	positionKey?: string;
}

export type RemarkProps = {
	mode?: 'textarea' | 'editor';
	ghost?: () => boolean;
};

export interface BizTourProps {
	steps?: TourStepProps[];
	expandSteps?: TourStepProps[];
}

export type BizProps<
	Func extends Record<string, any>,
	BizVO extends Record<string, any>,
	BizPageQry extends Record<string, any>,
	BizCreateCmd extends Record<string, any>,
	BizUpdateCmd extends Record<string, any>,
> = {
	rowKey: string;
	permission: string;
	func: Func;
	method: string;
	methodUpper: string;
	intlPrefix: string;

	onValueChange?: () => void;
	remark?: RemarkProps;
	status?: boolean;

	modeType: ModeType;
	container: {
		ghost?: boolean;
		fieldProps?: PageContainerProps;
	};
	tour?: false | BizTourProps;
	page?: false | BizPageProps<BizVO, BizPageQry, Func>;
	list?: false | BizListProps<BizVO, BizPageQry, Func>;
	tree?: false | BizTreeProps<BizVO, BizPageQry, Func>;
	drag?: false | BizDragProps<BizVO, BizPageQry, Func>;
	calender?: false | BizCalenderProps<BizVO, BizPageQry, Func>;
	create?: false | BizCreateProps<BizVO, BizCreateCmd, Func>;
	update?: false | BizUpdateProps<BizVO, BizUpdateCmd, Func>;
	destroy?: false | BizDestroyProps<BizVO, Func>;
	detail?: false | BizDetailProps<BizVO, Func>;
	batchImport?: false | BizImportProps<BizVO, BizCreateCmd, Func>;
};

// 定义固定位置按钮类型
export type FixedPositionKey = 'edit' | 'view' | 'delete';
export type InsertPosition =
	| `before:${FixedPositionKey}`
	| `after:${FixedPositionKey}`;
