<template>
	<view class=" content ">
		<mescroll-body bottom="0" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
			:down="downOption" :up="upOption">
			<view class="list">
				<view class="list-item" @click="goLive(item)" v-for="(item,index) in list" :key="index">

					<!-- <image :src="item.liveImgUrl"></image> -->


					<video v-if="item.flvHlsUrl && item.liveId" :id="'myVideo_' + item.liveId" :src="item.flvHlsUrl"
						:autoplay="false" :controls='false' object-fit='contain' :custom-cache="false"
						:enable-progress-gesture="false" vslide-gesture-in-fullscreen='true'
						:show-center-play-btn="false" :http-cache="false" @error="videoError">
					</video>

					<video v-if="item.videoUrl" :src="item.videoUrl" :autoplay="false" :controls='false'
						object-fit='contain' :custom-cache="false" :enable-progress-gesture="false"
						vslide-gesture-in-fullscreen='true' :show-center-play-btn="false" :http-cache="false" loop
						@error="videoError">
					</video>

					<view class="info">
						<text>{{item.liveName}}</text>
					</view>
				</view>

			</view>
		</mescroll-body>
	</view>

</template>
<script>
	import Hls from 'hls.js';
	import {
		liveList
	} from '@/api/list'
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {

				hlsPlayer: null, // HLS播放器实例,
				// 统一直播/录播类型标识
				LIVE_TYPE: {
					LIVE: 1, // 直播
					RECORD: 2 // 录播
				},





				list: [],
				liveId: null, // mescroll配置
				downOption: {
					offset: 80,
					use: true,
					auto: false // 是否在初始化后自动执行下拉回调
				},
				upOption: {
					use: true,
					auto: true, // 是否在初始化时自动执行上拉回调
					page: {
						num: 0, // 当前页码
						size: 10 // 每页数据条数
					}

				},
				mescroll: null // mescroll实例
			}
		},
		onLoad() {
			if (!uni.getStorageSync("AppToken")) {
				uni.navigateTo({
					url: '/pages/auth/login'
				});

			} // 销毁HLS播放器（如果使用了hls.js）
			if (this.hlsPlayer) {
				this.hlsPlayer.destroy();
				this.hlsPlayer = null;
			}
		},
		onUnload() {
			this.list.forEach(item => {
				this.$set(item, 'isDestroyed', true); // 标记已销毁，阻止播放
				this.pauseAndCleanVideo(item); // 统一清理
			});
		},
		methods: { // 处理单个视频项，适配m3u8流
			initVideoPlayer(item) {
				// 基础校验：无地址/无ID，不初始化
				const isLive = item.liveType === 1;
				const hasValidUrl = isLive ? (item.flvHlsUrl?.includes('.m3u8')) : !!item.videoUrl;
				if (!hasValidUrl || !item.liveId) return;

				const videoId = `myVideo_${item.liveId}`;
				console.log(`[视口监听] 初始化：${videoId}`);

				// 1. 创建交叉观察器（监听是否进入视口）
				const observer = uni.createIntersectionObserver(this, {
					thresholds: [0.2], // 20% 进入视口触发
					observeAll: false
				});

				// 2. 监听视口状态，触发按需播放/暂停
				observer.relativeTo('.list').observe(`#${videoId}`, (res) => {
					const isInView = res.intersectionRatio > 0; // 是否在视口内

					if (isInView) {
						console.log(`[视口监听] 进入视口，触发按需播放：${videoId}`);
						// 标记为在视口，避免重复调用
						this.$set(item, 'isInView', true);
						// 调用统一播放入口，实现按需播放
						this.setupVideoPlayback(item);
					} else {
						console.log(`[视口监听] 离开视口，暂停播放：${videoId}`);
						// 标记为离开视口
						this.$set(item, 'isInView', false);
						// 暂停播放并清理资源
						this.pauseAndCleanVideo(item);
					}
				});

				// 3. 存储观察器到 item，便于后续销毁
				this.$set(item, 'observer', observer);
				// 标记未销毁，避免 setupVideoPlayback 跳过
				this.$set(item, 'isDestroyed', false);
			},
			pauseAndCleanVideo(item) {
				// 1. 暂停录播/小程序直播（通过 videoContext）
				if (item.videoContext) {
					item.videoContext.pause();
					this.$set(item, 'videoContext', null); // 清空上下文，避免重复调用
				}

				// 2. 销毁 HLS 实例（直播 H5 场景）
				if (item.hlsInstance) {
					item.hlsInstance.destroy();
					this.$set(item, 'hlsInstance', null);
				}

				// 3. 销毁视口监听（避免列表刷新后仍监听）
				if (item.observer) {
					item.observer.disconnect();
					this.$set(item, 'observer', null);
				}

				// 4. 标记为已销毁（防止重复初始化）
				this.$set(item, 'isDestroyed', true);
			},

			setupVideoPlayback(item) {
				// 1. 基础校验：先判断类型，再校验 URL（避免无效执行）
				const isLive = item.liveType === this.LIVE_TYPE.LIVE;
				const videoUrl = isLive ? item.flvHlsUrl : item.videoUrl;

				// 无效场景直接返回（录播无URL、直播无m3u8、已销毁）
				if (!videoUrl || item.isDestroyed || (isLive && !videoUrl.includes('.m3u8'))) {
					console.warn(`[播放校验] 跳过无效播放：`, item.liveId, '类型：', isLive ? '直播' : '录播');
					return;
				}

				const videoId = `myVideo_${item.liveId}`;
				console.log(`[按需播放] 触发：${isLive ? '直播' : '录播'}，ID：${videoId}`);

				// 2. 先清理旧资源（避免重复初始化）
				this.pauseAndCleanVideo(item);

				// 3. 直播逻辑：仅 H5 平台用 HLS，其他平台（小程序/App）用原生 video
				if (isLive) {
					// #ifdef H5
					// 直播 + H5 + m3u8：初始化 HLS
					this.initHlsPlayer(item);
					// #endif

					// #ifndef H5
					// 小程序/App 直播：直接用原生 videoContext（无需 HLS，平台自带 m3u8 支持）
					this.initNativeVideo(item, videoId, isLive);
					// #endif
				} else {
					// 4. 录播逻辑：所有平台统一用原生 videoContext（无需 HLS）
					this.initNativeVideo(item, videoId, isLive);
				}
			},
			/**
			 * 初始化原生视频（录播 + 小程序/App 直播）
			 * @param {Object} item - 列表项数据
			 * @param {String} videoId - 视频DOM ID
			 * @param {Boolean} isLive - 是否为直播
			 */
			initNativeVideo(item, videoId, isLive) {
				uni.createSelectorQuery().in(this)
					.select(`#${videoId}`)
					.fields({
						context: true
					}) // 仅获取视频上下文
					.exec((res) => {
						if (!res || !res[0]?.context) {
							console.warn(`[原生视频] 未找到上下文：${videoId}`);
							return;
						}

						const videoContext = res[0].context;
						this.$set(item, 'videoContext', videoContext); // 存储上下文，用于后续暂停

						// 直播：直接播放（需用户交互，失败时提示）
						if (isLive) {
							videoContext.play().catch(err => {
								console.log(`[直播播放] 自动播放失败（需点击）：${item.liveId}`, err);
								// 可选：添加「播放按钮」，点击后调用 videoContext.play()
							});
						}
						// 录播：支持断点续播（从上次进度开始）
						else {
							const startDuration = item.nowDuration || 0; // 从接口获取的上次播放进度
							videoContext.seek(startDuration); // 跳转到指定进度
							videoContext.play().catch(err => {
								console.log(`[录播播放] 失败：${item.liveId}`, err);
							});
						}
					});
			},

			// 初始化HLS播放器
			initHlsPlayer(item) {
				// 兜底校验：确保是直播且有 m3u8 地址
				if (item.liveType !== this.LIVE_TYPE.LIVE || !item.flvHlsUrl?.includes('.m3u8')) {
					console.error(`[HLS 错误] 非直播场景调用：${item.liveId}`);
					return;
				}

				const videoUrl = item.flvHlsUrl;
				if (!Hls.isSupported()) {
					console.error(`[HLS 错误] 浏览器不支持 HLS：${item.liveId}`);
					return;
				}

				// 获取 H5 视频 DOM 节点
				const video = document.getElementById(`myVideo_${item.liveId}`);
				if (!video) {
					console.warn(`[HLS 错误] 未找到视频节点：myVideo_${item.liveId}`);
					return;
				}

				// 初始化 HLS（低延迟配置，适合直播）
				const hls = new Hls({
					enableWorker: true,
					lowLatencyMode: true, // 直播低延迟关键配置
					debug: false,
					maxBufferLength: 3, // 减少缓冲，降低延迟（根据需求调整）
					maxMaxBufferLength: 10
				});

				// 绑定视频节点 + 加载流
				hls.attachMedia(video);
				hls.loadSource(videoUrl);

				// 解析成功后播放
				hls.on(Hls.Events.MANIFEST_PARSED, () => {
					console.log(`[HLS 直播] 解析成功：${item.liveId}`);
					video.play().catch(err => {
						console.log(`[HLS 播放] 自动播放失败（需点击）：${item.liveId}`, err);
					});
				});

				// 错误处理（自动恢复或销毁）
				hls.on(Hls.Events.ERROR, (event, data) => {
					console.error(`[HLS 错误] ${item.liveId}：`, data);
					if (data.fatal) {
						switch (data.type) {
							case Hls.ErrorTypes.NETWORK_ERROR:
								hls.startLoad(); // 网络错误：重试加载
								break;
							default:
								hls.destroy(); // 其他致命错误：销毁实例
								this.$set(item, 'hlsInstance', null);
								break;
						}
					}
				});

				// 存储 HLS 实例到 item（便于后续销毁）
				this.$set(item, 'hlsInstance', hls);
			},


			// mescroll初始化
			mescrollInit(mescroll) {
				this.mescroll = mescroll;
			},
			// 下拉刷新回调
			downCallback(mescroll) {
				// 1. 先清理所有旧列表的视频资源（直播 HLS + 录播上下文）
				this.list.forEach(item => {
					this.pauseAndCleanVideo(item);
				});

				// 2. 重置列表和分页（必须在清理后执行）
				this.list = [];
				mescroll.resetUpScroll(); // 重置上拉加载的页码

				// 3. 可选：下拉后自动加载第一页（符合用户预期）
				this.mescroll.triggerUpScroll();
			},
			// 上拉加载回调
			upCallback(mescroll) {
				const pageNum = mescroll.num;
				const pageSize = mescroll.size;

				let data = {
					pageSize: pageSize,
					page: pageNum,
				}

				liveList(data).then(res => {
					if (res.code == 200) {
						let curPageData = res.rows || [];
						let totalSize = res.total || 0;

						if (pageNum === 1) {
							this.list = [];
						}

						// 追加新数据
					 this.list = this.list.concat(curPageData);

      // 关键修改：用 $nextTick 等待DOM渲染完成
      this.$nextTick(() => {
        curPageData.forEach(item => {
          this.initVideoPlayer(item); // 此时视频节点已存在
        });
      });

      mescroll.endBySize(curPageData.length, totalSize);
    } else {
						mescroll.endErr();
						uni.showToast({
							title: res.msg,
							icon: 'none'
						});
					}
				}).catch(err => {
					mescroll.endErr();
					console.log("请求异常:" + JSON.stringify(err));
				});
			},




			goLive(item) {
				this.liveId = item.liveId
				console.log("要传的liveId", this.liveId)
				uni.navigateTo({
					url: `/pages/home/living?liveId=${item.liveId}&immediate=true`
				});
			},

			// getList() {
			// 	const data = {
			// 		page: 1,
			// 		page_size: 10,
			// 	};
			// 	uni.showLoading({
			// 		title: "处理中..."
			// 	});
			// 	liveList(data)
			// 		.then(res => {
			// 			if (res.code == 200) {
			// 				this.list = res.rows; // 直接赋值给 this.list
			// 				console.log("list>>", this.list); // ✅ 打印已定义的 this.list
			// 			} else {
			// 				uni.showToast({
			// 					title: res.msg,
			// 					icon: 'none'
			// 				});
			// 			}
			// 		})
			// 		.catch(rej => {
			// 			console.log("请求失败:", JSON.stringify(rej));
			// 		})
			// 		.finally(() => {
			// 			uni.hideLoading();
			// 		});
			// }
		}
	}
</script>

<style lang="scss" scoped>
	.content {
		background-color: #111;
		min-height: 100vh;
		padding: 24rpx;

		.list {
			display: flex;
			justify-content: space-between;
			flex-wrap: wrap;

			.list-item {
				border-radius: 16rpx;
				width: 340rpx;
				height: 600rpx;
				background-color: #0d0d0d;
				margin-right: 10rpx;
				margin-bottom: 24rpx;
				overflow: hidden;
				position: relative;

				video {
					width: 100%;
					height: 100%;
					/* 视频填满列表项，确保可视区域判断准确 */
				}

				.info {
					position: absolute;
					left: 20rpx;
					bottom: 14rpx;
					color: #ffffff;
				}

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

			}
		}

	}
</style>