<template>
	<view class="ImagesUpload">
		<helang-compress ref="helangCompress"></helang-compress>
		<view class="pic-box">
			<block v-if="fileList && fileList.length > 0">
				<view class="pic-list-item" v-for="(img, i) in fileList" :key="i">
					<block v-if="isVideo">
						<video @click.stop="videoPreview(img.url)" :src="img.url" controls class="pic"
							:style="'width:'+width+'rpx;'+'height:'+height+'rpx'"></video>
					</block>
					<block v-else>
						<image class="pic" :style="'width:'+width+'rpx;'+'height:'+height+'rpx'" :src="img.url" mode=""
							@error="(e) => imgError(e, img)" @click.stop="preview(img.url)"></image>
						<view v-if="img.error" class="pic-error">加载失败</view>
					</block>
					<icon @click="handleRemove(i)" class="clear-icon" type="clear" size="20" />
				</view>
			</block>
			<block v-if="!fileList || fileList.length < limit">
				<picker @change="bindPickerChange" range-key="label" :range="pickerRange">
					<view class="img-uplad-btn" :style="'width:'+width+'rpx;'+'height:'+height+'rpx'"
						@click="handleUpload">
						<image class="icon" :style="'width:'+(width/3)+'rpx;'+'height:'+(height/3)+'rpx'"
							src="/static/images/publish/plus-icon.png"></image>
					</view>
				</picker>
			</block>
		</view>
		<view class="img-type-box" v-if="showIcons">
			<!-- 图片 -->
			<image src="/static/images/publish/img-icon.png" class="icons" @click="handleUploadByChooseImage"
				v-if="!isVideo"></image>
			<image src="/static/images/publish/img-disabled-icon.png" class="icons" v-else></image>
			<!-- 视频 -->
			<image src="/static/images/publish/video-icon.png" class="icons" @click="handleUploadByChooseMedia"
				v-if="!isImg"></image>
			<image src="/static/images/publish/video-disabled-icon.png" class="icons" v-else></image>
			<!-- 表情 -->
			<image src="/static/images/publish/face-icon.png" class="icons" @click="handleShowEmjo"></image>
			<!-- 表情展示区 -->
			<view class="emjo-box" v-if="showEmjo" :style="'left:' + clientX + 'rpx;' +'top:' + clientY + 'rpx'">
				<view class="emotion-list">
					<view class="emotion-item" v-for="(emotion, index) in emotions" :key="index"
						:title="emotion.name" @click="handleSelectEmjo(emotion)">
						<text class="iconfont" :class="emotion.code"></text>
					</view>
				</view>

			</view>
			<!-- 话题 -->
			<image src="/static/images/publish/topic-icon.png" class="icons" @click="handleOpenTopicSelection">
			</image>
			<!-- 链接 -->
			<!-- <image src="/static/images/publish/link-icon.png" class="icons"></image> -->
			<!-- @ -->
			<!-- <image src="/static/images/publish/important-icon.png" class="icons"></image> -->
		</view>

		<!-- 视频预览 -->
		<video-preview ref="videoPreviewRef"></video-preview>


	</view>
</template>

