<template>
	<u-popup :show="show" round="40rpx" @close="handleClose">
		<view class="channel-container">
			<!-- 我的频道区域 -->
			<view class="channel-section">
				<view class="section-header">
					<view class="left">
						<text class="section-title">我的频道</text>
						<text class="txt">拖拽可以排序</text>
					</view>
					<image class="w40 h40" src="https://cdn.his.cdwjyyh.com/images/pop_close_icon.png" @click="$emit('close')"></image>
				</view>
				<!-- 拖拽容器 -->
				<view class="channel-list" id="channelList">
					<view v-for="(item, index) in myChannels" :key="item.id" class="channel-item"
						:style="{ width: itemWidth + 'px' }" @touchstart="handleTouchStart(index, $event)"
						@touchmove="(e) => handleMove(e, index)" @touchend="handleEnd" @touchcancel="handleEnd">
						<!-- 拖拽中的元素特殊样式 -->
						<view class="channel-content" :class="{ 
					      'drag-item': isDragging && dragIndex === index 
					    }" :style="{
					      transform: isDragging && dragIndex === index 
					        ? `translate(${dragOffsetX}px, ${dragOffsetY}px) scale(1.05)` 
					        : 'none',
					      zIndex: isDragging && dragIndex === index ? 999 : 1,
					      opacity: isDragging && dragIndex === index ? 0.9 : 1,
					      transition: isDragging && dragIndex === index ? 'none' : 'all 0.15s ease-out'
					    }" @tap="handleChannelTap(item)">
							<text>{{ item.name }}</text>
							<image v-if="index !== 0" class="delete-icon" src="https://cdn.his.cdwjyyh.com/images/remove_icon.png"
								@tap.stop="removeFromMyChannels(index)"/>
							</view>

						<!-- 拖拽占位符-->
						<!-- <view v-if="isDragging && placeholderIndex === index" class="channel-placeholder"></view> -->
					</view>
				</view>
			</view>

			<!-- 全部频道区域 -->
			<view class="channel-section">
				<view class="section-header">
					<text class="section-title">全部频道</text>
				</view>
				<view class="channel-list">
					<view v-for="(item, index) in allChannels" :key="item.id" class="channel-item"
						:style="{ width: itemWidth + 'px' }">
						<view class="channel-content" :class="isChannelInMyList(item.id)?'active':''">
							<text>{{ item.name }}</text>
							<!-- 保留添加图标 -->
							<image v-if="!isChannelInMyList(item.id)" class="add-icon" src="https://cdn.his.cdwjyyh.com/images/add_icon.png"
								@tap="addToMyChannels(item)">
							</image>
						</view>
					</view>
				</view>
			</view>
			<view class="success" @click="handleClose">完成</view>
		</view>
	</u-popup>
