<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" 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 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>
						</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">
			<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-view>
							<l-painter-view :css="`flex: 1; padding: 14rpx 16rpx; display: flex; align-items: center;`">
								<l-painter-image v-for="(img, imgIdx) in item.images" :key="imgIdx" :src="img"
									css="width: 110rpx; height: 110rpx; margin: 0 6rpx; object-fit: cover;"
									mode="aspectFill" />
							</l-painter-view>
						</l-painter-view>
					</l-painter-view>
					<l-painter-view
						: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>
</template>

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

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', textColor: '#FFFFFF', hasStroke: true, images: [] },
	{ label: '顶级', bgColor: '#FF6A0B', textColor: '#FFFFFF', hasStroke: true, images: [] },
	{ label: '人上人', bgColor: '#FFF06A', textColor: '#FFFFFF', hasStroke: true, images: [] },
	{ label: 'NPC', bgColor: '#FDF5C8', textColor: '#FFFFFF', hasStroke: true, images: [] },
	{ label: '拉完了', bgColor: '#FFFFFF', textColor: '#FFFFFF', hasStroke: true, images: [] }
]);

// --- 生命周期：加载缓存 ---
onLoad(() => {
	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' : '#333333';
};

/**
 * 处理色域滑动
 */
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 8rpx;
	flex-wrap: wrap;
}

.item-wrapper {
	width: 100rpx;
	height: 100rpx;
	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;
	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 {
		position: absolute;
		top: 30rpx;
		left: 50%;
		transform: translateX(-50%);
		font-weight: bold;
		text-align: center;
		font-size: 36rpx;
		color: #333;
	}

	.title-input {
		background: rgba(255, 255, 255, 0.5);
		border-radius: 8rpx;
		padding: 4rpx 12rpx;
		width: 300rpx;
		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>