import {
	BizContainer,
	BizValueType,
	IconPicker,
	ModeType,
	PermissionList,
} from '@/components';
import useSearch from '@/models/useSearch';
import { business } from '@/services';
import { useIntl } from '@@/exports';
import {
	ProColumns,
	ProFormColorPicker,
	ProFormDependency,
	ProFormRadio,
	ProFormSelect,
	ProFormText,
	ProFormTreeSelect,
} from '@ant-design/pro-components';
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import {
	ProFormBizSelect,
	ProFormBizSelectHandles,
} from '@chageable/components';
import { TreeSelect } from 'antd';
import React, { useEffect, useRef, useState } from 'react';

export interface IMenuListProps {
	ghost?: boolean;
	menuVO?: BusinessAPI.MenuVO;
	search?: boolean;
	mode?: ModeType;
	trigger?: () => React.ReactNode;
	onValueChange?: () => void;
}

export default function MenuList(props: IMenuListProps) {
	const {
		mode = 'drag',
		menuVO,
		ghost = false,
		search = true,
		onValueChange,
		trigger,
	} = props;
	const intl = useIntl();
	const intlPrefix = 'menu';
	const permissionRef = useRef<ProFormBizSelectHandles>(null);

	const { getPlatformList, getPermissionList } = useSearch();

	const formContext = [
		<ProFormSelect
			key={'platformId'}
			label={intl.formatMessage({
				id: intlPrefix + '.form.platformId.label',
			})}
			placeholder={intl.formatMessage({
				id: intlPrefix + '.form.platformId.placeholder',
			})}
			name={'platformId'}
			required={true}
			rules={[
				{
					required: true,
					message: intl.formatMessage({
						id: intlPrefix + '.form.platformId.required',
					}),
				},
			]}
			request={async (params) => await getPlatformList(params)}
			fieldProps={{
				fetchDataOnSearch: false,
				showSearch: true,
				autoClearSearchValue: true,
				fieldNames: {
					label: 'platformName',
					value: 'platformId',
				},
			}}
		/>,
		<ProFormSelect
			key={'type'}
			label={intl.formatMessage({
				id: intlPrefix + '.form.type.label',
			})}
			placeholder={intl.formatMessage({
				id: intlPrefix + '.form.type.placeholder',
			})}
			name={'type'}
			required={true}
			rules={[
				{
					required: true,
					message: intl.formatMessage({
						id: intlPrefix + '.form.type.required',
					}),
				},
			]}
			valueEnum={{
				MENU: intl.formatMessage({
					id: intlPrefix + '.form.type.enum.menu',
				}),
				PAGE: intl.formatMessage({
					id: intlPrefix + '.form.type.enum.page',
				}),
				BUTTON: intl.formatMessage({
					id: intlPrefix + '.form.type.enum.button',
				}),
			}}
			fieldProps={{
				fetchDataOnSearch: false,
				showSearch: true,
				autoClearSearchValue: true,
			}}
		/>,

		<ProFormDependency key={'path'} name={['type']}>
			{({ type }) => {
				if (type === 'MENU') {
					return [
						<ProFormTreeSelect
							key={'pid'}
							label={intl.formatMessage({
								id: intlPrefix + '.form.menuPid.label',
							})}
							placeholder={intl.formatMessage({
								id: intlPrefix + '.form.menuPid.placeholder',
							})}
							required={false}
							name={'pid'}
							dependencies={['platformId']}
							request={async (params) => {
								const response = await business.menu.treeMenu(params);
								return response.data || [];
							}}
							fieldProps={{
								showSearch: true,
								filterTreeNode: true,
								autoClearSearchValue: true,
								multiple: false,
								treeNodeFilterProp: 'name',
								showCheckedStrategy: TreeSelect.SHOW_ALL,
								fieldNames: {
									label: 'name',
									children: 'routes',
									value: 'menuId',
								},
								placeholder: intl.formatMessage({
									id: intlPrefix + '.form.menuPid.placeholder',
								}),
							}}
						/>,
						<ProFormText
							key={'menuName'}
							name="name"
							label={intl.formatMessage({
								id: intlPrefix + '.form.menuName.label',
							})}
							placeholder={intl.formatMessage({
								id: intlPrefix + '.form.menuName.placeholder',
							})}
							required={true}
							fieldProps={{
								showCount: true,
								maxLength: 50,
							}}
							rules={[
								{
									required: true,
									message: intl.formatMessage({
										id: intlPrefix + '.form.menuName.required',
									}),
								},
							]}
						/>,
						<ProFormText
							key={'path'}
							name="path"
							label={intl.formatMessage({
								id: intlPrefix + '.form.path.label',
							})}
							placeholder={intl.formatMessage({
								id: intlPrefix + '.form.path.placeholder',
							})}
							required={true}
							fieldProps={{
								showCount: true,
								maxLength: 100,
							}}
							rules={[
								{
									required: true,
									message: intl.formatMessage({
										id: intlPrefix + '.form.path.required',
									}),
								},
							]}
						/>,
						<ProFormText
							key={'component'}
							name={'component'}
							hidden={true}
							// initialValue={' '}
						/>,
					];
				}

				if (type === 'PAGE') {
					return [
						<ProFormTreeSelect
							key={'pid'}
							label={intl.formatMessage({
								id: intlPrefix + '.form.pagePid.label',
							})}
							placeholder={intl.formatMessage({
								id: intlPrefix + '.form.pagePid.placeholder',
							})}
							required={false}
							name={'pid'}
							dependencies={['platformId']}
							request={async (params) => {
								const response = await business.menu.treeMenu(params);
								return response.data || [];
							}}
							fieldProps={{
								showSearch: true,
								filterTreeNode: true,
								autoClearSearchValue: true,
								multiple: false,
								treeNodeFilterProp: 'name',
								showCheckedStrategy: TreeSelect.SHOW_ALL,
								fieldNames: {
									label: 'name',
									children: 'routes',
									value: 'menuId',
								},
								placeholder: intl.formatMessage({
									id: intlPrefix + '.form.pagePid.placeholder',
								}),
							}}
						/>,
						<ProFormText
							key={'pageName'}
							name="name"
							label={intl.formatMessage({
								id: intlPrefix + '.form.pageName.label',
							})}
							placeholder={intl.formatMessage({
								id: intlPrefix + '.form.pageName.placeholder',
							})}
							required={true}
							fieldProps={{
								showCount: true,
								maxLength: 50,
							}}
							rules={[
								{
									required: true,
									message: intl.formatMessage({
										id: intlPrefix + '.form.pageName.required',
									}),
								},
							]}
						/>,
						<ProFormText
							key={'path'}
							name="path"
							label={intl.formatMessage({
								id: intlPrefix + '.form.path.label',
							})}
							placeholder={intl.formatMessage({
								id: intlPrefix + '.form.path.placeholder',
							})}
							required={true}
							fieldProps={{
								showCount: true,
								maxLength: 100,
							}}
							rules={[
								{
									required: true,
									message: intl.formatMessage({
										id: intlPrefix + '.form.path.required',
									}),
								},
							]}
						/>,
						<ProFormText
							key={'component'}
							name="component"
							label={intl.formatMessage({
								id: intlPrefix + '.form.component.label',
							})}
							placeholder={intl.formatMessage({
								id: intlPrefix + '.form.component.placeholder',
							})}
							required={true}
							fieldProps={{
								showCount: true,
								maxLength: 50,
							}}
							rules={[
								{
									required: true,
									message: intl.formatMessage({
										id: intlPrefix + '.form.component.required',
									}),
								},
							]}
						/>,
					];
				}

				if (type === 'BUTTON') {
					return [
						<ProFormTreeSelect
							key={'pid'}
							label={intl.formatMessage({
								id: intlPrefix + '.form.buttonPid.label',
							})}
							placeholder={intl.formatMessage({
								id: intlPrefix + '.form.buttonPid.placeholder',
							})}
							required={false}
							name={'pid'}
							dependencies={['platformId']}
							request={async (params) => {
								const response = await business.menu.treeMenu(params);
								return response.data || [];
							}}
							fieldProps={{
								showSearch: true,
								filterTreeNode: true,
								autoClearSearchValue: true,
								multiple: false,
								treeNodeFilterProp: 'name',
								showCheckedStrategy: TreeSelect.SHOW_ALL,
								fieldNames: {
									label: 'name',
									children: 'routes',
									value: 'menuId',
								},
								placeholder: intl.formatMessage({
									id: intlPrefix + '.form.buttonPid.placeholder',
								}),
							}}
						/>,
						<ProFormText
							key={'buttonName'}
							name="name"
							label={intl.formatMessage({
								id: intlPrefix + '.form.buttonName.label',
							})}
							placeholder={intl.formatMessage({
								id: intlPrefix + '.form.buttonName.placeholder',
							})}
							required={true}
							fieldProps={{
								showCount: true,
								maxLength: 50,
							}}
							rules={[
								{
									required: true,
									message: intl.formatMessage({
										id: intlPrefix + '.form.buttonName.required',
									}),
								},
							]}
						/>,
						<ProFormText
							key={'name'}
							name={'path'}
							hidden={true}
							initialValue={' '}
						/>,
						<ProFormText
							key={'component'}
							name={'component'}
							hidden={true}
							initialValue={' '}
						/>,
					];
				}

				return [];
			}}
		</ProFormDependency>,

		<ProFormBizSelect
			key={'permissionId'}
			ref={permissionRef}
			label={intl.formatMessage({
				id: intlPrefix + '.form.permissionId.label',
			})}
			placeholder={intl.formatMessage({
				id: intlPrefix + '.form.permissionId.placeholder',
			})}
			name={'permissionId'}
			fetchOptions={async (params) =>
				await getPermissionList(params as BusinessAPI.PermissionListQry)
			}
			fieldProps={{
				fetchDataOnSearch: false,
				showSearch: true,
				autoClearSearchValue: true,
				fieldNames: {
					label: 'name',
					value: 'permissionId',
				},
			}}
			addonAfter={
				<PermissionList
					ghost={true}
					search={false}
					mode={'create'}
					onValueChange={async () => permissionRef.current?.reload()}
				/>
			}
		/>,
		<IconPicker key={'icon'} label="菜单图标" name="icon" />,
		<ProFormColorPicker
			key={'iconColor'}
			label={'图标颜色'}
			name={'iconColor'}
			allowClear
			showText={true}
			convertValue={(value: any) => {
				if (typeof value === 'string') {
					return `rgb(${value})`;
				}
				return value;
			}}
			transform={(value: any) => {
				const metaColor = value?.metaColor;
				if (!metaColor) {
					return {
						iconColor: value,
					};
				}
				return {
					iconColor: `${metaColor.r} ${metaColor.g} ${metaColor.b}`,
				};
			}}
		/>,
		<ProFormColorPicker
			key={'bgColorClass'}
			label={'图标背景颜色'}
			name={'bgColorClass'}
			allowClear
			showText={true}
			convertValue={(value: any) => {
				if (typeof value === 'string') {
					return `rgb(${value})`;
				}
				return value;
			}}
			transform={(value: any) => {
				const metaColor = value?.metaColor;
				if (!metaColor) {
					return {
						bgColorClass: value,
					};
				}
				return {
					bgColorClass: `${metaColor.r} ${metaColor.g} ${metaColor.b}`,
				};
			}}
		/>,
		<ProFormRadio.Group
			key={'hideInMenu'}
			label={intl.formatMessage({
				id: intlPrefix + '.form.hideInMenu.label',
			})}
			tooltip={intl.formatMessage({
				id: intlPrefix + '.form.hideInMenu.placeholder',
			})}
			name={'hideInMenu'}
			required={true}
			rules={[
				{
					required: true,
					message: intl.formatMessage({
						id: intlPrefix + '.form.hideInMenu.required',
					}),
				},
			]}
			options={[
				{
					label: '是',
					value: true,
				},
				{
					label: '否',
					value: false,
				},
			]}
		/>,
	];

	const columns: ProColumns<BusinessAPI.MenuVO, BizValueType>[] = [
		{
			title: intl.formatMessage({
				id: intlPrefix + '.column.name',
			}),
			dataIndex: 'name',
		},
		{
			title: intl.formatMessage({
				id: intlPrefix + '.column.path',
			}),
			dataIndex: 'path',
		},
		{
			title: intl.formatMessage({
				id: intlPrefix + '.column.type',
			}),
			dataIndex: 'type',
			valueType: 'select',
			valueEnum: {
				MENU: intl.formatMessage({
					id: intlPrefix + '.column.type.enum.menu',
				}),
				PAGE: intl.formatMessage({
					id: intlPrefix + '.column.type.enum.page',
				}),
				BUTTON: intl.formatMessage({
					id: intlPrefix + '.column.type.enum.button',
				}),
			},
		},
		{
			title: intl.formatMessage({
				id: intlPrefix + '.column.component',
			}),
			dataIndex: 'component',
			valueType: 'text',
		},
		{
			title: intl.formatMessage({
				id: intlPrefix + '.column.hideInMenu',
			}),
			dataIndex: 'hideInMenu',
			render: (text) => {
				return text ? '是' : '否';
			},
			search: false,
		},
	];

	const detailColumns: ProDescriptionsItemProps<
		BusinessAPI.MenuVO,
		BizValueType
	>[] = columns as ProDescriptionsItemProps<BusinessAPI.MenuVO, BizValueType>[];

	const [platformList, setPlatformList] = useState<BusinessAPI.PlatformVO[]>();

	const [platformId, setPlatformId] =
		useState<BusinessAPI.PlatformVO['platformId']>('');

	const initPlatform = async () => {
		const { data: platformList } = await business.platform.listPlatform({
			platformListQry: {},
		});

		setPlatformList(platformList);
		if (platformList) {
			setPlatformId(platformList[0].platformId);
		}
	};

	useEffect(() => {
		initPlatform().then();
	}, []);

	if (!platformList) {
		return;
	}

	const detailContext = (
		menuVO: BusinessAPI.MenuVO,
		onValueChange: () => void,
	) => {
		return [
			{
				label: `下级菜单`,
				key: 'childrenMenu',
				children: (
					<MenuList
						menuVO={menuVO}
						mode={'drag'}
						ghost={true}
						search={false}
						onValueChange={onValueChange}
					/>
				),
			},
		];
	};
	return (
		<BizContainer<
			typeof business.menu,
			BusinessAPI.MenuVO,
			BusinessAPI.MenuTreeQry,
			BusinessAPI.MenuCreateCmd,
			BusinessAPI.MenuUpdateCmd
		>
			rowKey={'menuId'}
			permission={'operation-menu'}
			func={business.menu}
			method={'menu'}
			methodUpper={'Menu'}
			intlPrefix={intlPrefix}
			modeType={mode}
			onValueChange={onValueChange}
			container={{
				ghost,
				fieldProps: {
					tabActiveKey: platformId,
					onTabChange: (platformId) => {
						setPlatformId(platformId as BusinessAPI.PlatformVO['platformId']);
					},
					tabList: [
						...platformList.map((platformVO) => ({
							key: platformVO.platformId,
							tab: platformVO.platformName,
						})),
					],
				},
			}}
			page={{
				fieldProps: {
					ghost,
					//@ts-ignore
					search,
					params: {
						platformId: platformId,
						...(menuVO && {
							pid: menuVO.menuId,
							platformId: menuVO.platformId,
						}),
					},
				},
				columns,
			}}
			tree={{
				fieldProps: {
					ghost,
					//@ts-ignore
					search,
					expandable: {
						childrenColumnName: 'routes',
					},
					params: {
						platformId: platformId,
						...(menuVO && {
							pid: menuVO.menuId,
							platformId: menuVO.platformId,
						}),
					},
				},
				columns,
			}}
			drag={{
				mode: 'tree',
				fieldProps: {
					ghost,
					//@ts-ignore
					search,
					params: {
						platformId: platformId,
						...(menuVO && {
							pid: menuVO.menuId,
							platformId: menuVO.platformId,
						}),
					},
				},
				columns,
			}}
			create={{
				formType: 'drawer',
				formContext,
				trigger,
				initValues: {
					platformId: platformId,
					...(menuVO && {
						pid: menuVO.menuId,
						platformId: menuVO.platformId,
					}),
				},
			}}
			update={{
				formType: 'drawer',
				formContext,
				trigger,
			}}
			destroy={{}}
			detail={{
				formType: 'drawer',
				columns: detailColumns,
				formContext: detailContext,
				trigger,
			}}
		/>
	);
}
