import { get, defaults, findIndex } from 'lodash-es';
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
 
type keyPath = Array<string> | string;
type uOptions = { limit: number };
export function useUpload<T>(
	uApi: (params: any, formData: any) => Promise<T>,
	dApi?: (id: string) => Promise<T>,
	uOptions?: uOptions,
	uParams: object | (() => object) = {},
	// format: (data: { fileName: string; suffix: string }) => fFIle,
	options: {
		path?: { data?: keyPath };
	} = {}
) {
	defaults(options, {
		path: {
			data: 'data.result',
		},
		immediate: false,
	});
 
	// defaults(format, (data: bFile) => {
	// 	return { ...data, name: `${data.fileName}${data.suffix}`, type: 'image' };
	// });
 
	// 统一数据格式
	const format = (data: any): any => {
		const type = getFileType(data.suffix);
		return { ...data, name: `${data.fileName}${data.suffix}`, type };
	};
 
	const getFileType = (suffix: string) => {
		const suffixType: any = {
			'.jpg': 'image',
			'.jpeg': 'image',
			'.bmp': 'image',
			'.png': 'image',
			'.webp': 'image',
			'.mp4': 'video',
			'.webm': 'video',
			'.mp3': 'audio',
		};
		return suffixType[suffix];
	};
 
	let uFileList = ref<any>([]);
 
	// 初始化文件列表
	const initFileList = (fileList: Array<any> = []) => {
		fileList = fileList || [];
		uFileList.value = fileList.map((file) => format(file));
	};
 
	// 文件上传
	const onChange = async (uploadFile: any) => {
		const requestData = {};
		if (uParams) {
			if (typeof uParams === 'function') {
				Object.assign(requestData, uParams());
			} else {
				Object.assign(requestData, uParams);
			}
		}
		const uid = uploadFile.uid;
		let formData = new FormData();
		formData.append('files', uploadFile.raw);
		try {
			const res = await uApi(requestData, formData);
			const result = get(res, options!.path?.data, []);
			if (!result) return; // 没有返回数据就不更新本地文件列表
			// 上传成功文件用新数据更新文件列表
			const curIndex = findIndex(uFileList.value, function (o: { uid: string }) {
				return o.uid == uid;
			});
			uFileList.value.splice(curIndex, 1, format(result[0]));
		} catch (error: any) {
			// 上传不成功移除文件
			const curIndex = findIndex(uFileList.value, function (o: { uid: string }) {
				return o.uid == uid;
			});
			uFileList.value.splice(curIndex, 1);
		}
	};
 
	// 文件移除
	const onRemove = async (file: { id: string }) => {
		if (!dApi) return;
		await dApi(file.id);
	};
 
	// 文件异常处理
	const onExceed = (files: any, uploadFiles: any) => {
		const total = files.length + uploadFiles.length;
		if (total > uOptions.limit) {
			ElMessage.error(`最多只能上传 ${uOptions.limit} 个文件,请删除后再上传!`);
		}
	};
 
	return { fileList: uFileList, initFileList, onChange, onRemove, onExceed };
}