import { ButtonAccess } from '@/components';
import { formLayout } from '@/utils/formLayout';
import { useIntl } from '@@/exports';
import {
	ActionType,
	DrawerForm,
	ModalForm,
	ProFormInstance,
	ProFormText,
	StepsForm,
} from '@ant-design/pro-components';
import { Drawer, Flex, message, Space } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import { BizUpdateProps } from './typing';

export default function BizCreate<
	BizVO extends Record<string, any>,
	BizUpdateCmd extends Record<string, any>,
	Func extends Record<string, any>,
>(
	props: BizUpdateProps<BizVO, BizUpdateCmd, Func> & {
		intlPrefix: string;
		actionRef?: React.MutableRefObject<ActionType | undefined>;
	},
) {
	const {
		row,
		rowId,
		rowKey,
		permission,
		intlPrefix,
		formType,
		method,
		methodUpper,
		func,
		onFinish,
		formContext,
		actionRef,
		trigger,
		isMobile = false,
		request,
		positionKey,
		transform,
	} = props;

	const [open, setOpen] = useState(false);
	const [current, setCurrent] = useState<number>(0);

	const formMapRef = useRef<
		React.MutableRefObject<ProFormInstance<any> | undefined>[]
	>([]);

	const initStepForm = async () => {
		const { data } = await func?.[`show${methodUpper}`]({
			[`${method}ShowQry`]: {
				[`${rowKey}`]: rowId,
			},
		});
		// 编辑场景下需要使用formMapRef循环设置formData
		formMapRef?.current?.forEach((formInstanceRef) => {
			formInstanceRef?.current?.setFieldsValue(data);
		});
	};

	useEffect(() => {
		if (open && formMapRef.current.length > 0) {
			initStepForm().then();
		}
	}, [open]);

	const intl = useIntl();

	let rest = {
		title: intl.formatMessage({
			id: intlPrefix + '.modal.update.title',
		}),
		autoFocusFirstInput: true,
		submitTimeout: 2000,
		open: open,
		onOpenChange: setOpen,
		request: async () => {
			const { data } = await func?.[`show${methodUpper}`]({
				[`${method}ShowQry`]: {
					[`${rowKey}`]: rowId,
				},
			});

			if (transform) {
				return (await transform?.(data)) as BizUpdateCmd;
			}

			return data as BizUpdateCmd;
		},
		onFinish: async (formData: BizUpdateCmd) => {
			// 移除 formData 里面的key名字带有VO的字段
			Object.keys(formData).forEach((key) => {
				if (key.includes('VO')) {
					delete formData[key];
				}
			});

			if (request) {
				const success = await request(formData);

				if (success) {
					message.success(
						intl.formatMessage({
							id: intlPrefix + '.modal.update.success',
						}),
					);
				}

				onFinish?.(formData as any);
			} else {
				const { success } = await func?.[`update${methodUpper}`]?.(
					formData as any,
				);

				if (success) {
					message.success(
						intl.formatMessage({
							id: intlPrefix + '.modal.update.success',
						}),
					);
				}

				onFinish?.(formData);
			}

			await actionRef?.current?.reload();

			formMapRef?.current?.forEach((formInstanceRef) => {
				formInstanceRef?.current?.resetFields();
			});

			setOpen(false);
		},
	};

	const renderForm = () => {
		if (formType === 'step') {
			return (
				<StepsForm<BizUpdateCmd>
					containerStyle={{ width: '100%', minWidth: '0px' }}
					onFinish={rest.onFinish}
					formMapRef={formMapRef}
					current={current}
					onCurrentChange={setCurrent}
					stepsFormRender={(dom, submitter) => {
						return (
							<Drawer
								width={isMobile ? '100%' : '85%'}
								title={intl.formatMessage({
									id: intlPrefix + '.modal.update.title',
								})}
								open={open}
								onClose={() => {
									setOpen(false);
									formMapRef?.current?.forEach((formInstanceRef) => {
										formInstanceRef?.current?.resetFields();
									});
								}}
								afterOpenChange={(open) => {
									if (!open) {
										setCurrent(0);
									}
								}}
								destroyOnHidden={false}
								footer={
									<Flex justify={'right'}>
										<Space>{submitter}</Space>
									</Flex>
								}
							>
								{dom}
							</Drawer>
						);
					}}
				>
					{formContext}
				</StepsForm>
			);
		}

		if (formType === 'drawer') {
			return (
				<DrawerForm<BizUpdateCmd>
					{...formLayout()}
					width={isMobile ? '100%' : '85%'}
					drawerProps={{
						destroyOnHidden: true,
					}}
					{...rest}
				>
					<ProFormText name={[`${rowKey}`]} hidden={true} />
					<ProFormText name={'storeId'} hidden={true} />
					{formContext}
				</DrawerForm>
			);
		}

		if (formType === 'modal') {
			return (
				<ModalForm<BizUpdateCmd>
					{...formLayout()}
					modalProps={{
						destroyOnHidden: true,
					}}
					{...rest}
				>
					<ProFormText name={[`${rowKey}`]} hidden={true} />
					<ProFormText name={'storeId'} hidden={true} />
					{formContext}
				</ModalForm>
			);
		}
	};

	const renderTrigger = () => {
		if (trigger) {
			return (
				<div
					onClick={() => {
						setOpen(true);
					}}
				>
					{trigger(row)}
				</div>
			);
		}

		return (
			<ButtonAccess
				permission={permission + '-update'}
				key="update"
				type="link"
				onClick={(event) => {
					setOpen(true);
					event.stopPropagation();
				}}
				positionKey={positionKey}
			>
				{intl.formatMessage({
					id: intlPrefix + '.modal.update.button',
				})}
			</ButtonAccess>
		);
	};

	return (
		<>
			{renderTrigger()}
			{renderForm()}
		</>
	);
}
