<template>
	<u-upload :name="name" :disabled="disabled" :width="width" :height="height" :accept="accept" :fileList="fileList"
		:multiple="multiple" :maxCount="maxCount"  :previewFullImage="true"
		@afterRead="afterRead" @delete="onDelete" @beforeRead="beforeRead">
		<slot name="content" :data="fileList">
			
		</slot>

		<image v-if="customImg" src="@/static/discover/ic_upload.png" mode=""
			:style="{ width: width + 'px', height: height + 'px', borderRadius: '12rpx' }"></image>
	</u-upload>
</template>

<script>
import { baseUrl } from '@/common/config.js';
export default {
	name: "",
	props: {
		disabled: {
			type: Boolean,
			default: false
		},
		api: {
			type: String,
			default: '/common/upload'
		},
		name: {
			type: String,
			default: uni.$u.props.upload.name
		},
		accept: {
			type: String,
			default: 'image' // 默认接受图片
		},
		width: {
			type: [String, Number],
			default: uni.$u.props.upload.width
		},
		height: {
			type: [String, Number],
			default: uni.$u.props.upload.height
		},
		// 文件大小限制，单位为byte
		maxSize: {
			type: [String, Number],
			default: uni.$u.props.upload.maxSize
		},
		maxCount: {
			type: Number,
			default: 5
		},
		multiple: {
			type: Boolean,
			default: true
		},
		// 图片格式限制
		imageFormats: {
			type: Array,
			default: () => ['png', 'jpg', 'jpeg']
		},
		// 视频格式限制
		videoFormats: {
			type: Array,
			default: () => ['mp4', 'mov', 'mkv', 'wmv']
		},
		// 音频格式限制
		audioFormats: {
			type: Array,
			default: () => ['mp3', 'wav', 'wma', 'm4a']
		},
		// 图片大小限制，单位为byte
		maxImageSize: {
			type: Number,
			default: 2 * 1024 * 1024 // 默认2MB
		},
		// 视频大小限制，单位为byte
		maxVideoSize: {
			type: Number,
			default: 50 * 1024 * 1024 // 默认50MB
		},
		// 音频大小限制，单位为byte
		maxAudioSize: {
			type: Number,
			default: 10 * 1024 * 1024 // 默认10MB
		},
		customImg: {
			type: Boolean,
			default: false
		},
		fileList: {
			type: Array,
			default: []
		},
		// 是否启用图片预览
		previewImage: {
			type: Boolean,
			default: true
		},
		// 是否全屏预览
		previewFullImage: {
			type: Boolean,
			default: true
		},
	},
	data() {
		return {
			//fileList: [],
		};
	},
	computed: {

	},
	mounted() {

	},
	beforeDestroy() {

	},
	methods: {
		// 上传前的处理函数
		beforeRead(event) {
			console.log(event,'66666666')
		},
		// 上传后的处理函数
		async afterRead(event) {
			// 当设置 multiple 为 true 时, file 为数组格式，否则为对象格式
			console.log(event,'event')
			let lists = [].concat(event.file);
			let fileListLen = this[`fileList`].length;

			// 验证文件格式和大小
			for (let i = 0; i < lists.length; i++) {
				const file = lists[i];
				const fileName = file.name.split('/').pop();
				const fileExtension = fileName.split('.').pop().toLowerCase();

				// 根据文件扩展名判断是图片、视频还是音频（优先使用扩展名判断）
				const isImage = this.imageFormats.includes(fileExtension);
				const isVideo = this.videoFormats.includes(fileExtension);
				const isAudio = this.audioFormats.includes(fileExtension);

				if (isImage) {
					// 图片验证
					if (file.size && file.size > this.maxImageSize) {
						const maxSizeMB = (this.maxImageSize / 1024 / 1024).toFixed(1);
						uni.$u.toast(`图片大小不能超过 ${maxSizeMB}MB`);
						return;
					} else {
						// 压缩后可能是 File 对象（H5）或 URL 字符串（App/小程序）
						const compressedResult = await this.compressImage(file.url);
						console.log(compressedResult,'compressedResult')
						// 保存原始 URL 用于预览，压缩结果用于上传
						lists[i].compressedFile = compressedResult;
						lists[i].contentType = 'image/' + fileExtension;
					}
				} else if (isVideo) {
					// 视频验证
					if (file.size && file.size > this.maxVideoSize) {
						const maxSizeMB = (this.maxVideoSize / 1024 / 1024).toFixed(1);
						uni.$u.toast(`视频大小不能超过 ${maxSizeMB}MB`);
						return;
					}
				} else if (isAudio) {
					// 音频验证
					if (file.size && file.size > this.maxAudioSize) {
						const maxSizeMB = (this.maxAudioSize / 1024 / 1024).toFixed(1);
						uni.$u.toast(`音频大小不能超过 ${maxSizeMB}MB`);
						return;
					}
					lists[i].type = 'audio/' + fileExtension;
				} else {
					// 无法判断类型或类型不支持，检查是否有file.type
					if (file.type) {
						if (file.type.startsWith('image/')) {
							// 是图片但扩展名不在允许列表中
							uni.$u.toast(`图片格式仅限 ${this.imageFormats.join(', ')}`);
							return;
						} else if (file.type.startsWith('video/')) {
							// 是视频但扩展名不在允许列表中
							uni.$u.toast(`视频格式仅限 ${this.videoFormats.join(', ')}`);
							return;
						} else if (file.type.startsWith('audio/')) {
							// 是音频但扩展名不在允许列表中
							uni.$u.toast(`音频格式仅限 ${this.audioFormats.join(', ')}`);
							return;
						}
					}
					// 无法判断类型或类型不支持
					uni.$u.toast('不支持的文件格式');
					return;
				}
			}

			lists.map((item) => {
				this[`fileList`].push({
					...item,
					status: "uploading",
					message: "上传中",
					localUrl: item.url, // 保存原始本地路径用于预览
				});
			});
			// 无预览时，使用toast
			if (!this.$attrs.previewImage) {
				uni.showLoading({
					title: '上传中...'
				});
			}
			for (let i = 0; i < lists.length; i++) {
				const result = await this.uploadFilePromise(lists[i].url);
				let item = this[`fileList`][fileListLen];
				this[`fileList`].splice(
					fileListLen,
					1,
					Object.assign(item, {
						status: "success",
						message: "",
						url: baseUrl + result,
					})
				);
				fileListLen++;
				// 无预览时，使用toast
				if (!this.$attrs.previewImage) {
					uni.hideLoading();
					uni.showToast({
						icon: 'none',
						title: result.message || '上传完成',
						duration: 2000
					});
					this.$emit('complete');
				}
			}
			this.$emit('fileList', this.fileList);
		},
		// 图片压缩 - 支持H5、App、小程序三端
		// 使用条件编译区分平台
		async compressImage(url) {
			// #ifdef H5
			// H5 环境直接使用 Canvas 压缩
			try {
				return await this.canvasCompress(url, 0.8);
			} catch (err) {
				console.warn('Canvas 压缩失败，使用原图片:', err);
				return url;
			}
			// #endif

			// #ifndef H5
			// App 和小程序使用 uni.compressImage
			return new Promise((resolve) => {
				uni.compressImage({
					src: url,
					quality: 0.8,
					success: (res) => {
						resolve(res.tempFilePath);
					},
					fail: (err) => {
						console.warn('uni.compressImage 失败，使用原图片:', err);
						resolve(url);
					}
				});
			});
			// #endif
		},
		// Canvas 图片压缩（H5 专用）
		canvasCompress(url, quality) {
			return new Promise((resolve, reject) => {
				const img = new Image();
				img.crossOrigin = 'anonymous';
				img.onload = () => {
					const canvas = document.createElement('canvas');
					const ctx = canvas.getContext('2d');

					// 计算压缩后的尺寸（保持宽高比）
					const maxWidth = 1200;
					const maxHeight = 1200;
					let width = img.width;
					let height = img.height;

					if (width > maxWidth) {
						height = (maxWidth / width) * height;
						width = maxWidth;
					}
					if (height > maxHeight) {
						width = (maxHeight / height) * width;
						height = maxHeight;
					}

					canvas.width = width;
					canvas.height = height;
					ctx.drawImage(img, 0, 0, width, height);

					// 将 Canvas 转换为 File 对象
					canvas.toBlob((blob) => {
						if (blob) {
							// 确保文件名以 .jpg 结尾
							const originalName = url.split('/').pop() || 'image';
							console.log(originalName,'originalName')
							const fileName = originalName.endsWith('.jpg') || originalName.endsWith('.jpeg') || originalName.endsWith('.png')
								? originalName
								: originalName + '.jpg';
							const file = new File([blob], fileName, { type: 'image/jpeg' });
							resolve(file);
						} else {
							reject('Blob 创建失败');
						}
					}, 'image/jpeg', quality);
				};
				img.onerror = (err) => {
					reject('图片加载失败: ' + err);
				};
				img.src = url;
			});
		},
		uploadFilePromise(url) {
			return new Promise((resolve, reject) => {
				uni.uploadFile({
					url: baseUrl + this.api,
					name: "file",
					header: {
						'Authorization': `tf: ${uni.getStorageSync('access-token')}`
					},
					formData: {
						'biz': 'temp',
					},
					filePath: url,
					success: (res) => {
						let data = JSON.parse(res.data);
						if (data.code === 200) {
							resolve(data.fileName);
						} else {
							uni.$u.toast('上传失败');
							reject();
						}
					},
				});
			});
		},
		onDelete(event) {
			uni.showModal({
				title: '提示',
				content: '确定要删除？',
				cancelText: '取消',
				confirmText: '确定',
				success: res => {
					if (res.confirm) {
						this[`fileList`].splice(event.index, 1);
						this.$emit('fileList', this.fileList);
					}
				}
			})
		},
		
	}
}
</script>

<style lang="scss" scoped></style>