<template>
	<view class="ranking-page">
		<nav-bar title="从夯到拉" bgColor="#F5F5F5" isRightButton :rightButtonText="rightButtonText"
			@right-click="onRightClick">
		</nav-bar>

		<view class="content-container">
			<view :class="{ 'skin-box': type == 'skin', 'table-box': type != 'skin' }"
				:style="type == 'skin' ? { backgroundColor: skinBgColor } : {}">
				<template v-if="type == 'skin'">
					<view v-if="!isEdit" class="title">{{ title }}</view>
					<input v-else class="title title-input" v-model="title" maxlength="12" placeholder="请输入排名标题" />
					<image class="img happy" src="/static/image/other/ranking/happy.png"></image>
					<image class="img sad" src="/static/image/other/ranking/sad.png"></image>
				</template>
				<image v-if="$isVip()" class="watermark" :class="{}" src="/static/image/other/card/shuiyin2.png"
					mode="heightFix">
				</image>

				<view class="ranking-table">
					<view  v-for="(item, index) in tierList" :key="index" class="ranking-row">
						<view class="label-box" :style="{ backgroundColor: item.bgColor }"
							@click="changeRowBgColor(index)">
							<!-- <text class="label-text" :class="{ 'with-stroke': item.hasStroke }"
								:style="{ color: item.textColor }">
								{{ item.label }}
							</text> -->
							<image :style="`height:60rpx;width:160rpx;`"
								:src="`/static/image/other/ranking/${type == 'skin' ? item.img + '_skin' : item.img}.png`">
							</image>
						</view>

						<view class="items-box ranking-item-list" :id="'row-' + index">
							<view v-for="(img, imgIdx) in item.images" :key="imgIdx" class="item-wrapper"
								:class="{ 'is-dragging': drag.tierIndex === index && drag.imgIdx === imgIdx }"
								:style="getDragStyle(index, imgIdx)" @touchstart="onTouchStart($event, index, imgIdx)"
								@touchmove.stop.prevent="onTouchMove" @touchend="onTouchEnd">

								<image :src="img" mode="aspectFill" class="item-img"></image>
								<view v-if="isEdit" class="del-btn" @click.stop="deleteImage(index, imgIdx)">×</view>
							</view>

							<view v-if="isEdit && item.images.length < 4" class="add-btn" @click="chooseImage(index)">
								<image class="add-icon" src="/static/image/common/add.png"></image>
							</view>
						</view>
					</view>
				</view>
			</view>

			<view class="save-action">
				<button v-if="!isEdit" class="save-btn" @click="handleSave">保存图片</button>
				<!-- 编辑模式下的全局颜色控制器 -->
				<view v-else-if="type == 'skin'" class="bottom-edit-actions">
					<view class="color-picker-wrapper">
						<view class="color-picker">
							<view v-for="color in ['#FFDFDF', '#DFF0FF', '#E0FFDF', '#FDF5C8', '#F3DFFF']" :key="color"
								class="color-dot" :style="{ backgroundColor: color }" @click="skinBgColor = color">
							</view>
						</view>
						<input v-if="false" class="hex-input" v-model="skinBgColor" placeholder="#HEX" maxlength="7" />
					</view>
					<view class="spectrum-picker" @touchstart="handleHueTouch" @touchmove.stop.prevent="handleHueTouch">
						<view class="spectrum-bar"></view>
						<view class="slider-thumb" :style="{ left: (skinHue / 360 * 100) + '%' }"></view>
					</view>

					<text class="edit-tip">点击左侧分类标签可切换背景色</text>
				</view>
			</view>
		</view>

		<view class="bottom-tabs" :style="{'margin-bottom':$store.state.safeBottomAz+'px'}">
			<view class="tab-item" :class="{ active: type == 'base' }" @click="switchType('base')">基础</view>
			<view class="tab-item" :class="{ active: type == 'skin' }" @click="switchType('skin')">皮肤</view>
		</view>

		<view class="painter-container" v-if="isSnapshot">
			<l-painter isCanvasToTempFilePath @success="onPainterSuccess"
				:css="`width:750rpx; padding: 40rpx; background-color:${type == 'skin' ? skinBgColor : '#F8F8F8'};`">
				<l-painter-view
					:css="`width: 100%; display: flex; flex-direction: column; position: relative; ${type == 'skin' ? 'padding-top: 120rpx;padding-bottom: 120rpx;' : ''}`">
					<template v-if="type == 'skin'">
						<l-painter-text :text="title"
							css="position: absolute; top: 26rpx; left: 50%; transform: translateX(-50%); font-size: 36rpx; font-weight: bold; color: #333;" />
						<l-painter-image src="/static/image/other/ranking/happy.png"
							css="position: absolute;top: 58rpx;right: 24rpx; width: 96rpx; height: 96rpx;" />
					</template>

					<l-painter-view css="border: 3rpx solid #333; background-color: #fff; width: 100%;">
						<l-painter-view v-for="(item, index) in tierList" :key="index"
							:css="`display: flex; min-height: 148rpx; border-bottom: ${index === tierList.length - 1 ? 'none' : '3rpx solid #333'};`">
							<l-painter-view
								:css="`width: 176rpx; min-height: 148rpx; background-color: ${item.bgColor}; display: flex; align-items: center; justify-content: center; border-right: 3rpx solid #333;`">
								<!-- <l-painter-text :text="item.label"
									:css="`font-size: 52rpx; font-weight: bold; color: ${item.textColor}; ${item.hasStroke ? 'text-shadow: 2rpx 2rpx 0 #000, -2rpx -2rpx 0 #000, 2rpx -2rpx 0 #000, -2rpx 2rpx 0 #000, 0 2rpx 0 #000, 0 -2rpx 0 #000, 2rpx 0 0 #000, -2rpx 0 0 #000;' : ''}`" /> -->
								<l-painter-image
									:src="`/static/image/other/ranking/${type == 'skin' ? item.img + '_skin' : item.img}.png`"
									:css="`height: 60rpx; width: 160rpx;`" mode="heightFix" />
							</l-painter-view>
							<l-painter-view
								:css="`flex: 1; display: flex; align-items: center;height: 148rpx;width:490rpx;padding:0 12rpx;`">
								<l-painter-image v-for="(img, imgIdx) in item.images" :key="imgIdx" :src="img"
									css="width: 105rpx; height: 105rpx; margin: 0 8rpx; object-fit: cover;"
									mode="aspectFill" />
							</l-painter-view>
						</l-painter-view>
					</l-painter-view>
					<l-painter-view v-if="$isVip()"
						:css="type == 'skin' ? `position: absolute;bottom: 32rpx;right: 14rpx;` : `position: absolute;top: 50%;right: 50%;transform: translate(50%, -50%);`">
						<l-painter-image src="/static/image/other/card/shuiyin2.png"
							css="width: 194rpx;height: 56rpx;" />
					</l-painter-view>
					<l-painter-image v-if="type == 'skin'" src="/static/image/other/ranking/sad.png"
						css="position: absolute;bottom: 76rpx;left: 116rpx; width: 96rpx; height: 96rpx;" />
				</l-painter-view>
			</l-painter>
		</view>
	</view>
	<!-- 水印 -->
	<view v-if="$isVip()">
		<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark', 'uni_alipay_other_ranking')">
			<image src='/static/lottie/watermark.gif' mode="widthFix" style="width:94px;height:74px;" ></image>
		</liu-drag-button>
	</view>
