import {
	BizContainer,
	BizValueType,
	MaterialCategoryList,
	ModeType,
	ProFormBizTreeSelect,
	ProFormBizTreeSelectHandles,
	ProFormUploadOss,
	Remark,
} from '@/components';
import { business } from '@/services';
import { useIntl } from '@@/exports';
import {
	ProColumns,
	ProFormDependency,
	ProFormRadio,
} from '@ant-design/pro-components';
import { useModel } from '@umijs/max';
import { TreeSelect } from 'antd';
import moment from 'moment';
import React, { useRef, useState } from 'react';
import { v4 as uuidv4 } from 'uuid';

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

export default function MaterialList(props: IMaterialListProps) {
	const {
		mode = 'page',
		ghost = false,
		search = true,
		onValueChange,
		trigger,
	} = props;
	const intl = useIntl();
	const intlPrefix = 'material';
	const actionBizRef = useRef<ProFormBizTreeSelectHandles>(null);

	const { getOssToken } = useModel('useOssToken', (model) => ({
		getOssToken: model.getOssToken,
	}));
	const [type, setType] = useState<BusinessAPI.MaterialVO['type']>();

	const formContext = [
		<ProFormDependency key={'categoryId'} name={['type']}>
			{({ type: formType }, form) => {
				if (formType !== type) {
					setType(formType);
				}
				return (
					<>
						<ProFormRadio.Group
							label={intl.formatMessage({
								id: intlPrefix + '.form.type.label',
							})}
							name={'type'}
							required={true}
							fieldProps={{
								onChange: () => {
									form.setFieldValue('categoryId', undefined);
									form.setFieldValue('path', undefined);
								},
							}}
							options={[
								{
									label: intl.formatMessage({
										id: intlPrefix + '.form.type.enum.image',
									}),
									value: 'FILE_IMAGE',
								},
								{
									label: intl.formatMessage({
										id: intlPrefix + '.form.type.enum.video',
									}),
									value: 'FILE_VIDEO',
								},
							]}
							rules={[
								{
									required: true,
									message: intl.formatMessage({
										id: intlPrefix + '.form.type.required',
									}),
								},
							]}
						/>
					</>
				);
			}}
		</ProFormDependency>,
		<ProFormBizTreeSelect
			ref={actionBizRef}
			key={'categoryId'}
			label={intl.formatMessage({
				id: intlPrefix + '.form.categoryId.label',
			})}
			required={true}
			name={'categoryId'}
			placeholder={intl.formatMessage({
				id: intlPrefix + '.form.categoryId.placeholder',
			})}
			params={{ type }}
			fetchOptions={async (params) => {
				const { data } = await business.materialCategory.treeMaterialCategory({
					categoryTreeQry: {
						...params,
					},
				});
				return data || [];
			}}
			rules={[
				{
					required: true,
					message: intl.formatMessage({
						id: intlPrefix + '.form.categoryId.required',
					}),
				},
			]}
			fieldProps={{
				suffixIcon: null,
				showSearch: true,
				allowClear: true,
				autoClearSearchValue: true,
				filterTreeNode: true,
				multiple: false,
				treeNodeFilterProp: 'name',
				showCheckedStrategy: TreeSelect.SHOW_ALL,
				fieldNames: {
					label: 'name',
					children: 'children',
					value: 'categoryId',
				},
			}}
			addonAfter={
				<MaterialCategoryList
					ghost={true}
					type={type}
					mode={'create'}
					search={search}
					onValueChange={() => actionBizRef.current?.reload()}
				/>
			}
		/>,
		<ProFormDependency key={'path'} name={['type']}>
			{({ type }) => {
				switch (type) {
					case 'FILE_IMAGE':
					case 'FILE_VIDEO':
						return (
							<ProFormUploadOss
								//@ts-ignore
								label={intl.formatMessage({
									id: intlPrefix + '.form.path.label',
								})}
								required={true}
								placeholder={intl.formatMessage({
									id: intlPrefix + '.form.path.placeholder',
								})}
								rules={[
									{
										required: true,
										message: intl.formatMessage({
											id: intlPrefix + '.form.path.required',
										}),
									},
								]}
								key={'file'}
							/>
						);
				}
			}}
		</ProFormDependency>,
	];

	const columns: ProColumns<BusinessAPI.MaterialVO, BizValueType>[] = [
		{
			title: intl.formatMessage({ id: intlPrefix + '.column.name' }),
			dataIndex: 'name',
			order: 3,
		},
		{
			title: intl.formatMessage({ id: intlPrefix + '.column.url' }),
			dataIndex: 'url',
			search: false,
			render: (_, record) => {
				return record.type === 'FILE_IMAGE' || record.type === 'FILE_VIDEO' ? (
					// 可预览
					<a
						href={record.url}
						target="_blank"
						rel="noopener noreferrer"
						style={{
							display: 'inline-block',
							width: 22,
							height: 22,
							overflow: 'hidden',
						}}
					>
						<img
							src={record.url}
							alt={record.name}
							style={{ width: 22, height: 22 }}
						/>
					</a>
				) : (
					<Remark remark={record.path} />
				);
			},
		},
		{
			title: intl.formatMessage({ id: intlPrefix + '.column.type' }),
			dataIndex: 'type',
			valueType: 'select',
			valueEnum: {
				FILE_IMAGE: {
					text: intl.formatMessage({
						id: intlPrefix + '.column.type.enum.image',
					}),
				},
				FILE_VIDEO: {
					text: intl.formatMessage({
						id: intlPrefix + '.column.type.enum.video',
					}),
				},
			},
			fieldProps: {
				showSearch: true,
				allowClear: true,
				autoClearSearchValue: true,
			},
			order: 2,
		},
		{
			title: intl.formatMessage({ id: intlPrefix + '.column.category' }),
			dataIndex: 'categoryId',
			valueType: 'treeSelect',
			request: async (params) => {
				const { data } = await business.materialCategory.treeMaterialCategory({
					categoryTreeQry: {
						...params,
					},
				});
				return data || [];
			},
			dependencies: ['type'],
			fieldProps: {
				fieldNames: {
					label: 'name',
					children: 'children',
					value: 'categoryId',
				},
				showSearch: true,
				allowClear: true,
				autoClearSearchValue: true,
				filterTreeNode: true,
				multiple: false,
				treeNodeFilterProp: 'name',
			},
			order: 2,
		},
	];

	return (
		<BizContainer<
			typeof business.material,
			BusinessAPI.MaterialVO,
			BusinessAPI.MaterialPageQry,
			BusinessAPI.MaterialCreateCmd & { file: any },
			BusinessAPI.MaterialUpdateCmd & { file: any }
		>
			rowKey={'materialId'}
			permission={'operation-community'}
			func={business.material}
			method={'material'}
			methodUpper={'Material'}
			intlPrefix={intlPrefix}
			onValueChange={onValueChange}
			modeType={mode}
			container={{ ghost }}
			page={{
				fieldProps: {
					ghost,
					//@ts-ignore
					search,
				},
				columns,
			}}
			create={{
				formType: 'drawer',
				formContext,
				trigger,
				request: async (
					formData: BusinessAPI.MaterialCreateCmd & {
						file: any;
					},
				) => {
					const OSS = require('ali-oss');
					const ossToken = await getOssToken();
					const client = new OSS({
						// yourRegion填写Bucket所在地域。以华东1（杭州）为例，yourRegion填写为oss-cn-hangzhou。
						region: 'oss-' + ossToken?.region,
						// 从STS服务获取的临时访问密钥（AccessKey ID和AccessKey Secret）。
						accessKeyId: ossToken?.accessKeyId,
						accessKeySecret: ossToken?.accessKeySecret,
						// 从STS服务获取的安全令牌（SecurityToken）。
						stsToken: ossToken?.securityToken,
						// 填写Bucket名称。
						bucket: ossToken?.bucket,
					});

					const path = moment(new Date()).format('YYMM/DD');

					const materialCreateCmdList =
						new Array<BusinessAPI.MaterialCreateCmd>();
					for (const file of formData.file) {
						const filename = uuidv4();
						// @ts-ignore
						const fileExtension = ((file.originFileObj?.name || '').match(
							/\.([0-9a-z]+)(?:[\\?#]|$)/i,
						) || ['.png'])[0];

						// 目录存放 `/uploads/operations/${path}/${filename}${fileExtension}`
						const result = await client.put(
							`/uploads/operations/${path}/${filename}${fileExtension}`,
							file.originFileObj,
						);

						materialCreateCmdList.push({
							name: file.name,
							categoryId: formData.categoryId,
							path: result.name,
							type: formData.type,
						});
					}

					const { success } = await business.material.batchCreateMaterial({
						materialCreateCmdList,
					});

					return success;
				},
			}}
			destroy={{}}
			update={{
				formType: 'drawer',
				formContext,
			}}
		/>
	);
}
