import {
	BizContainer,
	BizDragDrop,
	BizValueType,
	CostList,
	ModeType,
} from '@/components';
import { business } from '@/services';
import groupby from '@/utils/groupby';
import { useIntl } from '@@/exports';
import {
	ProColumns,
	ProFormDependency,
	ProFormText,
} from '@ant-design/pro-components';
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import {
	ProFormBizSelect,
	ProFormBizSelectHandles,
} from '@chageable/components';
import { Space, Typography } from 'antd';
import React, { useRef } from 'react';

interface IProductDataListProps {
	ghost?: boolean;
	id?: BusinessAPI.ProductVO['productId'];
	search?: boolean;
	onValueChange?: () => void;
	mode?: ModeType;
	trigger?: () => React.ReactNode;
}

export default function ProductDataList(props: IProductDataListProps) {
	const {
		ghost = false,
		id,
		search = true,
		mode = 'drag',
		trigger,
		onValueChange,
	} = props;

	const intl = useIntl();
	const intlPrefix = 'productData';
	const costRef = useRef<ProFormBizSelectHandles>(null);

	const columns: ProColumns<BusinessAPI.ProductVO, BizValueType>[] = [
		{
			title: intl.formatMessage({ id: intlPrefix + '.column.name' }),
			dataIndex: 'name',
			key: 'name',
			renderText: (text: string) => <span className="font-medium">{text}</span>,
		},
		{
			title: intl.formatMessage({
				id: intlPrefix + '.column.costIds',
			}),
			dataIndex: 'costTemplate',
			key: 'costIds',
			valueType: 'text',
			render: (_, record) => {
				const group = groupby(record.costVOList || [], (item) => item.type);
				return Object.keys(group).map((key) => {
					const costGroup = group[key];
					return (
						<div key={key}>
							<Space>
								<Typography.Text>
									{intl.formatMessage({
										id:
											'cost.column.type.enum.' +
											key
												.toLowerCase()
												.replace(/_([a-z])/g, (_, char) => char.toUpperCase()),
									})}
								</Typography.Text>
								<Typography.Text type={'secondary'}>
									{costGroup.map((item) => item.name).join('、')}
								</Typography.Text>
							</Space>
						</div>
					);
				});
			},
		},
	];

	const formContext = [
		<ProFormText
			key="name"
			name="name"
			label={intl.formatMessage({ id: intlPrefix + '.form.name.label' })}
			placeholder={intl.formatMessage({
				id: intlPrefix + '.form.name.placeholder',
			})}
			rules={[
				{
					required: true,
					message: intl.formatMessage({
						id: intlPrefix + '.form.name.required',
					}),
				},
			]}
		/>,
		<ProFormDependency
			key={'costIds'}
			name={[
				'costIds',
				'costVOList',
				'productionTypeList',
				'materialTypeList',
				'artificialTypeList',
			]}
		>
			{(
				{
					costVOList,
					productionTypeList,
					materialTypeList,
					artificialTypeList,
				},
				form,
			) => {
				return (
					<>
						<ProFormText name={'costVOList'} hidden={true} />
						<ProFormText name={'costTemplate'} hidden={true} />
						<ProFormBizSelect
							ref={costRef}
							name={'costIds'}
							label={intl.formatMessage({
								id: intlPrefix + '.form.costIds.label',
							})}
							required={true}
							placeholder={intl.formatMessage({
								id: intlPrefix + '.form.costIds.placeholder',
							})}
							rules={[
								{
									required: true,
									message: intl.formatMessage({
										id: intlPrefix + '.form.costIds.required',
									}),
								},
							]}
							params={{}}
							fetchOptions={async () => {
								const { data } = await business.cost.listCost({
									costListQry: {},
								});

								form.setFieldValue('costVOList', data);

								const costGroup = groupby(data || [], (item) => item.type);

								const options = Object.keys(costGroup).map((key) => ({
									label: intl.formatMessage({
										id:
											'cost.column.type.enum.' +
											key
												.toLowerCase()
												.replace(/_([a-z])/g, (_, char) => char.toUpperCase()),
									}),
									title: key,
									options: costGroup[key].map((item) => ({
										label: item.name,
										value: item.costId,
									})),
								}));

								return options || [];
							}}
							fieldProps={{
								mode: 'multiple',
								fetchDataOnSearch: false,
								showSearch: true,
								autoClearSearchValue: true,
							}}
							onChange={(value) => {
								const productionTypeList = costVOList
									.filter(
										(item: BusinessAPI.CostVO) =>
											value.includes(item.costId) &&
											item.type === 'PRODUCTION_TYPE',
									)
									.map((item: BusinessAPI.CostVO) => {
										return {
											costId: item.costId,
											name: item.name,
											type: item.type,
											price: item.price,
											unit: item.unit,
											belong: item.belong,
										};
									});

								form.setFieldValue('productionTypeList', productionTypeList);

								const materialTypeList = costVOList
									.filter((item: BusinessAPI.CostVO) =>
										value.includes(item.costId),
									)
									.map((item: BusinessAPI.CostVO) => item.costItemVOList)
									.flat()
									.filter(
										(item: BusinessAPI.CostItemVO) =>
											item && item.type === 'MATERIAL_TYPE',
									)
									.filter(
										(item: BusinessAPI.CostItemVO, index: number, self: any) =>
											index ===
											self.findIndex(
												(t: any) => t.costItemId === item.costItemId,
											),
									)
									.map((item: BusinessAPI.CostItemVO) => ({
										costItemId: item.costItemId,
										name: item.name,
										type: item.type,
										price: item.price,
										unit: item.unit,
										rule: item.rule,
									}));
								form.setFieldValue('materialTypeList', materialTypeList);

								const artificialTypeList = costVOList
									.filter((item: BusinessAPI.CostVO) =>
										value.includes(item.costId),
									)
									.map((item: BusinessAPI.CostVO) => item.costItemVOList)
									.flat()
									.filter(
										(item: BusinessAPI.CostItemVO) =>
											item && item.type === 'ARTIFICIAL_TYPE',
									)
									.filter(
										(item: BusinessAPI.CostItemVO, index: number, self: any) =>
											index ===
											self.findIndex(
												(t: any) => t.costItemId === item.costItemId,
											),
									)
									.map((item: BusinessAPI.CostItemVO) => ({
										costItemId: item.costItemId,
										name: item.name,
										type: item.type,
										price: item.price,
										unit: item.unit,
										rule: item.rule,
									}));
								form.setFieldValue('artificialTypeList', artificialTypeList);

								// 将三个列表字段存储到costTemplate中
								const templateData = {
									productionTypeList,
									materialTypeList,
									artificialTypeList,
								};
								form.setFieldValue(
									'costTemplate',
									JSON.stringify(templateData),
								);
							}}
							addonAfter={
								<CostList
									ghost={true}
									search={false}
									mode={'create'}
									onValueChange={async () => costRef.current?.reload()}
								/>
							}
						/>

						{productionTypeList && (
							<BizDragDrop<BusinessAPI.CostVO>
								fieldProps={{
									label: intl.formatMessage({
										id: intlPrefix + '.form.productionTypeList.label',
									}),
								}}
								droppableId={'PRODUCTION_TYPE'}
								rowKey={'costId'}
								value={productionTypeList || []}
								name="productionTypeList"
								onChange={(updatedList) => {
									console.log('productionTypeList', updatedList);
									// 更新时同时更新costTemplate
									const templateData = {
										productionTypeList: updatedList,
										materialTypeList:
											form.getFieldValue('materialTypeList') || [],
										artificialTypeList:
											form.getFieldValue('artificialTypeList') || [],
									};
									form.setFieldValue(
										'costTemplate',
										JSON.stringify(templateData),
									);
								}}
								render={(item: BusinessAPI.CostVO) => {
									return (
										<>
											<Typography.Text strong>{item.name}</Typography.Text>
											{item.unit && item.price !== undefined && (
												<Typography.Text type="secondary">
													({item.unit}: ¥{item.price})
												</Typography.Text>
											)}
										</>
									);
								}}
							/>
						)}

						{materialTypeList && (
							<BizDragDrop<BusinessAPI.CostItemVO>
								fieldProps={{
									label: intl.formatMessage({
										id: intlPrefix + '.form.materialTypeList.label',
									}),
								}}
								droppableId={'MATERIAL_TYPE'}
								rowKey={'costItemId'}
								value={materialTypeList || []}
								name="materialTypeList"
								onChange={(updatedList) => {
									console.log('materialTypeList', updatedList);
									// 更新时同时更新costTemplate
									const templateData = {
										productionTypeList:
											form.getFieldValue('productionTypeList') || [],
										materialTypeList: updatedList,
										artificialTypeList:
											form.getFieldValue('artificialTypeList') || [],
									};
									form.setFieldValue(
										'costTemplate',
										JSON.stringify(templateData),
									);
								}}
								render={(item: BusinessAPI.CostItemVO) => {
									return (
										<>
											<Typography.Text strong>{item.name}</Typography.Text>
											{item.unit && item.price !== undefined && (
												<Typography.Text type="secondary">
													({item.unit}: ¥{item.price})
												</Typography.Text>
											)}
										</>
									);
								}}
							/>
						)}

						{artificialTypeList && (
							<BizDragDrop<BusinessAPI.CostItemVO>
								fieldProps={{
									label: intl.formatMessage({
										id: intlPrefix + '.form.artificialTypeList.label',
									}),
								}}
								droppableId={'ARTIFICIAL_TYPE'}
								rowKey={'costItemId'}
								value={artificialTypeList || []}
								name="artificialTypeList"
								onChange={(updatedList) => {
									console.log('artificialTypeList', updatedList);
									// 更新时同时更新costTemplate
									const templateData = {
										productionTypeList:
											form.getFieldValue('productionTypeList') || [],
										materialTypeList:
											form.getFieldValue('materialTypeList') || [],
										artificialTypeList: updatedList,
									};
									form.setFieldValue(
										'costTemplate',
										JSON.stringify(templateData),
									);
								}}
								render={(item: BusinessAPI.CostItemVO) => {
									return (
										<>
											<Typography.Text strong>{item.name}</Typography.Text>
											{item.unit && item.price !== undefined && (
												<Typography.Text type="secondary">
													({item.unit}: ¥{item.price})
												</Typography.Text>
											)}
										</>
									);
								}}
							/>
						)}
					</>
				);
			}}
		</ProFormDependency>,
	];

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

	return (
		<BizContainer<
			typeof business.product,
			BusinessAPI.ProductVO,
			BusinessAPI.ProductPageQry,
			BusinessAPI.ProductCreateCmd,
			BusinessAPI.ProductUpdateCmd
		>
			rowKey={'productId'}
			permission={'operation-product-data'}
			func={business.product}
			method={'product'}
			methodUpper={'Product'}
			intlPrefix={intlPrefix}
			modeType={mode}
			onValueChange={onValueChange}
			container={{}}
			remark={{
				mode: 'editor',
			}}
			status
			drag={{
				fieldProps: {
					bordered: true,
					ghost,
					//@ts-ignore
					search,
					params: {
						// 这里可以添加特定的查询参数
					},
				},
				columns,
			}}
			create={{
				formType: 'drawer',
				formContext,
				initValues: {
					status: true,
					sort: 0,
				},
			}}
			update={{
				formType: 'drawer',
				formContext,
				transform: async (data) => {
					return {
						...data,
						...JSON.parse(data.costTemplate || '{}'),
					};
				},
			}}
			destroy={{}}
			detail={{
				rowId: id,
				formType: 'drawer',
				columns: detailColumns,
				trigger,
			}}
		/>
	);
}