</template>

<script setup>
	import {
		ref,
		reactive,
		getCurrentInstance
	} from 'vue';
	import {
		onLoad
	} from '@dcloudio/uni-app';

	const {
		proxy
	} = getCurrentInstance();

	const type = ref("base");
	const title = ref("xx排名");
	const skinBgColor = ref("#FFDFDF");
	const skinHue = ref(0); // 记录色相位置
	const isSnapshot = ref(false);
	const isEdit = ref(false);
	const rightButtonText = ref("编辑");

	const tierList = ref([{
			label: '夯',
			bgColor: '#D5171C',
			img: 'hang',
			textColor: '#FFFFFF',
			hasStroke: true,
			images: [],
			width: 60,
		},
		{
			label: '顶级',
			bgColor: '#FF6A0B',
			img: 'dingji',
			textColor: '#FFFFFF',
			hasStroke: true,
			images: [],
			width: 104,
		},
		{
			label: '人上人',
			bgColor: '#FFF06A',
			img: 'renshangren',
			textColor: '#FFFFFF',
			hasStroke: true,
			images: [],
			width: 156,
		},
		{
			label: 'NPC',
			bgColor: '#FDF5C8',
			img: 'npc',
			textColor: '#FFFFFF',
			hasStroke: true,
			images: [],
			width: 110,
		},
		{
			label: '拉完了',
			bgColor: '#FFFFFF',
			img: 'lawanle',
			textColor: '#FFFFFF',
			hasStroke: true,
			images: [],
			width: 156,
		}
	]);

	// --- 生命周期：加载缓存 ---
	onLoad(() => {
		// 进入页面埋点
		proxy.$apiUserEvent('all', {
			type: 'click',
			key: 'ranking',
			value: "从夯倒拉排名"
		})
		// 获取缓存数据
		const cache = uni.getStorageSync('ranking_config_data');
		if (cache) {
			title.value = cache.title || title.value;
			type.value = cache.type || type.value;
			skinBgColor.value = cache.skinBgColor || skinBgColor.value;
			skinHue.value = cache.skinHue ?? skinHue.value;
			if (cache.tierList) tierList.value = cache.tierList;
			console.log(tierList.value);
		}
	});

	// --- 拖拽排序逻辑 ---
	const drag = reactive({
		tierIndex: -1,
		imgIdx: -1,
		startX: 0,
		startY: 0,
		moveX: 0,
		moveY: 0
	});

	// 计算拖拽样式
	const getDragStyle = (tIdx, iIdx) => {
		if (drag.tierIndex === tIdx && drag.imgIdx === iIdx) {
			return {
				transform: `translate(${drag.moveX}px, ${drag.moveY}px)`,
				zIndex: 99,
				transition: 'none'
			};
		}
		return {
			transition: 'transform 0.3s ease'
		};
	};

	const onTouchStart = (e, tIdx, iIdx) => {
		if (!isEdit.value) return;
		const touch = e.touches[0];
		drag.tierIndex = tIdx;
		drag.imgIdx = iIdx;
		drag.startX = touch.clientX;
		drag.startY = touch.clientY;
		drag.moveX = 0;
		drag.moveY = 0;
	};

	const onTouchMove = (e) => {
		if (drag.tierIndex === -1) return;
		const touch = e.touches[0];
		drag.moveX = touch.clientX - drag.startX;
		drag.moveY = touch.clientY - drag.startY;
	};

	const onTouchEnd = () => {
		if (drag.tierIndex === -1) return;

		const {
			tierIndex,
			imgIdx,
			moveX
		} = drag;
		const rowData = tierList.value[tierIndex].images;

		// 估算单个item跨度 (100rpx宽度 + 12rpx间距 ≈ 56px，建议根据真机微调)
		const itemWidth = 56;
		const offset = Math.round(moveX / itemWidth);
		let newIndex = imgIdx + offset;

		// 限制索引范围
		newIndex = Math.max(0, Math.min(newIndex, rowData.length - 1));

		if (newIndex !== imgIdx) {
			const temp = rowData.splice(imgIdx, 1)[0];
			rowData.splice(newIndex, 0, temp);
		}

		// 重置拖拽状态
		drag.tierIndex = -1;
		drag.imgIdx = -1;
	};

	// --- 其他业务逻辑 ---
	const chooseImage = (index) => {
		const currentCount = tierList.value[index].images.length;
		uni.chooseImage({
			count: 4 - currentCount,
			sizeType: ['compressed'],
			success: (res) => {
				tierList.value[index].images.push(...res.tempFilePaths);
			}
		});
	};

	const deleteImage = (tIdx, iIdx) => {
		const path = tierList.value[tIdx].images[iIdx];
		removeLocalFile(path); // 物理删除已有文件
		tierList.value[tIdx].images.splice(iIdx, 1);
	};

	const onRightClick = async () => {
		if (isEdit.value) {
			uni.showLoading({
				title: '正在持久化图片...',
				mask: true
			});
			// 1. 深度遍历并持久化所有临时图片
			for (let tierIdx = 0; tierIdx < tierList.value.length; tierIdx++) {
				const tier = tierList.value[tierIdx];
				for (let i = 0; i < tier.images.length; i++) {
					const path = tier.images[i];
					// 逻辑逻辑：如果是 static 或者是已经保存的 _doc/usr 路径，则跳过
					const isStatic = path.startsWith('/static/') || path.startsWith('static/');
					const isPersistent = path.indexOf('_doc/') !== -1 || path.indexOf('usr/') !== -1;

					if (!isStatic && !isPersistent) {
						console.log('检测到待持久化图片:', path);
						const newPath = await saveImageToLocal(path);
						if (newPath) {
							tier.images[i] = newPath;
							console.log('持久化成功，新路径:', newPath);
						}
					}
				}
			}

			// 2. 全部处理完后，进行数据持久化
			uni.setStorageSync('ranking_config_data', {
				title: title.value,
				type: type.value,
				skinBgColor: skinBgColor.value,
				skinHue: skinHue.value,
				tierList: tierList.value
			});
			uni.hideLoading();
			uni.showToast({
				title: '已保存',
				icon: 'none'
			});
		}
		isEdit.value = !isEdit.value;
		rightButtonText.value = isEdit.value ? "确定" : "编辑";
	};

	/**
	 * 将临时图片保存到本地永久目录
	 */
	const saveImageToLocal = (tempFilePath) => {
		return new Promise((resolve) => {
			// 如果已经是持久化路径，直接返回
			if (tempFilePath.indexOf('_doc/') !== -1 || tempFilePath.indexOf('usr/') !== -1) {
				return resolve(tempFilePath);
			}

			uni.saveFile({
				tempFilePath: tempFilePath,
				success: (res) => {
					resolve(res.savedFilePath);
				},
				fail: (err) => {
					console.error('本地持久化保存失败:', err);
					// 提示：H5 环境不支持 saveFile 持久化，仅 App/小程序支持
					resolve(null);
				}
			});
		});
	};

	/**
	 * 物理删除本地已保存的文件
	 */
	const removeLocalFile = (path) => {
		if (!path) return;
		// 仅针对非静态资源的本地文件进行删除
		if (path.indexOf('_doc/') !== -1 || path.indexOf('usr/') !== -1) {
			uni.removeSavedFile({
				filePath: path,
				success: () => console.log('文件物理删除成功:', path),
				fail: (err) => console.log('文件删除失败:', err)
			});
		}
	};

	const handleSave = () => {
		uni.showLoading({
			title: '生成中...',
			mask: true
		});
		isSnapshot.value = true;
	};

	const onPainterSuccess = (path) => {
		const done = () => {
			isSnapshot.value = false;
			uni.hideLoading();
		};
		if (!path) return done();

		uni.saveImageToPhotosAlbum({
			filePath: path,
			success: () => uni.showToast({
				title: '保存成功'
			}),
			fail: () => uni.showToast({
				title: '保存失败',
				icon: 'none'
			}),
			complete: done
		});
	};

	const switchType = (val) => {
		type.value = val;
		if (val == 'skin') {
			tierList.value[0].bgColor = '#F3575B'
			tierList.value[1].bgColor = '#FF9B5B'
			tierList.value[2].bgColor = '#FFF59E'
			tierList.value[3].bgColor = '#FFFBE1'
			tierList.value[4].bgColor = '#FFFFFF'
		} else {
			tierList.value[0].bgColor = '#D5171C'
			tierList.value[1].bgColor = '#FF6A0B'
			tierList.value[2].bgColor = '#FFF06A'
			tierList.value[3].bgColor = '#FDF5C8'
			tierList.value[4].bgColor = '#FFFFFF'
		}

		// 切换时由于改变了 type，立即同步到缓存中以便记录最后选择的模式
		const cache = uni.getStorageSync('ranking_config_data') || {};
		cache.type = val;
		uni.setStorageSync('ranking_config_data', cache);
	}

	/**
	 * 循环切换行背景色 (编辑模式下)
	 */
	const changeRowBgColor = (index) => {
		if (!isEdit.value) return;
		const colors = ['#D5171C', '#FF6A0B', '#FFF06A', '#FDF5C8', '#FFFFFF', '#1777FF', '#333333'];
		const curr = tierList.value[index].bgColor;
		let nextIdx = (colors.indexOf(curr.toUpperCase()) + 1) % colors.length;
		if (nextIdx === -1) nextIdx = 0;
		tierList.value[index].bgColor = colors[nextIdx];

		// 自动适配文字颜色 (深色背景用白色，浅色用黑色)
		const darkColors = ['#D5171C', '#1777FF', '#333333'];
		tierList.value[index].textColor = darkColors.includes(colors[nextIdx]) ? '#FFFFFF' : '#FFFFFF';
	};

	/**
	 * 处理色域滑动
	 */
	const handleHueTouch = (e) => {
		const touch = e.touches[0];
		uni.createSelectorQuery().select('.spectrum-picker').boundingClientRect(rect => {
			if (rect) {
				const x = Math.max(0, Math.min(touch.clientX - rect.left, rect.width));
				skinHue.value = Math.round((x / rect.width) * 360);

				// 1. 获取 HSL 的数值
				const h = skinHue.value;
				const s = 70;
				const l = 90;

				// 2. 转换为 16 进制色值
				skinBgColor.value = hslToHex(h, s, l);
			}
		}).exec();
	};

	/**
	 * HSL 转 Hex 工具函数
	 */
	function hslToHex(h, s, l) {
		l /= 100;
		const a = s * Math.min(l, 1 - l) / 100;
		const f = n => {
			const k = (n + h / 30) % 12;
			const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
			return Math.round(255 * color).toString(16).padStart(2, '0');
		};
		return `#${f(0)}${f(8)}${f(4)}`.toUpperCase();
	}