<script>
	import config from '@/config/index.config.js';
	import {
		toast,
		showConfirm
	} from '@/utils/common';
	import {
		getToken
	} from '@/utils/auth.js';
	import $modal from '@/utils/modal.js'
	import VideoPreview from './VideoPreview.vue';
	import emotions from '@/utils/emjo';
	import HelangCompress from './HelangCompress.vue';
	export default {
		name: 'BatchImageUpload',
		props: {
			modelValue: {
				type: [String, Array],
				default: () => []
			},
			// 文件数量
			limit: {
				type: Number,
				default: 9
			},
			// 文件类型
			mediaType: {
				type: Array,
				default: () => ['image', 'video']
			},
			// 是否显示下方得操作按钮
			showIcons: {
				type: Boolean,
				default: false
			},
			width: {
				type: Number,
				default: 200
			},
			height: {
				type: Number,
				default: 200
			}
		},
		components: {
			VideoPreview,
			HelangCompress
		},
		data() {
			return {
				uploadUrl: '/bbs/mobile/common/upload', //上传地址
				baseUrl: config.requestUrl,
				resourceUrl: config.requestUrl, //资源地址
				fileList: [],
				isVideo: false,
				isImg: false,
				limiData: undefined,
				emotions,
				showEmjo: false,
				clientX: 0,
				clientY: 0
			};
		},
		computed: {
			pickerRange() {
				if (!this.mediaType.includes('image')) {
					return [{
						label: '视频',
						value: '1'
					}];
				} else if (!this.mediaType.includes('video')) {
					return [{
						label: '图片',
						value: '0'
					}];
				}
				return [{
						label: '图片',
						value: '0'
					},
					{
						label: '视频',
						value: '1'
					}
				];
			}
		},
		watch: {
			modelValue: {
				handler: function(val, oldVal) {
					console.log(val, oldVal)
					const _this = this;
					let list = [];
					let newlist = [];
					if (!_this.modelValue || _this.modelValue === null || _this.modelValue === undefined) {
						newlist = [];
					} else {
						if (Array.isArray(_this.modelValue)) {
							list = JSON.parse(JSON.stringify(_this.modelValue));
						} else {
							list = JSON.parse(JSON.stringify(_this.modelValue)).split(',');
						}
						newlist = list.map((item) => {
							return {
								url: item.url,
								name: item.name
							};
						});
					}
					if (newlist && newlist.length === 1) {
						const videoExtensions = ['.mp4', '.avi', '.mov', '.wmv', '.flv', '.mkv', '.webm'];
						const extension = '.' + newlist[0].url.split('.').pop().toLowerCase();
						_this.isVideo = videoExtensions.includes(extension);
					} else {
						_this.isVideo = false;
					}
					if (newlist && newlist.length > 0) {
						const imgExtensions = ['.png', '.jpg', '.jpeg', '.PNG', '.JPG', '.JPEG', '.svg'];
						const extension = '.' + newlist[0].url.split('.').pop().toLowerCase();
						_this.isImg = imgExtensions.includes(extension);
					} else {
						_this.isImg = false
					}
					_this.fileList = newlist;
					this.limiData = this.limit - newlist.length
					_this.$emit('componentsType', _this.isVideo ? 'VIDEO' : 'IMAGE')
				},
				immediate: true
			}
		},
		methods: {
			imgError(e, img) {
				if (e.type == 'error') {
					img['error'] = true;
				} else {
					img['error'] = false;
				}
			},
			handleUploadByChooseImage() {
				const _this = this;
				// 从本地相册选择图片或使用相机拍照
				uni.chooseImage({
					count: _this.limiData,
					sourceType: ['album', 'camera'],
					sizeType: ['original', 'compressed'],
					success(res) {
						const tempFilePaths = JSON.parse(JSON.stringify(res.tempFilePaths));
						if (tempFilePaths.length <= _this.limiData) {
							console.log('选择完',new Date())
							// 开始上传到api
							$modal.loading('上传中...');
							// _this.handleUploadPic(tempFilePaths)
							
							_this.$refs.helangCompress.compress({
								src: tempFilePaths,
								maxSize: 800,
								fileType: 'jpg',
								quality: 0.80,
								progress: (res) => {
									// console.log('压缩进度');
									// console.log(res);
								}
							}).then((res) => {
								let tempFile = res.map(item => _this.dataURLtoBlob(item));
								if (tempFile.length <= 0) {
									uni.hideLoading();
									uni.showToast({
										title:'未识别到图片'
									})
									return;
								}
								_this.handleUploadPic(tempFile);
							}).catch((err) => {
								uni.hideLoading();
								uni.showToast({
									title:err
								})
							})
						} else {
							uni.showToast({
								title: `最多选择${_this.limiData}张`,
								icon: 'error'
							})
						}

					}
				});
			},
			//将base64转换为blob
			dataURLtoBlob(dataurl) {
				var arr = dataurl.split(','),
					mime = arr[0].match(/:(.*?);/)[1],
					bstr = atob(arr[1]),
					n = bstr.length,
					u8arr = new Uint8Array(n);
				while (n--) {
					u8arr[n] = bstr.charCodeAt(n);
				}
				return new Blob([u8arr], {
					type: mime
				});
			},

			handleUploadPic(fileList) {
				console.log('上传图片',new Date())
				const _this = this;
				let uploadTasks = fileList.map((item, index) => {
					return uni.uploadFile({
						url: _this.baseUrl + _this.uploadUrl,
						file: item,
						name: 'file',
						formData: {},
						header: {
							Authorization: 'Bearer ' + getToken()
						},
						success: (uploadFileRes) => {
							const data = JSON.parse(uploadFileRes.data);
							if (data.code === 401) {
								uni.reLaunch({
									url: '/pages/login/login'
								});
							} else if (data.code === 200) {
								// 上传成功
								_this.handleSuccess(data);
							} else if (data.code === 500) {
								$modal.msg(data.msg || '上传失败');
							}
						},
						fail: (error) => {
							console.log('上传失败：', error);
						},
						// 接口调用结束的回调函数（调用成功、失败都会执行）
						complete: () => {
							console.log('上传完成',new Date())
							$modal.closeLoading();
						}
					});
				})

				Promise.all(uploadTasks).then((res) => {
					// console.log('所有图片上传完成'); // 所有图片上传成功后执行的逻辑
				}).catch(err => {
					console.error('有图片上传失败', err); // 如果有上传失败的情况处理的逻辑
				});

			},
			handleUploadByChooseMedia() {
				const _this = this;
				//如果上传了video 则不能再继续上传
				// 拍摄视频或从手机相册中选视频，返回视频的临时文件路径。
				uni.chooseVideo({
					success(res) {
						console.log(res)
						if(res.size > (config.videoLimitSize*1024*1024)){
							$modal.msg(`请上传大小为${config.videoLimitSize}M以下的视频`);
							return
						}
						if (_this.isVideo == true) {
							$modal.msg('上传了视频,不能再上传其他媒体文件。');
						} else {
							_this.isVideo = true;
							// 开始上传到api
							$modal.loading('上传中...');
							uni.uploadFile({
								url: _this.baseUrl + _this.uploadUrl,
								filePath: res.tempFilePath,
								name: 'file',
								formData: {},
								header: {
									Authorization: 'Bearer ' + getToken()
								},
								success: (uploadFileRes) => {
									const data = JSON.parse(uploadFileRes.data);
									if (data.code === 401) {
										showConfirm('登录状态已过期，您可以继续留在该页面，或者重新登录?').then((res) => {
											if (res.confirm) {
												_this.$store.dispatch('LogOut').then((res) => {
													uni.reLaunch({
														url: '/pages/login/login'
													});
												});
											}
										});
									} else if (data.code === 200) {
										// 上传成功
										_this.handleSuccess(data);
									} else if (data.code === 500) {
										$modal.msg(data.msg || '上传失败');
									}
								},
								fail: (error) => {
									console.log('上传失败：', error);
									_this.isVideo = false;
								},
								// 接口调用结束的回调函数（调用成功、失败都会执行）
								complete: () => {
									$modal.closeLoading();
								}
							});
						}
					}
				});
			},
			// 点击上传
			handleUpload() {},
			// 选择上传图片 或 视频
			bindPickerChange(e) {
				// 0图片 1视频
				const typeValue = this.pickerRange[e.detail.value].value;
				if (typeValue == '1') {
					if (this.fileList && this.fileList.length > 0) {
						const videoExtensions = ['.png', '.jpg', '.jpeg', '.PNG', '.JPG', '.JPEG', '.svg'];
						const extension = '.' + this.fileList[0].url.split('.').pop().toLowerCase();
						const isImg = videoExtensions.includes(extension);
						if (isImg) {
							$modal.msg('图片和视频不能一起上传');
							return false;
						}
					}
					this.handleUploadByChooseMedia();
				} else {
					if (this.fileList && this.fileList.length > 0) {
						const videoExtensions = ['.mp4', '.avi', '.mov', '.wmv', '.flv', '.mkv', '.webm'];
						const extension = '.' + this.fileList[0].url.split('.').pop().toLowerCase();
						const isVideo = videoExtensions.includes(extension);
						if (isVideo) {
							$modal.msg('图片和视频不能一起上传');
							return false;
						}
					}
					this.handleUploadByChooseImage();
				}
			},
			/**
			 * 上传成功
			 * @param {Object} data
			 * {fileName,ossId,url}
			 */
			handleSuccess(data) {
				this.fileList = [...this.fileList, data];
				this.handleFinish();
			},
			handleRemove(i) {
				console.log(i, this.fileList);
				$modal.confirm('确定删除吗？').then(() => {
					this.fileList.splice(i, 1);
					this.handleFinish();
				});
			},
			// 上传文件结束处理
			handleFinish() {
				let files = this.fileList.map((item) => {
					return {
						name: item.originalFilename,
						url: item.url
					}
				});
				this.$emit('update:modelValue', files); //子组件通过this.$emit()方法修改number值
			},
			// 预览
			preview(url) {
				uni.previewImage({
					urls: [url]
				});
			},
			//预览视频
			videoPreview(url) {
				this.$refs.videoPreviewRef.openModal(url)
			},
			// 选择话题
			handleOpenTopicSelection() {
				this.showEmjo = false
				this.$emit('handleTopic')
			},
			// 打开表情选择
			handleShowEmjo(e) {
				this.showEmjo = !this.showEmjo
				this.clientX = (e.target.offsetLeft * 2 - 158);
				this.clientY = ((e.target.offsetTop * 2) + 34);
			},
			// 选择表情
			handleSelectEmjo(emotion){
				this.showEmjo = false
				this.$emit('handleEmjo',emotion)
			},
			// 关闭表情窗
			closeEmjo(){
				if(this.showEmjo){
					this.showEmjo = false
				}
			}
		}
	};
