<template>
	<view class="preview">
		<swiper :circular="true" :current="currentIndex" @change="swiperChange">
			<swiper-item v-for="(item,index) in classList" :key="item._id">
				<!-- 下面的这个v-if是进行流量控制的。看哪个页面就加载哪个页面
					避免用户的流量消耗。提高用户体验。
				 -->
				<!-- <image v-if="index===currentIndex" @click="maskChange" :src="item.picurl" mode="aspectFill"></image> -->

				<!-- 也可以选择加载临近一至两张的图片 -->

				<!-- 这是加载临近的左右图片 -->
				<!-- <image v-if="Math.abs(index - currentIndex) <= 1" @click="maskChange" :src="item.picurl" mode="aspectFill"></image> -->

				<image v-if="readImgs.includes(index)" @click="maskChange" :src="item.picurl" mode="aspectFill"></image>
			</swiper-item>
		</swiper>

		<view class="mask" v-show="maskState">
			<view class="goBack" @click="goBack" :style="{top:getPreviewBarHeight() + 'px'}">
				<uni-icons type="back" color="#fff" size="20"></uni-icons>
			</view>
			<view class="count">{{currentIndex+1}} / {{classList.length}}</view>
			<view class="time">
				<uni-dateformat :date="Date.now()" format="hh:mm"></uni-dateformat>
			</view>
			<view class="date">
				<uni-dateformat :date="Date.now()" format="MM月dd日"></uni-dateformat>
			</view>
			<view class="footer">
				<view class="box" @click="clickInfo">
					<uni-icons type="info" size="23"></uni-icons>
					<view class="text">信息</view>
				</view>
				<view class="box" @click="clickScore">
					<uni-icons type="star" size="23"></uni-icons>
					<view class="text">{{currentInfo.score}}分</view>
				</view>
				<view class="box" @click="clickDownload">
					<uni-icons type="download" size="23"></uni-icons>
					<view class="text">下载</view>
				</view>
			</view>
		</view>


		<uni-popup ref="infoPopup" type="bottom">
			<view class="infoPopup">
				<view class="popHeader">
					<!-- 空占位区，用于flex布局的分布 -->
					<view></view>
					<view class="title">壁纸信息</view>
					<view class="close" @click="clickInfoClose">
						<uni-icons type="closeempty" size="18" color="#999"></uni-icons>
					</view>
				</view>

				<scroll-view :scroll-y="true">
					<view class="content">
						<view class="row">
							<view class="label">壁纸ID：</view>
							<!-- 这里的内容是可选的，所以要用text的 selectable属性 -->
							<text selectable class="value">{{currentInfo._id}}</text>
						</view>

						<!-- 暂时没用到 -->
						<!-- 						<view class="row">
							<view class="label">分类：</view>
							<text class="value class">明星美女</text>
						</view> -->

						<view class="row">
							<view class="label">发布者：</view>
							<text class="value">{{currentInfo.nickname}}</text>
						</view>

						<view class="row">
							<text class="label">评分：</text>
							<view class="value roteBox">
								<uni-rate :readonly="true" :touchable="false" :value="currentInfo.score" size="16" />
								<!-- 								<uni-rate :readonly="true" :touchable="false" :value="5"/> -->
								<text class="score">{{currentInfo.score}}</text>
							</view>
						</view>

						<view class="row">
							<text class="label">摘要：</text>
							<view class="value">
								{{currentInfo.description}}
							</view>
						</view>

						<view class="row">
							<text class="label">标签：</text>
							<view class="value tabs">
								<view class="tab" v-for="tab in currentInfo.tabs" :key="tab">
									{{tab}}
								</view>
							</view>
						</view>
						
						
						<view class="copyright">
							声明：本图片来用户投稿，非商业使用，用于免费学习交流，如侵犯了您的权益，您可以拷贝壁纸ID举报至平台，邮箱513894357@qq.com，管理将删除侵权壁纸，维护您的权益。
						</view>

						<!-- 自己手动加一个安全距离 -->
						<view class="safe-area-inset-bottom"></view>
					</view>
				</scroll-view>
			</view>
		</uni-popup>


		<!-- :is-mask-click  表示与不允许你点击旁边的蒙版进行关闭弹窗 -->
		<uni-popup ref="scorePopup" :is-mask-click="false">
			<view class="scorePopup">
				<!-- 头部 -->
				<view class="popHeader">
					<!-- 空占位区，用于flex布局的分布 -->
					<view></view>
					<view class="title">{{isScore?'已经评分过了~':'壁纸评分'}}</view>
					<view class="close" @click="clickScoreClose">
						<uni-icons type="closeempty" size="18" color="#999"></uni-icons>
					</view>
				</view>

				<!-- 中部内容-评分区 -->
				<view class="content">
					<!-- allowHalf  允许评分一半 -->
					<uni-rate v-model="userScore" @change="onChange" :disabled="isScore" disabled-color="#FFCA3E"
						allowHalf />
					<text class="text">{{userScore}}分</text>
				</view>

				<!-- 底部内容-确认按钮 -->
				<view class="footer">
					<button @click="submitScore" :disabled="!userScore || isScore" type="default" size="mini"
						plain>确认评分</button>
				</view>

			</view>
		</uni-popup>

		<!-- <view class="">{{readImgs}}</view> -->

	</view>