</script>

<style lang="less" scoped>
	.ranking-page {
		min-height: 100vh;
		background-color: #F8F8F8;
		padding-bottom: 200rpx;
	}

	.content-container {
		position: relative;
		padding: 12rpx 24rpx;

	}

	.table-box {
		position: relative;

		.watermark {
			position: absolute;
			height: 56rpx;
			top: 50%;
			left: 50%;
			transform: translate(-50%, -50%);
			z-index: 99;
		}
	}

	.ranking-table {
		border: 3rpx solid #333;
		background-color: #fff;
	}

	.ranking-row {
		display: flex;
		min-height: 148rpx;
		border-bottom: 3rpx solid #333;

		&:last-child {
			border-bottom: none;
		}
	}

	.label-box {
		width: 176rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		border-right: 3rpx solid #333;
	}

	.label-text {
		font-size: 48rpx;
		font-weight: bold;

		&.with-stroke {
			text-shadow: 2rpx 2rpx 0 #000, -2rpx -2rpx 0 #000, 2rpx -2rpx 0 #000, -2rpx 2rpx 0 #000;
		}
	}

	.items-box {
		flex: 1;
		display: flex;
		align-items: center;
		padding: 14rpx 12rpx;
		flex-wrap: wrap;
	}

	.item-wrapper {
		width: 105rpx;
		height: 105rpx;
		position: relative;
		margin: 0 6rpx;
		touch-action: none;
		/* 关键：禁止浏览器默认触摸行为 */

		&.is-dragging {
			opacity: 0.7;
			scale: 1.1;
			box-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.2);
		}
	}

	.item-img {
		width: 100%;
		height: 100%;
		border-radius: 4rpx;
	}

	.del-btn {
		position: absolute;
		top: -12rpx;
		right: -12rpx;
		width: 36rpx;
		height: 36rpx;
		background: #ff4d4f;
		color: #fff;
		border-radius: 50%;
		display: flex;
		justify-content: center;
		align-items: center;
		font-size: 24rpx;
		z-index: 10;
	}

	.add-btn {
		width: 100rpx;
		height: 100rpx;
		background: #eee;
		display: flex;
		justify-content: center;
		align-items: center;
		border-radius: 4rpx;

		.add-icon {
			width: 40rpx;
			height: 40rpx;
		}
	}

	.save-btn {
		margin-top: 60rpx;
		width: 400rpx;
		background: #1777FF;
		color: #fff;
		border-radius: 50rpx;
	}

	.bottom-tabs {
		position: fixed;
		bottom: 40rpx;
		bottom: calc(32rpx + env(safe-area-inset-bottom));
		bottom: calc(32rpx + constant(safe-area-inset-bottom));
		width: 100%;
		display: flex;
		justify-content: center;

		.tab-item {
			width: 180rpx;
			height: 80rpx;
			line-height: 80rpx;
			text-align: center;
			background: #fff;
			margin: 0 20rpx;
			border-radius: 10rpx;

			&.active {
				border: 4rpx solid #1777FF;
				color: #1777FF;
			}
		}
	}

	.skin-box {
		position: relative;
		padding: 120rpx 12rpx;
		background-color: #FFDFDF;

		.watermark {
			height: 56rpx !important;
			position: absolute;
			right: 14rpx !important;
			bottom: 32rpx !important;
		}

		.title {
			width: 260px;
			position: absolute;
			top: 30rpx;
			left: 50%;
			transform: translateX(-50%);
			font-weight: bold;
			text-align: center;
			font-size: 36rpx;
			color: #333;
		}

		.title-input {
			min-width: 260px;
			background: rgba(255, 255, 255, 0.5);
			border-radius: 8rpx;
			padding: 4rpx 12rpx;
			border: 1rpx dashed #1777FF;
		}

		.title-input {
			background: rgba(255, 255, 255, 0.5);
			border-radius: 8rpx;
			padding: 4rpx 12rpx;
			width: 300rpx;
			border: 1rpx dashed #1777FF;
		}

		.img {
			position: absolute;
			width: 90rpx;
			height: 90rpx;
		}

		.happy {
			top: 40rpx;
			right: 30rpx;
		}

		.sad {
			bottom: 60rpx;
			left: 100rpx;
		}
	}

	.save-action {
		margin-top: 60rpx;
		display: flex;
		flex-direction: column;
		align-items: center;
		padding-bottom: 60rpx;
	}

	.bottom-edit-actions {
		display: flex;
		flex-direction: column;
		align-items: center;
		width: 100%;
	}

	.edit-tip {
		font-size: 22rpx;
		color: #999;
		margin-top: 10rpx;
	}

	.color-picker {
		display: flex;
		gap: 16rpx;
		background: #fff;
		padding: 12rpx 20rpx;
		border-radius: 40rpx;
		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
	}

	.color-picker-wrapper {
		display: flex;
		align-items: center;
		margin: 12rpx 0;
	}

	.hex-input {
		width: 150rpx;
		height: 56rpx;
		background: #fff;
		border-radius: 28rpx;
		font-size: 24rpx;
		text-align: center;
		color: #333;
		border: 1rpx solid #eee;
		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
	}

	.spectrum-picker {
		width: 600rpx;
		height: 32rpx;
		background: #fff;
		border-radius: 16rpx;
		padding: 4rpx;
		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
		position: relative;
		margin: 12rpx 0;
	}

	.slider-thumb {
		position: absolute;
		top: 50%;
		width: 38rpx;
		height: 38rpx;
		background: #fff;
		border-radius: 50%;
		transform: translate(-50%, -50%);
		box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.3);
		border: 2rpx solid #fff;
		pointer-events: none;
	}

	.spectrum-bar {
		width: 100%;
		height: 100%;
		border-radius: 12rpx;
		background: linear-gradient(to right, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
	}

	.color-dot {
		width: 32rpx;
		height: 32rpx;
		border-radius: 50%;
		border: 2rpx solid #fff;
		box-shadow: 0 0 4rpx rgba(0, 0, 0, 0.2);
		margin: 0 10rpx;
	}

	.painter-container {
		position: fixed;
		left: -9999rpx;
	}
</style>