import { BizValueType, ButtonAccess } from '@/components';
import column from '@/utils/column';
import { formLayout } from '@/utils/formLayout';
import { useIntl } from '@@/exports';
import {
	DrawerForm,
	ModalForm,
	ProCard,
	ProDescriptions,
	ProFormDependency,
} from '@ant-design/pro-components';
import { useState } from 'react';
import { BizDetailProps } from './typing';

export default function BizDetail<
	BizVO extends Record<string, any>,
	Func extends Record<string, any>,
>(props: BizDetailProps<BizVO, Func>) {
	const {
		row,
		rowId,
		rowKey,
		permission,
		intlPrefix,
		formType,
		method,
		methodUpper,
		func,
		formContext,
		trigger,
		fieldProps,
		initValues,
		isMobile,
		columns,
		positionKey,
		showDetail = true,
	} = props;

	const [open, setOpen] = useState(false);

	const intl = useIntl();

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

			const extra = await initValues?.(rowId!);
			return {
				[`${rowKey}`]: rowId,
				[`${method}VO`]: data,
				...extra,
				isMobile,
			};
		},
	};

	const renderForm = () => {
		if (formType === 'drawer' || formType === 'step') {
			return (
				<DrawerForm<BizVO>
					{...fieldProps}
					{...formLayout(isMobile)}
					width={isMobile ? '100%' : '85%'}
					drawerProps={{
						destroyOnHidden: true,
					}}
					submitter={{
						searchConfig: {
							resetText: '关闭',
						},
						submitButtonProps: {
							style: {
								display: 'none',
							},
						},
					}}
					{...rest}
				>
					{columns && showDetail && (
						<ProFormDependency name={[`${method}VO`, 'isMobile', 'activeKey']}>
							{(data, form) => {
								return (
									<ProCard
										ghost={true}
										gutter={24}
										direction={data.isMobile ? 'column' : 'row'}
									>
										<ProCard
											bordered={true}
											headerBordered={true}
											colSpan={
												data.isMobile || formContext === undefined ? 24 : 6
											}
										>
											<ProDescriptions<BizVO, BizValueType>
												params={{ data: data[`${method}VO`] }}
												request={async (params) =>
													Promise.resolve({
														success: true,
														data: params?.data,
													})
												}
												columns={[...columns]}
												column={column(data.isMobile, formContext)}
											/>
										</ProCard>
										{formContext && (
											<ProCard
												bordered={true}
												headerBordered={true}
												colSpan={data.isMobile ? 24 : 18}
												tabs={{
													tabPosition: 'top',
													activeKey: data.activeKey,
													items: formContext?.(
														data?.[`${method}VO`],
														async () => {
															const { data } = await func?.[
																`show${methodUpper}`
															]({
																[`${method}ShowQry`]: {
																	[`${rowKey}`]: rowId,
																},
															});

															form.setFieldValue(`${method}VO`, data);
														},
													),
													onChange: (key) => {
														form.setFieldValue('activeKey', key);
													},
												}}
											/>
										)}
									</ProCard>
								);
							}}
						</ProFormDependency>
					)}
				</DrawerForm>
			);
		}

		if (formType === 'modal') {
			return (
				<ModalForm<BizVO>
					{...fieldProps}
					{...formLayout(isMobile)}
					modalProps={{
						destroyOnHidden: true,
					}}
					submitter={{
						searchConfig: {
							resetText: '关闭',
						},
						submitButtonProps: {
							style: {
								display: 'none',
							},
						},
					}}
					{...rest}
				>
					{columns && (
						<ProFormDependency name={[`${method}VO`, 'isMobile']}>
							{(data, form) => {
								return (
									<ProCard ghost={true} gutter={24} direction={'row'}>
										<ProCard
											bordered={true}
											headerBordered={true}
											colSpan={
												data.isMobile || formContext === undefined ? 24 : 6
											}
										>
											<ProDescriptions<BizVO, BizValueType>
												params={{ data: data[`${method}VO`] }}
												request={async (params) =>
													Promise.resolve({
														success: true,
														data: params?.data,
													})
												}
												columns={[...columns]}
												column={column(data.isMobile, formContext)}
											/>
										</ProCard>
										{formContext && (
											<ProCard
												bordered={true}
												headerBordered={true}
												colSpan={data.isMobile ? 24 : 18}
												tabs={{
													tabPosition: 'top',
													activeKey: data.activeKey,
													items: formContext?.(
														data?.[`${method}VO`],
														async () => {
															const { data } = await func?.[
																`show${methodUpper}`
															]({
																[`${method}ShowQry`]: {
																	[`${rowKey}`]: rowId,
																},
															});

															form.setFieldValue(`${method}VO`, data);
														},
													),
													onChange: (key) => {
														form.setFieldValue('activeKey', key);
													},
												}}
											/>
										)}
									</ProCard>
								);
							}}
						</ProFormDependency>
					)}
				</ModalForm>
			);
		}
	};

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

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

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