</template>

<script setup>
	import {
		ref
	} from "vue"
	import {
		getPreviewBarHeight
	} from "@/utils/system.js"
	import {
		onLoad
	} from "@dcloudio/uni-app"
	import {
		apiGetSetScore,
		apiWriteDownload
	} from "@/api/apis.js"
	// import { fail } from "assert";
import {apiDetailWall} from "@/api/apis.js"
import {onShareAppMessage,onShareTimeline} from "@dcloudio/uni-app"
	
	const maskState = ref(true);
	//信息弹窗
	const infoPopup = ref(null)
	//当前图片的具体信息内容
	const currentInfo = ref({})
	//评分弹窗
	const scorePopup = ref(null)
	//用户评分，v-model双向绑定
	const userScore = ref(0)
	//用户是否评完分了
	const isScore = ref(false)
	//对应分类的图片列表
	const classList = ref([])
	//当前图片的id
	const currentId = ref(null)
	//通过当前图片id获得的当前图片的index
	const currentIndex = ref(0)
	//已经看过的图片的索引数组
	const readImgs = ref([])


	//读取缓存里面的内容
	//后面加一个空数组的原因是为了防止缓存里面没数据时用map会报错.
	const storgClassList = uni.getStorageSync("storgClassList") || [];
	classList.value = storgClassList.map(item => {
		// 如果直接return item 的话,item里面所有的属性都会不见
		// ...item的意思是就是将item里面的所有东西原模原样的全部拷贝到我们新return出来的数据
		return {
			...item,
			//注意 _small.webp是小图,要看大图的话,需要将后缀改变成.jpg
			picurl: item.smallPicurl.replace("_small.webp", ".jpg")
		}
		console.log(classList.value);
	})

	//onLoad方法获得页面传入的参数
	onLoad(async (e) => {
		// console.log(e);
		//当前图片的id
		currentId.value = e.id
		
		// 判断用户是不是通过分享页面进来的
		if(e.type == 'share'){
			// apiDetailWall()这个函数需要一个接收图片的id
			let res = await apiDetailWall({id:currentId.value})
			//将返回对象的内容全部复制给classList.value，并修改picurl
			classList.value = res.data.map(item =>{
				return {
					...item,
					picurl:item.smallPicurl.replace("_small.webp", ".jpg")
				}
			})
		}
		

		
		// 注意：使用 _id 而不是 id，并确保类型匹配
		//根据id找在数组中的索引
		currentIndex.value = classList.value.findIndex(item => item._id == currentId.value)
		// 预先加载和去重
		readImgsFun()
		currentInfo.value = classList.value[currentIndex.value]
	})


	//swiper的页面滑动时会触发swiper的change事件,有对象传入
	const swiperChange = (e) => {
		currentIndex.value = e.detail.current
		// console.log(e);
		readImgsFun()
		currentInfo.value = classList.value[currentIndex.value]
	}

	//普通状态就是加载临近左右的两张图片，包自己共三张
	//必须考虑加载页面时  第一页要加载最后一页 和 最后一页 要加载第一页的情况。
	const readImgsFun = () => {
		readImgs.value.push(
			currentIndex.value <= 0 ? classList.value.length - 1 : currentIndex.value - 1,
			currentIndex.value,
			currentIndex.value >= classList.value.length - 1 ? 0 : currentIndex.value + 1
		)

		//new Set()  可以保持数组的唯一性。但是new Set 后的结果是一个 new Set对象
		//因此我们需要将其转换为数组对象。因此对其使用  [...]
		//  ... 是展开运算符。将对象所有可枚举的属性逐一展开并复制到新对象中
		//  []  是将其转换为数组对象
		readImgs.value = [...new Set(readImgs.value)]

	}

	//点击info弹窗
	const clickInfo = () => {
		infoPopup.value.open();
	}
	//点击关闭info弹窗
	const clickInfoClose = () => {
		infoPopup.value.close();
	}

	//评分弹窗
	const clickScore = () => {
		// 判断本地是否存在这个userScore，来表明用户是否评过分了
		if (currentInfo.value.userScore) {
			isScore.value = true
			//如果已经评完分了，将评过的分数赋值给展示的分数
			userScore.value = currentInfo.value.userScore
		}
		scorePopup.value.open();
	}
	//点击关闭评分弹窗
	const clickScoreClose = () => {
		scorePopup.value.close();
		userScore.value = 0
		//复原思想，将这个flag变回原来的信息，展示的时候再变回来，可以免去许多的bug
		isScore.value = false
	}

	//确认评分
	const submitScore = async () => {
		// console.log("评分了");
		uni.showLoading({
			title: "加载中...",
		})
		//冒号的作用是将后面的名字作为当前名字的别名。两字名字都代表同个东西
		let {
			classid,
			_id: wallId
		} = currentInfo.value
		// 用户的评分作为参数传入，userScore是一个v-model
		let res = await apiGetSetScore({
			classid,
			wallId,
			userScore: userScore.value
		})
		uni.hideLoading();
		// console.log(res);
		if (res.errCode === 0) {
			uni.showToast({
				title: "评分成功",
				icon: "none"
			})
		}
		//classList.value[currentIndex.value] 表示找到这个数组里的这个对象
		// .userScore  表示给这个对象加一个 userScore  属性
		classList.value[currentIndex.value].userScore = userScore.value;
		//然后将这个新的 classList 保存到本地
		uni.setStorageSync("storgClassList", classList.value)
		clickScoreClose()
	}

	//遮罩层状态
	const maskChange = () => {
		maskState.value = !maskState.value
	}

	//返回上一页
	const goBack = () => {
		uni.navigateBack({
			success: () => {
				
			},
			fail:(err) => {
				uni.reLaunch({
					url:"/pages/index/index"
				})
			}
		})
	}

	// 文件下载
	const clickDownload = async () => {
		// #ifdef H5
		uni.showModal({
			content: "请长按保存壁纸",
			showCancel: false
		})
		// #endif

		// #ifndef H5
		try {
			
			uni.showLoading({
				title: "下载中...",
				// 显示过程中不允许点击其他的东西
				mask: true
			})

			let {
				classid,
				_id: wallId
			} = currentInfo.value
			let res = await apiWriteDownload({
				classid,
				wallId
			})

			/* != 表示5s内重复下载了
			（人家接口设计的,5s内重复下载就提示这个东西，5s内只能下载一次 */
			if (res.errCode != 0) {
				throw res
			}

			uni.getImageInfo({
				// 这个getImageInfo是为了根据网络地址获得一个临时下载地址，以便能够下载到相册里面
				//单纯的使用 saveImageToPhotosAlbum  是不能够保存图片的
				src: currentInfo.value.picurl,
				success: (res) => {
					uni.saveImageToPhotosAlbum({
						filePath: res.path,
						success: (res) => {
							// console.log(res);
							uni.showToast({
								title:"保存成功，请到相册查看",
								icon:"none"
							})
						},
						fail: (err) => {
							/* 下面这个情况是针对用户点击“下载”之后，但是没有保存时出现的
							情况，，取消保存错误信息是fail cancel ，没有授权是fail auth deny */
							if (err.errMsg == 'saveImagePhotoAlbum:fail cancel') {
								uni.showToast({
									title: "保存失败，请重新点击下载",
									icon: "none"
								})
								//此时return 是为了结束步骤。不能继续进行到下面的代码当中
								return;
							}
							uni.showModal({
								title: "授权提示",
								content: "需要授权保存相册",
								//success表示系统回复了的情况
								success: res => {
									//这里表示点击了“确认"的情况
									if (res.confirm) {
										uni.openSetting({
											success: setting => {
												console.log(
													setting);
												/* setting.authSetting['scope.writePhotosAlbum']
												表示的是你   "是否授权的值（true / false"   */
												if (setting
													.authSetting[
														'scope.writePhotosAlbum'
														]) {
													uni.showToast({
														title: "获取授权成功",
														icon: "none"
													})
												} else {
													uni.showToast({
														title: "获取权限失败",
														icon: "none"
													})
												}
											}
										})
									}
								}
							})

						},
						//complete表示无论成功还是失败都会做的事件
						complete: () => {
							uni.hideLoading();
						}
					})

				}
			})

		} catch (err)  {
			uni.hideLoading()
		}
		// #endif
	}
	
