<template>
	<view class="upload_wrap_preview">
		<!--  除了 APP 平台，其它平台均存在的代码  -->
		<!--    #ifndef APP-PLUS-->
		<view style="height: 0">
			<video
				@fullscreenchange="fullscreenchange"
				id="cVideo"
				:src="videoSrc"
			></video>
		</view>
		<!--    #endif-->

		<!--   仅出现在 App 平台下的代码  -->
		<!--    #ifdef APP-PLUS-->
		<view style="display: none">
			<video
				@fullscreenchange="fullscreenchange"
				id="cVideo"
				:src="videoSrc"
			></video>
		</view>
		<!--    #endif-->
		<view
			:key="i"
			v-for="(item, i) in fileList"
			class="video_box"
			@click.prevent="openVideo(item)"
		>
			<template v-if="!$attrs.disabled">
				<!-- 删除 icon -->
				<view
					@click.stop="deleteVideo(item, i)"
					v-if="item.status !== 'uploading'"
				>
					<u-icon
						name="close"
						color="#ffffff"
						size="10"
						class="del_icon"
					></u-icon>
				</view>
				<!-- 上传中loading -->
				<view
					class="upload_status"
					v-if="item.status === 'uploading'"
				>
					<u-loading-icon size="22" mode="circle" color="#ffffff" />
					<text v-if="item.message" class="upload_status_message">
						{{ item.message + item.progress }}
					</text>
				</view>
				<!-- 上传成功 -->
				<view v-if="item.status === 'success'" class="upload_success">
					<view class="upload_success_icon">
						<u-icon name="checkmark" color="#ffffff" size="12">
						</u-icon>
					</view>
				</view>
				<!-- 上传失败 -->
				<view v-if="item.status === 'error'" class="upload_status">
					<u-icon
						color="#ffffff"
						size="26"
						name="error-circle"
					></u-icon>
					<text class="upload_status_message">
						{{ item.message || '上传失败' }}
					</text>
				</view>
			</template>
			<view>
				<u-icon color="#80CBF9" size="26" name="movie"></u-icon>
				<text class="upload_video_text">视频</text>
			</view>
		</view>

		<u-upload v-on="_listeners" v-bind="_attrs">
			<slot></slot>
		</u-upload>
	</view>
</template>