</script>

<style scoped lang="scss">
	.ImagesUpload {
		.pic-box {
			display: flex;
			justify-content: flex-start;
			align-items: center;
			gap: 10px;
			flex-wrap: wrap;

			.pic-list-item {
				position: relative;
			}

			.pic {

				border-radius: 10px;
				object-fit: cover;
			}

			.pic-error {

				border-radius: 10px;
				display: flex;
				justify-content: center;
				align-items: center;
				border: 1px solid #666666;
				color: #666666;
			}

			.clear-icon {
				position: absolute;
				right: 0;
				top: 0;
				transform: translate(35%, -35%);
				background: #fff;
				width: 20px;
				height: 20px;
				border-radius: 100%;
				z-index: 900;
			}
		}

		.img-uplad-btn {

			background-color: rgba(255, 255, 255, 1);
			border: 1px solid #eee;
			display: flex;
			align-items: center;
			justify-content: center;

			.icon {
				width: 62rpx;
				height: 62rpx;
			}
		}

		.img-type-box {
			margin-top: 40rpx;
			display: flex;

			.icons {
				width: 48rpx;
				height: 48rpx;
				margin-right: 32rpx;
			}
		}
	}



	.emjo-box {
		position: fixed;
		width: 90vw;
		min-height: 100rpx;
		background-color: white;
		box-shadow: 0px 2px 12rpx 0px rgba(0, 0, 0, 0.2);
		border-radius: 10rpx;
		
		z-index: 999;

		.emotion-list {
			display: flex;
			flex-wrap: wrap;
			padding: 10px;
			
			overflow-y: auto;
		}

		.emotion-item {
			width: 14%;
			height:100rpx;
			display: flex;
			justify-content: center;
			align-items: center;
			font-size: 24px;
		}
	}
</style>