<template>
	<!-- 上传短视频 -->
	<view class="upload-content">
		<view class="progress-box" v-if="showProgress">
			<text class="progress-text">{{progress}}%</text>
			<text class="progress-lable">上传中</text>
			<progress :percent="progress"></progress>
		</view>
		<view v-if="video" class="video-preview">
		  <video 
			  :src="'https://app.mrrweb.com.cn' + video"
			  ref="videoPlayer"
			  v-if="video"
			  class="preview-video"
			  :controls="false"
			  object-fit="cover"
			  :autoplay="true"
			  :muted="true"
			  :initial-time="1"
			  :show-center-play-btn="false"
			  :show-loading="false"
			  :enable-progress-gesture="false"
			  :show-fullscreen-btn="false"
			  :show-play-btn="false"
			  @play="onPlay"
		  ></video>		  
		  <!-- 备用提示 -->
		  <view v-if="showFallback" class="video-fallback">
			<text>视频加载失败，请尝试刷新或更换视频源</text>
		  </view>
		  <view class="delete-btn" @click="deleteVideo">×</view>
		</view>
		<view v-else class="upload-btn" @click="chooseVideo">
			<text class="plus-icon">+</text>
		</view>
	</view>
</template>

<script>
import request from '../../utils/request';
import sparkMD5 from 'spark-md5'; // 引入MD5计算库
	export default {
		name:"upload-video",
		props: {
		  video: {
			type: String,
			default: ''
		  },
		  videoNum: {
			type: Number,
			default: 1
		  },
		},
		data() {
			return {
				autoplay: false,
				showProgress: false,
				progress: 0,
				showFallback: false,
				finalVideoUrl: '',
				platformAutoplay: true,
				autoplayMuted: true,
			};
		},
		// watch: {
		// 	video: {
		// 		handler(newValue) {
		// 			this.video = newValue
		// 		},
		// 		deep: true
		// 	}
		// },
		methods: {
		  // 获取文件 (兼容各平台)
		  getFile() {
		    return new Promise((resolve, reject) => {
		      // #ifdef H5
		      const input = document.createElement('input')
		      input.type = 'file'
		      input.accept = this.accept
		      input.onchange = (e) => {
		        // resolve(e.target.files[0])
		        resolve(e)
		      }
		      input.click()
		      // #endif
		      
		      // #ifndef H5
		      uni.chooseVideo({
		        count: 1,
		        sourceType: ['album', 'camera'],
				compressed: false,
				maxDuration: 180,
				camera: 'back',
		        success: (res) => {
		          // resolve(res.tempFiles[0])
		          resolve(res)
		        },
		        fail: (err) => {
		          reject(err)
		        }
		      })
		      // #endif
		    })
		  },
		  // 上传视频区域
		  async chooseVideo() {
		  	// 选择文件（添加类型校验）
		      // const res = await uni.chooseVideo({
		      //   sourceType: ['album', 'camera'],
		      //   compressed: false,
		      //   maxDuration: 180,
		      //   camera: 'back'
		      // });
			const res = await this.getFile();
			console.log(res,';;;;;;;;;;;;;;;;;;;;;;;;;;;')
		  	this.showProgress = true;
		  	let size = res.size;
		  	if(size > 5*1024*1024) {
		  		// 统一获取文件列表
		  		const files = res.tempFile || res;
		  		const file = res.tempFile || res;
				console.log('file',file)
		  		// if (!files || files.length === 0) {
		  		// 	uni.showToast({ title: '文件选择取消', icon: 'none' });
		  		// 	return;
		  		// }
		  		
		  		if (!file) {
		  			uni.showToast({ title: '视频选择取消', icon: 'none' });
		  			return;
		  		}
		  		
		  		progress: (res) => {
		  			console.log(`分片${index}进度: ${res.progress}%`);
		  		}
		  	  
		  		// 通过 tempFiles 获取文件（UniApp规范）
		  		// const file = files[0];
		  	  
		  		
		  		// 计算文件MD5（优化大文件计算）
		  		const md5 = await this.calculateFileMD5(file);
		  		
		  		// 分片大小（2MB）
		  		const chunkSize = 1 * 1024 * 1024;
		  		const totalChunks = Math.ceil(file.size / chunkSize);
		  	  
		  		// 分片上传
		  		for (let index = 0; index < totalChunks; index++) {
		  			const start = index * chunkSize;
		  			const end = Math.min(file.size, start + chunkSize);
					// #ifdef H5
					// 浏览器环境使用标准的 slice 方法
		  			const chunk = file.slice(start, end);
					// 上传分片
					await this.uploadChunk(chunk, index, totalChunks, md5);
					// #endif
					// #ifndef H5
					// 非浏览器环境使用 Uniapp API
					const fs = uni.getFileSystemManager();
					const arrayBuffer = fs.readFileSync({
					    filePath: file,
					    position: start,
					    length: end - start
					});
					// 上传分片
					await this.uploadChunk(arrayBuffer, index, totalChunks, md5);
					// #endif
		  			// 上传分片
		  			// await this.uploadChunk(chunk, index, totalChunks, md5);
		  				this.progress = parseInt((index+1)/totalChunks*100)
		  		}
		  		
		  		// 合并请求
		  		await this.mergeChunks(md5, file.name);
		  	}else {
		  		let item = {
		  			filePath: res.tempFilePath,
		  			type: 'video'
		  		}
		  		this.uploadVideo(item)
		  	}
		  },
		  uploadVideo(item) {
			request.uploadVideo('/user/uploadvideo',item.filePath,'video',{type: item.type}).then(res=>{
				this.$emit('addVideo',res.path)
				// this.initVideo();
				this.showProgress = false;
			})
		  },
		  // 计算文件MD5（分块计算）
		  calculateFileMD5(file) {
		    return new Promise((resolve) => {
		      const chunkSize = 1 * 1024 * 1024;
		      const chunks = Math.ceil(file.size / chunkSize);
		      const spark = new sparkMD5.ArrayBuffer();
		      let currentChunk = 0;
		  
		      const loadNext = () => {
		        const start = currentChunk * chunkSize;
		        const end = start + chunkSize >= file.size ? file.size : start + chunkSize;
				// #ifdef H5
		        const reader = new FileReader();
				// #endif
				// #ifndef H5
		        const reader = uni.getfilesystem;
				// #endif
		        reader.onload = (e) => {
		          spark.append(e.target.result);
		          currentChunk++;
		          if (currentChunk < chunks) {
		            loadNext();
		          } else {
		            resolve(spark.end());
		          }
		        };
		        reader.readAsArrayBuffer(file.slice(start, end));
		      };
		      loadNext();
		    });
		  },
		  
		  async uploadChunk(chunk, index, totalChunks, md5) {
		    let that = this;
		    try {
		      // 获取ArrayBuffer
		      const arrayBuffer = await new Promise((resolve) => {
		        // #ifdef H5
		        const reader = new FileReader();
		        // #endif
		        // #ifndef H5
		        const reader = uni.getfilesystem;
		        // #endif
		        reader.onload = () => resolve(reader.result);
		        reader.readAsArrayBuffer(chunk);
		      });
		  
		      // 平台差异化处理
		      let tempFilePath = '';
		      
		      // 微信小程序/App端写入临时文件
		      // #ifdef MP-WEIXIN || APP-PLUS
		      const fs = uni.getFileSystemManager();
		      tempFilePath = `${getTempDir()}${md5}_${Date.now()}_${index}.tmp`;
		      
		      await new Promise((resolve, reject) => {
		        fs.writeFile({
		          filePath: tempFilePath,
		          data: arrayBuffer,
		          encoding: 'binary',
		          success: resolve,
		          fail: (err) => reject(`文件写入失败: ${JSON.stringify(err)}`)
		        });
		      });
		      // #endif
		  
		      // H5端特殊处理
		      // #ifdef H5
		      const blob = new Blob([arrayBuffer], { type: chunk.type });
		      const file = new File([blob], `${md5}_${index}.bin`, {
		        type: chunk.type,
		        lastModified: Date.now()
		      });
			  tempFilePath = file;
		      // #endif
			const uploadTask = await request.uploadTask('/user/uploadvideoother',tempFilePath,'file',{chunkIndex: index,totalChunks: totalChunks,md5: md5});
		  
		      // 上传后清理临时文件（非H5）
		      // #ifdef MP-WEIXIN || APP-PLUS
		      fs.unlink({ filePath: tempFilePath });
		      // #endif
		  
		      return uploadTask;
		    } catch (error) {
		      console.error('分片上传失败:', error);
		      throw new Error(`分片${index}上传失败: ${error.message}`);
		    }
		  },
		  // 合并请求
		  mergeChunks(md5, fileName) {
		  	let that = this;
		  	request.post('/user/uploadvideomerge',{md5: md5,filename: fileName}).then(res=>{
				that.$emit('addVideo',res.path)
				// that.initVideo();
		  		that.showProgress = false;
		  	})
		  
		  },
		  // 上传视频结束区域
		  // 删除视频
		  deleteVideo() {
			this.$emit('deleteVideo')
		  },
		  initVideo() {
		    // 平台自动播放处理
		    this.platformAutoplay = this.autoplay;
		    
		    // iOS自动播放必须静音
		    // #ifdef APP-PLUS
		    if (plus.os.name === 'iOS' && this.autoplay) {
				this.autoplayMuted = true;
		    }
		    // #endif
		    
		    // 路径处理
		    this.processVideoUrl();
		  },
		  processVideoUrl() {
		    if (!this.video) return;
		    
		    // 处理APP本地路径
		    if (this.video.startsWith('file://') || this.video.startsWith('/storage')) {
		  	// #ifdef APP-PLUS
		  	this.finalVideoUrl = plus.io.convertLocalFileSystemURL(this.video);
		  	// #endif
			// #ifdef MP-WEIXIN || H5
		  	this.finalVideoUrl = this.video;
		  	// #endif
		    } else {
		  	this.finalVideoUrl = this.video;
		    }
		  },
		  onPlay() {
		    console.log('视频开始播放');
			this.platformAutoplay = true;
		    this.showFallback = false;
		  },
		  onError(e) {
		    console.error('视频播放错误:', e);
		    this.showFallback = true;
		    
		    // 尝试备用方案
		    this.tryFallbackSource();
		  },
		  tryFallbackSource() {
		    // 可以在这里实现备用视频源逻辑
		  }
		}
	}