<script>
import { uploadFile } from '@/api/com';
export default {
	name: 'videoUpload',
	inheritAttrs: false,
	model: {
		prop: 'value',
		event: 'change',
	},
	props: {
		maxSize: Number, // 单位是字节（Byte）
		value: {
			// 视频列表
			type: Array,
			default: () => [],
		},
	},

	data() {
		return {
			fileList: [],
			videoSrc: '',
			videoContext: null,
		};
	},
	watch: {
		value: {
			handler(list) {
				this.fileList = list;
			},
			immediate: true,
		},
	},
	computed: {
		_attrs() {
			return {
				...this.$attrs,
				accept: 'video',
				fileList: this.fileList,
				compressed: false, //不压缩视频，压缩视频会很慢
				uploadIcon: 'play-circle-fill',
				multiple: false, //开启后afterRead 参数拿到的file是一个对象(视频不支持多选)
				maxSize: 200 * 1024 * 1024, // 默认两百兆,
			};
		},
		_listeners() {
			return {
				...this.$listeners,
				afterRead: this.afterRead,
				delete: () => {},
			};
		},
	},
	mounted() {
		this.videoContext = uni.createVideoContext('cVideo', this);
	},
	methods: {
		fullscreenchange(e) {
			// 当视频进入和退出全屏时触发，event.detail = {fullScreen, direction}，direction取为 vertical 或 horizontal
			if (!e.detail.fullScreen) {
				this.videoContext.stop(); // 停止播放视频
			}
		},
		openVideo(item) {
			// 显示播放视频
			if (item.status === 'uploading' || item.status === 'error') {
				return;
			}
			console.log(item);
			this.videoSrc = item.url;
			this.$nextTick(() => {
				this.videoContext.requestFullScreen({ direction: 0 }); // 全屏
				this.videoContext.play(); // 播放视频
			});
		},
		deleteVideo(e) {
			// 删除file
			if (this.$listeners.delete) {
				this.$emit('delete', e);
				return;
			}
			this.fileList.splice(e.index, 1); // 删除
			this.$emit('change', this.fileList); // v-model
		},
		async afterRead(e) {
			//新增file
			if (this.$listeners.afterRead) {
				// 外部自定义
				this.$emit('afterRead', e);
				return;
			}
			const { file } = e;
			const maxSize = this.maxSize; // 字节 byte
			const maxSizeMb = (this.maxSize / 1024 / 1024).toFixed(0); // 转为兆
			if (maxSize && e.file.size > maxSize) {
				uni.showToast({
					icon: 'none',
					title: `视频不能大于${maxSizeMb}兆`,
				});
				return;
			}
			try {
				const obj = {
					...file,
					status: 'uploading',
					message: '上传中',
					progress: '0%',
				};
				this.fileList.push(obj);
				const config = {
					getTask: (task) => {
						task.onProgressUpdate((res) => {
							obj.progress = res.progress + '%';
						});
					},
				};
				const { data } = await uploadFile(file.url, config);
				const fileIdx = this.fileList.length - 1;
				// 上传成功 todo 这里是把旧的删除替换新的 http_url 并改变status
				this.fileList.splice(fileIdx, 1, {
					status: 'success',
					message: '',
					url: data.http_url,
					noPrefixUrl: data.url, // 没有前缀的
				});
				this.$emit('change', this.fileList);
			} catch (e) {
				// 上传失败
				this.fileList.splice(this.fileList.length - 1, 1);
				this.$emit('change', this.fileList);
				console.error(e);
			}
		},
	},
};
</script>

<style scoped lang="scss">
.upload_wrap_preview {
	display: flex;
	flex-wrap: wrap;

	#cVideo {
		opacity: 0;
		z-index: -1;
		width: 0 !important;
		height: 0;
		overflow: hidden;

		/deep/ .uni-video-container {
			width: 0 !important;
			height: 0;
		}
	}

	/deep/ .u-upload__wrap__preview {
		display: none !important;
	}

	.video_box {
		position: relative;
		background-color: #f2f2f2;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		border-radius: 2px;
		margin: 0 8px 8px 0;
		overflow: hidden;
		width: 80px;
		height: 80px;

		.upload_status {
			position: absolute;
			top: 0;
			bottom: 0;
			left: 0;
			right: 0;
			background-color: rgba(0, 0, 0, 0.5);
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;
			z-index: 2;

			.upload_status_message {
				margin-top: 5px;
				font-size: 12px;
				color: #ffffff;
			}
		}

		.upload_success {
			position: absolute;
			bottom: 0;
			right: 0;
			display: flex;
			flex-direction: row;
			border-style: solid;
			border-top-color: transparent;
			border-left-color: transparent;
			border-bottom-color: #5ac725;
			border-right-color: #5ac725;
			border-width: 9px;
			align-items: center;
			justify-content: center;

			.upload_success_icon {
				position: absolute;
				-webkit-transform: scale(0.7);
				transform: scale(0.7);
				bottom: -10px;
				right: -10px;
			}
		}

		.upload_video_text {
			font-size: 11px;
			color: #909193;
		}

		._video {
			width: 100%;
			height: 100%;
		}

		.del_icon {
			position: absolute;
			top: 0;
			right: 0;
			background-color: #373737;
			height: 14px;
			width: 14px;
			display: flex;
			flex-direction: row;
			border-bottom-left-radius: 100px;
			align-items: center;
			justify-content: center;
			z-index: 3;

			/deep/.uicon-close {
				position: absolute;
				top: 1px !important;
				right: 0;
				transform: scale(0.7);
			}
		}
	}
}
</style>
