import { config } from "@/config";
import { request } from "../service";
import { basename, extname, filename, parse, parseObject, pathJoin, uuid } from "../utils";
import { useStore } from "../store";

// 上传进度回调结果类型
export type OnProgressUpdateResult = {
	progress: number;
	totalBytesSent: number;
	totalBytesExpectedToSend: number;
};

// 上传任务类型定义
export type UploadTask = {
	abort(): void;
};

// 上传选项类型定义
export type UploadOptions = {
	onProgressUpdate?: (result: OnProgressUpdateResult) => void; // 上传进度回调
	onTask?: (task: UploadTask) => void; // 上传任务回调
};

// 上传模式类型
export type UploadMode = {
	mode: "local" | "cloud"; // 上传模式：本地或云端
	type: string; // 云服务类型
};

// 上传请求的参数类型
export type UploadRequestOptions = {
	url: string;
	preview?: string;
	data: any;
};

// 云上传返回数据类型
export type CloudUploadResponse = {
	uploadUrl?: string;
	url?: string;
	host?: string;
	credentials?: any;
	OSSAccessKeyId?: string;
	policy?: string;
	signature?: string;
	publicDomain?: string;
	token?: string;
	fields?: any;
};

// 本地上传返回数据类型
export type LocalUploadResponse = {
	code: number;
	message?: string;
	data: string;
};


/**
 * 路径上传
 * @param path 文件路径
 */
export async function upload(path: string) {
	return uploadFile({
		path,
		size: 0,
		name: "",
		type: "image/png"
	});
}

/**
 * 文件上传
 * @param file 文件信息 ChooseImageTempFile
 * @param options 上传选项
 */
export async function uploadFile(
	file: ChooseImageTempFile,
	options: UploadOptions | null = null
): Promise<string> {
	const { user } = useStore();


	// 获取文件路径
	const filePath = file.path;

	// 获取文件名
	let fileName = file.name;

	// 如果文件名不存在，则使用文件路径的文件名
	if (fileName == "" || fileName == null) {
		fileName = basename(filePath);
	}

	// 获取文件扩展名
	let ext = extname(fileName);
	if (ext == "") {
		ext = "png";
	}

	// 生成唯一key: 原文件名_uuid.扩展名
	let key = `${filename(fileName)}_${uuid()}.${ext}`;

	// 支持多种上传方式
	return new Promise((resolve, reject) => {
		/**
		 * 实际上传文件的函数
		 * @param param0 上传参数
		 */
		function next({ url, preview, data }: UploadRequestOptions) {
			// 发起上传请求
			const task = uni.uploadFile({
				url,
				filePath,
				name: "file",
				header: {
					// 本地上传带token
					Authorization: user.token
				},
				formData: {
					...(data as UTSJSONObject),
					key
				},
				success(res) {
					// 本地上传返回处理
					const { code, data, message } = parseObject<LocalUploadResponse>(res.data)!;
					resolve(data);
				},
				fail(err) {
					console.error(err);
					reject(err);
				}
			});

			// 上传任务回调
			if (options?.onTask != null) {
				options.onTask!({
					abort: () => {
						task.abort();
					}
				} as UploadTask);
			}

			// 上传进度回调
			if (options?.onProgressUpdate != null) {
				task.onProgressUpdate((result) => {
					const { progress, totalBytesSent, totalBytesExpectedToSend } = result;

					options.onProgressUpdate!({
						progress,
						totalBytesSent,
						totalBytesExpectedToSend
					});
				});
			}
		}

		// 本地上传
		next({
			url: config.baseUrl + "/upms/files/upload",
			data: {}
		});
	});
}