</template>
<script>
	import {
		getMyProductCate,
		channelAdd,
		channelDelete
	} from "@/api/index.js"
	export default {
		props: {
			show: {
				type: Boolean,
				default: false
			},
			initialMyChannels: {
				type: Array,
				default: () => []
			},
			initialAllChannels: {
				type: Array,
				default: () => []
			},
			activeChannelId: {
				type: [String, Number],
				default: ''
			},
			itemWidth: {
				type: Number,
				default: 80
			}
		},
		data() {
			return {
				// show: true,
				myChannels: [],
				allChannels: [],
				activeChannel: '',
				isDragging: false,
				dragIndex: -1, // 正在拖拽的索引
				placeholderIndex: -1, // 占位符索引
				startX: 0, // 触摸初始X
				startY: 0, // 触摸初始Y
				elementLeft: 0, // 元素初始左坐标
				elementTop: 0, // 元素初始上坐标
				dragOffsetX: 0, // 拖拽偏移X
				dragOffsetY: 0, // 拖拽偏移Y
				itemHeight: 60, // 频道项高度
				colCount: 0, // 每行显示列数
				itemRects: [], // 所有频道项的位置信息
				dragThreshold: 3, // 降低触发阈值，更灵敏
				lastSwapTime: 0, // 防抖：记录上次交换时间
				touchStartTime: 0, // 触摸开始时间
				rectTimer: null // 计算位置的定时器
			};
		},
		watch: { // 监听 show 属性的变化
			show: {
				immediate: true,
				handler(newVal) {
					// 如果需要，可以在这里处理显示/隐藏的逻辑
				}
			},
			activeChannelId: {
				immediate: true,
				handler(newVal) {
					this.activeChannel = newVal;
				}
			},
			initialMyChannels: {
				immediate: true,
				handler(newVal) {
					this.myChannels = JSON.parse(JSON.stringify(newVal));
					this.$nextTick(() => this.calcItemRects());
				}
			},
			initialAllChannels: {
				immediate: true,
				handler(newVal) {
					this.allChannels = JSON.parse(JSON.stringify(newVal));
				}
			}
		},
		mounted() {
			this.$nextTick(() => this.calcItemRects());
			// 组件挂载时获取我的频道
			this.getMyChannels();
		},
		methods: {
			// 获取我的频道
			getMyChannels() {
				getMyProductCate().then(
					res => {
						if (res.code == 200) {
							console.log("获取我的频道", res.data);
							// 更新我的频道列表
							if (res.data && res.data.length > 0) {
								// 将返回的数据转换为频道需要的格式
								const channels = res.data.map(item => ({
									id: item.cateId,
									name: item.cateName,
									pic: item.pic,
									isSelect: item.isSelect
								}));
								// 更新全部频道列表
								this.allChannels = channels;
								// 保持我的频道列表不变，使用父组件传递的初始值
								// 或者根据 isSelect 字段过滤我的频道
								const myChannels = channels.filter(item => item.isSelect === 1);
								if (myChannels.length > 0) {
									this.myChannels = myChannels;
								}
								this.$nextTick(() => this.calcItemRects());
								this.$emit('channels-change', {
									myChannels: this.myChannels,
									allChannels: this.allChannels
								});
							}
						}
					},
					rej => {
						console.error("获取我的频道失败", rej);
					}
				);
			},
			// 计算所有频道项的位置信息（保留原有逻辑，优化计算精度）
			calcItemRects() {
				if (!this.myChannels.length) return;

				const query = uni.createSelectorQuery().in(this);
				query.select('#channelList').boundingClientRect(rect => {
					if (!rect) return;
					// 计算每行列数（考虑容器内边距）
					this.colCount = Math.floor((rect.width - 40) / this.itemWidth);
					// 预计算每个项的位置
					this.itemRects = this.myChannels.map((_, index) => {
						const row = Math.floor(index / this.colCount);
						const col = index % this.colCount;
						return {
							left: rect.left + 20 + col * this.itemWidth,
							top: rect.top + 20 + row * this.itemHeight,
							right: rect.left + 20 + (col + 1) * this.itemWidth,
							bottom: rect.top + 20 + (row + 1) * this.itemHeight,
							centerX: rect.left + 20 + (col + 0.5) * this.itemWidth,
							centerY: rect.top + 20 + (row + 0.5) * this.itemHeight
						};
					});
				}).exec();
			},

			// 判断频道是否已在我的列表中（保留原有功能）
			isChannelInMyList(channelId) {
				return this.myChannels.some(item => item.id === channelId);
			},

			// 添加频道到我的频道（保留原有功能）
			addToMyChannels(channel) {
				if (this.isChannelInMyList(channel.id)) return;

				// 调用添加频道API
				channelAdd(channel.id).then(
					res => {
						if (res.code == 200) {
							console.log("添加频道成功", channel);
							this.myChannels = [...this.myChannels, channel];
							this.$nextTick(() => this.calcItemRects());
							this.$emit('channels-change', {
								myChannels: this.myChannels,
								allChannels: this.allChannels
							});
						} else {
							console.error("添加频道失败", res.msg);
							uni.showToast({
								title: res.msg || '添加频道失败',
								icon: 'none'
							});
						}
					},
					rej => {
						console.error("添加频道失败", rej);
						uni.showToast({
							title: '网络错误，请重试',
							icon: 'none'
						});
					}
				);
			},

			// 从我的频道中移除（保留原有功能）
			removeFromMyChannels(index) {
				if (index === 0 || this.isDragging) return;

				const channel = this.myChannels[index];
				// 调用删除频道API
				channelDelete(channel.id).then(
					res => {
						if (res.code == 200) {
							console.log("删除频道成功", channel);
							this.myChannels.splice(index, 1);
							this.$nextTick(() => this.calcItemRects());
							this.$emit('channels-change', {
								myChannels: this.myChannels,
								allChannels: this.allChannels
							});
						} else {
							console.error("删除频道失败", res.msg);
							uni.showToast({
								title: res.msg || '删除频道失败',
								icon: 'none'
							});
						}
					},
					rej => {
						console.error("删除频道失败", rej);
						uni.showToast({
							title: '网络错误，请重试',
							icon: 'none'
						});
					}
				);
			},

			// 点击频道（保留原有功能）
			handleChannelTap(channel) {
				if (this.isDragging) return;
				this.activeChannel = channel.id;
				this.$emit('channel-tap', channel);
			},

			// ========== 以下是拖拽功能的核心优化 ==========
			// 触摸开始：记录初始信息，替代原longpress
			handleTouchStart(index, e) {
				// 第一个频道不能拖拽
				if (index === 0) return;
				this.touchStartTime = Date.now();
				const touch = e.touches[0];
				this.startX = touch.clientX;
				this.startY = touch.clientY;

				// 获取当前元素的初始位置
				const query = uni.createSelectorQuery().in(this);
				query.selectAll('.channel-item').boundingClientRect(rects => {
					const currentRect = rects[index];
					if (currentRect) {
						this.elementLeft = currentRect.left;
						this.elementTop = currentRect.top;
					}
				}).exec();
			},

			// 拖拽移动：优化跟随流畅度和交换逻辑
			handleMove(e, index) {
				if (index === 0) return;

				// 阻止页面滚动和默认行为
				e.stopPropagation();
				if (e.preventDefault) e.preventDefault();
				else e.returnValue = false;

				const touch = e.touches[0];
				const currentX = touch.clientX;
				const currentY = touch.clientY;

				// 未进入拖拽状态：判断是否触发拖拽（移动距离+触摸时间）
				if (!this.isDragging) {
					const moveDistance = Math.hypot(currentX - this.startX, currentY - this.startY);
					const touchTime = Date.now() - this.touchStartTime;
					// 移动超过阈值+触摸时间>80ms，触发拖拽（避免误触）
					if (moveDistance >= this.dragThreshold && touchTime > 80) {
						this.isDragging = true;
						this.dragIndex = index;
						this.placeholderIndex = index;
						this.lastSwapTime = Date.now();
						// 实时计算位置
						this.calcItemRects();
					} else {
						return;
					}
				}

				// 计算偏移量：基于元素初始位置，跟随更丝滑
				this.dragOffsetX = currentX - this.elementLeft;
				this.dragOffsetY = currentY - this.elementTop;

				// 防抖交换：15ms内只交换一次，避免卡顿
				const now = Date.now();
				if (now - this.lastSwapTime > 15) {
					this.swapChannelItem(currentX, currentY);
					this.lastSwapTime = now;
				}
			},

			// 交换频道项：优化碰撞检测，精准交换
			swapChannelItem(x, y) {
				if (this.itemRects.length === 0) return;

				// 找到当前触摸点对应的目标项
				let targetIndex = -1;
				for (let i = 1; i < this.myChannels.length; i++) {
					const rect = this.itemRects[i];
					// 扩大检测范围，更容易触发交换
					if (x >= rect.left - 5 && x <= rect.right + 5 && y >= rect.top - 5 && y <= rect.bottom + 5) {
						targetIndex = i;
						break;
					}
				}

				// 交换逻辑：只在目标不同时执行
				if (targetIndex !== -1 && targetIndex !== this.placeholderIndex) {
					// 交换数组元素
					[this.myChannels[this.dragIndex], this.myChannels[targetIndex]] = [this.myChannels[targetIndex], this
						.myChannels[this.dragIndex]
					];
					// 更新占位符和拖拽索引
					this.placeholderIndex = targetIndex;
					this.dragIndex = targetIndex;
					// 更新元素初始位置，让拖拽跟随更准确
					this.elementLeft = this.itemRects[targetIndex].left;
					this.elementTop = this.itemRects[targetIndex].top;

					// 延迟计算位置，避免频繁DOM查询
					if (!this.rectTimer) {
						this.rectTimer = setTimeout(() => {
							this.calcItemRects();
							clearTimeout(this.rectTimer);
							this.rectTimer = null;
						}, 30);
					}
				}
			},

			// 拖拽结束/取消：重置状态（保留原有逻辑，优化定时器清理）
			handleEnd() {
				if (!this.isDragging) return;

				// 清理定时器
				if (this.rectTimer) {
					clearTimeout(this.rectTimer);
					this.rectTimer = null;
				}

				// 重置拖拽状态
				this.isDragging = false;
				this.dragIndex = -1;
				this.placeholderIndex = -1;
				this.dragOffsetX = 0;
				this.dragOffsetY = 0;
				this.startX = 0;
				this.startY = 0;
				this.elementLeft = 0;
				this.elementTop = 0;

				// 保存顺序
				this.saveChannelOrder();
			},

			// 保存频道顺序（保留原有功能）
			saveChannelOrder() {
				this.$emit('order-change', JSON.parse(JSON.stringify(this.myChannels)));
				this.$emit('channels-change', {
					myChannels: this.myChannels,
					allChannels: this.allChannels
				});
			},

			// 关闭弹窗（保留原有功能）
			handleClose() {
				this.$emit('update:show', false); // 通知父组件关闭
				this.$emit('close');
			}
		}
	};