//分享给好友
onShareAppMessage((e)=>{
	//分享这里是需要有一个  “return” 的
	
	//在上面的onLoad中，已经将列表的id赋给了queryParams的id属性
	return{
		title:"hzb壁纸-",
		// 必须传递id进去，否则进不去内部页面
		path:"/pages/preview/preview?id="+currentId.value+"&type=share"
	}
})

//分享到朋友圈
onShareTimeline(()=>{
	return{
		// 标题
		title:"hzb壁纸~~~",
		// 分享时候的图片地址。可以本地也可以网络图
		// imageUrl:"/static/images/logo2.jpg"
		//要想看朋友圈这个，需要带的query参数
		// type表示是分享传入的
		query:"id="+currentId.value+"&type=share"
	}
})
	
</script>

<style lang="scss" scoped>
	@import '../../uni.scss';
	// @include fix-position就是下面的这堆东西
	// position: absolute;
	// left: 0;
	// right: 0;
	// //单纯的给margin：auto的话，你的宽度会被拉长，需要给一个固定宽度
	// margin: auto;
	// //宽度你给多少都不能准确到达中间位置，给一个fit-content自动适应
	// width:fit-content;
	// color: #fff;

	.preview {
		width: 100%;
		height: 100vh;
		position: relative;

		swiper {
			width: 100%;
			height: 100%;

			image {
				width: 100%;
				height: 100%;
			}
		}

		.mask {
			.goBack {
				@include fix-position;
				width: 38px;
				height: 38px;
				background: rgba(0, 0, 0, 0.5);
				left: 30rpx;
				top: 0;
				margin-left: 0;
				border-radius: 100px;
				backdrop-filter: blur(10rpx);
				border: 1px solid rbga(255, 255, 255, 0.3);
				display: flex;
				justify-content: center;
				align-items: center;
			}

			.count {
				position: absolute;
				top: 10vh;
				left: 0;
				right: 0;
				//单纯的给margin：auto的话，你的宽度会被拉长，需要给一个固定宽度
				margin: auto;
				//宽度你给多少都不能准确到达中间位置，给一个fit-content自动适应
				width: fit-content;
				background: rgba(0, 0, 0, 0.3);
				font-size: 28rpx;
				color: #fff;
				border-radius: 40rpx;
				padding: 8rpx 28rpx;
				backdrop-filter: blur(20rpx);
			}

			.time {
				@include fix-position;
				//看设计图上面的设计
				top: calc(10vh + 80rpx);
				font-size: 140rpx;
				font-weight: 100rpx;
				//去除行高
				line-height: 1em;
				//加上文字阴影，避免图片是白色是时候你看不到文字
				text-shadow: 0 4rpx rgba(0, 0, 0, 0.3);
			}

			.date {
				@include fix-position;
				top: calc(10vh + 230rpx);
				font-size: 34rpx;
				//加上文字阴影，避免图片是白色是时候你看不到文字
				text-shadow: 0 2rpx rgba(0, 0, 0, 0.3);
			}

			.footer {
				@include fix-position;
				background: rgba(255, 255, 255, 0.8);
				bottom: 10vh;
				width: 65vw;
				height: 120rpx;
				border-radius: 120rpx;
				color: #000;
				display: flex;
				justify-content: space-around;
				align-items: center;
				box-shadow: 0 2rpx rgba(0, 0, 0, 0.1);
				backdrop-filter: blur(20rpx);

				//使文字和样式在同一列上
				.box {
					display: flex;
					flex-direction: column;
					justify-content: center;
					align-items: center;
					//给box加padding，增大接触距离
					padding: 2rpx 12rpx;

					.text {
						font-size: 26rpx;
						color: $text-font-color-2;
					}
				}
			}
		}

		.popHeader {
			display: flex;
			justify-content: space-between;
			align-items: center;

			.title {
				color: $text-font-color-2;
				font-size: 26rpx;
			}

			.close {
				// 细节处理，增大图标接触面积，提高用户体验
				padding: 6rpx
			}
		}

		.infoPopup {
			background: #fff;
			padding: 30rpx;
			border-radius: 30rpx 30rpx 0 0;
			overflow: hidden;

			scroll-view {
				max-height: 60vh;

				.content {
					.row {
						display: flex;
						padding: 16rpx 0;
						font-size: 32rpx;
						// 行高控制
						line-height: 1.7em;

						.label {
							color: $text-font-color-3;
							width: 140rpx;
							//文字靠右，就是word里面的右对齐
							text-align: right;
							font-size: 30rpx;
						}

						.value {
							//上面父级已经给了宽度了，你子级就可以给一个flex：1来让其自动分配
							flex: 1;
							//因为可能  value的值可能很多，会把label挤压，所以加一个兼容性写法，宽度为0
							width: 0;
							font-size: 30rpx;
						}

						.roteBox {
							display: flex;
							align-items: center;

							.score {
								font-size: 26rpx;
								color: $text-font-color-2 ;
								padding-left: 10rpx;
							}
						}

						.tabs {
							display: flex;
							white-space: wrap;

							.tab {
								border: 1px solid $brand-theme-color;
								color: $brand-theme-color;
								font-size: 22rpx;
								padding: 10rpx 30rpx;
								;
								border-radius: 40rpx;
								line-height: 1em;
								margin: 0 10rpx 10rpx 0;
							}
						}

						.class {
							color: $brand-theme-color;
						}
					}

					.copyright {
						font-size: 28rpx;
						padding: 20rpx;
						background: #F6F6F6;
						color: #666;
						border-radius: 10rpx;
						margin: 20rpx 0;
						line-height: 1.5em;
					}
				}
			}
		}

		.scorePopup {
			background: #fff;
			padding: 30rpx;
			width: 70vw;
			border-radius: 30rpx;
			overflow: hidden;

			.content {
				padding: 30rpx 0;
				display: flex;
				justify-content: center;
				align-items: center;

				.text {
					color: #FFCA3E;
					padding-left: 10rpx;
					width: 80rpx;
					line-height: 1em;
					text-align: right;
				}
			}

			.footer {
				display: flex;
				justify-content: center;
				align-items: center;
			}

		}
	}
</style>