</script>

<style>
.upload-content {
  display: flex;
  flex-wrap: wrap;
  position: relative;
}
.progress-box {
	width: 204rpx;
	height: 204rpx;
	background-color: rgba(0 ,0 ,0 , 0.5);
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	z-index: 99;
	display: flex;
	flex-flow: column nowrap;
	justify-content: center;
	align-items: center;
}
.progress-text {
	font-size: 42rpx;
	color: #FFFFFF;
	font-weight: 500;
}
.progress-lable {
	font-size: 28rpx;
	color: #FFFFFF;
}
.progress-box progress {
	/* width: 204rpx; */
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
}
.video-preview,
.upload-btn {
  width: 200rpx;
  height: 200rpx;
  margin-right: 10rpx;
  margin-bottom: 20rpx;
  position: relative;
}

.preview-video {
  width: 200rpx;
  height: 200rpx;
  border-radius: 8rpx;
}
.upload-btn {
  border: 2rpx dashed #DDDDDD;
  border-radius: 8rpx;
  display: flex;
  justify-content: center;
  align-items: center;
}

.plus-icon {
  font-size: 60rpx;
  color: #999999;
}

.delete-btn {
  position: absolute;
  top: -20rpx;
  right: -20rpx;
  width: 40rpx;
  height: 40rpx;
  background-color: rgba(0, 0, 0, 0.5);
  border-radius: 50%;
  color: #FFFFFF;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 32rpx;
}

</style>