</script>

<style scoped lang="scss">
	// 保留你所有的样式，仅优化拖拽相关的样式
	.channel-container {
		border-radius: 32rpx 32rpx 0rpx 0rpx;
		padding: 24rpx;
		background-color: #fff;

		.channel-section {
			margin-bottom: 40rpx;
			border-radius: 10rpx;
			overflow: hidden;

			.section-header {
				display: flex;
				align-items: center;
				justify-content: space-between;
				height: 80rpx;
				margin-bottom: 20rpx;

				.left {
					.section-title {
						font-weight: 500;
						font-size: 32rpx;
						color: #333333;
					}

					.txt {
						font-size: 24rpx;
						color: #999999;
						margin-left: 18rpx;
					}

				}

				.txt {
					font-size: 24rpx;
					color: #999;
				}
			}

			.channel-list {
				display: flex;
				flex-wrap: wrap;
				position: relative;

				.channel-item {
					position: relative;
					box-sizing: border-box;
					margin-bottom: 10rpx;
					margin-right: 18rpx;

					&:last-child {
						margin-right: 0;
					}

					.channel-content {
						width: 162rpx;
						height: 88rpx;
						background: #F5F7FA;
						border-radius: 12rpx 12rpx 12rpx 12rpx;
						position: relative;
						display: flex;
						align-items: center;
						justify-content: center;
						transition: all 0.15s ease-out;
						color: #333333;

						&.active {
							color: #999999;
						}

						// 拖拽中的元素 - 优化阴影和透明度
						&.drag-item {
							position: relative;
							// 增强阴影效果：增大阴影范围、提高不透明度，让阴影更明显
							box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.15);
							// 降低透明度，让拖拽元素有半透明效果（0.8比0.9更明显）
							opacity: 0.8;
							background-color: #fff; // 增加白色背景，让半透明效果更自然
						}

						// 图标样式 - 完全保留
						.add-icon,
						.delete-icon,
						.added-mark {
							position: absolute;
							right: -10rpx;
							top: -10rpx;
							width: 32rpx;
							height: 32rpx;
							border-radius: 50%;
							display: flex;
							align-items: center;
							justify-content: center;
							z-index: 2;
						}

						.add-icon {
							.icon-plus {
								font-size: 30rpx;
								color: #fff;
								line-height: 1;
							}
						}

						.delete-icon {
							.icon-minus {
								font-size: 36rpx;
								color: #fff;
								line-height: 1;
								margin-top: -2rpx;
							}
						}

						.added-mark {
							background-color: #d9d9d9;
							color: #999;

							.icon-check {
								font-size: 26rpx;
								color: #999;
								line-height: 1;
							}
						}
					}

					// 拖拽占位符 - 优化背景色，更贴近UI
					// .channel-placeholder {
					// 	width: 100%;
					// 	height: 60rpx;
					// 	border-radius: 30rpx;
					// 	box-sizing: border-box;
					// 	background-color: #E8EBF0;
					// }
				}
			}
		}

		.success {
			width: 100%;
			height: 88rpx;
			line-height: 88rpx;
			background: linear-gradient(136deg, #38D97D 0%, #02B176 100%);
			border-radius: 44rpx 44rpx 44rpx 44rpx;
			font-weight: 600;
			font-size: 32rpx;
			color: #FFFFFF;
			text-align: center;
		}
	}

	.w40 {
		width: 40rpx;
	}

	.h40 {
		height: 40rpx;
	}
</style>