<template>
	<view class="container">
		<NavBar class="nav-bar" title="快捷入口" :bgColor="data.navBar.bgColor" isRightButton @right-click="onRightClick">
		</NavBar>
		<view class="content">
			<view class="grid-card">
				<view class="grid-list">
					<!-- 遍历显示网格项，绑定触摸事件以支持拖拽 -->
					<view class="grid-item" v-for="(item, index) in data.list" :key="item.id"
						:class="{ 'dragging-placeholder': draggingItem && draggingItem.id === item.id }"
						@touchstart="handleTouchStart($event, item, index)" @touchmove.stop.prevent="handleTouchMove"
						@touchend="handleTouchEnd">
						<view class="icon-box">
							<image class="icon" :src="`/static/image/balance/menu-icon/${item.label}.png`"
								mode="aspectFit"></image>
						</view>
						<text class="name">{{ item.name }}</text>
					</view>
				</view>
				<view class="footer-tip">*长按可以排序哟</view>
			</view>
		</view>

		<!-- 拖拽时显示的浮动项（跟随手指） -->
		<view v-if="draggingItem" class="grid-item floating-item" :style="dragStyle">
			<view class="icon-box">
				<image class="icon" :src="`/static/image/balance/menu-icon/${draggingItem.label}.png`" mode="aspectFit">
				</image>
			</view>
			<text class="name">{{ draggingItem.name }}</text>
		</view>
	</view>
</template>

<script setup>
import NavBar from '@/components/nav-bar/nav-bar.vue'
import { fastEntranceList } from '@/static/json/initial.json'
import { onShow } from '@dcloudio/uni-app'
import { storage } from '@/utils/storage'
import {
	reactive,
	toRefs,
	ref,
	nextTick
} from 'vue'

const data = reactive({
	navBar: {
		bgColor: "#F5F5F5"
	},
	list: []
})

let { list } = toRefs(data)

// 拖拽相关状态
const draggingItem = ref(null) // 当前正在拖拽的项
const dragStyle = ref({ top: '0px', left: '0px' }) // 拖拽项的样式（位置）
let startX = 0 // 触摸开始X坐标
let startY = 0 // 触摸开始Y坐标
let longPressTimer = null // 长按定时器
let itemRects = [] // 所有网格项的位置信息
let containerTop = 0 // 容器顶部偏移

onShow(() => {
	// 优先从缓存读取
	const cachedList = storage.get('fastEntranceList')
	if (cachedList && cachedList.length > 0) {
		data.list = cachedList
	} else {
		// 深拷贝数据，防止直接修改原引用的json数据，允许页面内重新排序
		data.list = JSON.parse(JSON.stringify(fastEntranceList))
	}

	// 渲染完成后测量位置
	nextTick(() => {
		measureItems()
	})
})

/**
 * 测量所有网格项的位置，用于后续碰撞检测
 */
const measureItems = () => {
	uni.createSelectorQuery().select('.grid-list').boundingClientRect(res => {
		if (res) {
			containerTop = res.top
		}
	}).exec()

	uni.createSelectorQuery().selectAll('.grid-item').boundingClientRect(rects => {
		itemRects = rects
	}).exec()
}

/**
 * 触摸开始：启动长按定时器
 */
const handleTouchStart = (e, item, index) => {
	if (e.touches.length !== 1) return

	startX = e.touches[0].clientX
	startY = e.touches[0].clientY

	longPressTimer = setTimeout(() => {
		// 长按触发拖拽
		draggingItem.value = item
		// 更新拖拽项位置使其出现在手指中心
		updateDragPosition(startX, startY)

		// 震动反馈
		uni.vibrateShort()
	}, 500) // 500ms 长按触发
}

/**
 * 触摸移动：更新拖拽位置并检测排序
 */
const handleTouchMove = (e) => {
	if (!draggingItem.value) {
		// 如果还没触发拖拽，检测手指移动距离，如果移动过多则取消长按定时器（由点击变为滑动）
		const moveX = e.touches[0].clientX
		const moveY = e.touches[0].clientY
		if (Math.abs(moveX - startX) > 10 || Math.abs(moveY - startY) > 10) {
			clearTimeout(longPressTimer)
		}
		return
	}

	const x = e.touches[0].clientX
	const y = e.touches[0].clientY

	updateDragPosition(x, y)
	checkReorder(x, y)
}

/**
 * 触摸结束：重置状态
 */
const handleTouchEnd = () => {
	clearTimeout(longPressTimer)
	draggingItem.value = null
}

/**
 * 更新拖拽浮层的位置
 */
const updateDragPosition = (x, y) => {
	// 将项目中心定位到手指位置
	// 假设项目宽度大约占屏幕宽度的20% (例如75px) -> 中心偏移约37px
	// 仅用于视觉更新
	dragStyle.value = {
		top: (y - 40) + 'px',
		left: (x - 37) + 'px',
		position: 'fixed',
		zIndex: 999,
		opacity: 0.8,
		width: itemRects[0] ? itemRects[0].width + 'px' : '20%' // 匹配实际宽度
	}
}

/**
 * 检测是否需要重新排序
 */
const checkReorder = (x, y) => {
	// 查找当前手指位置所在的网格项索引
	const targetIndex = itemRects.findIndex(rect =>
		x >= rect.left && x <= rect.right &&
		y >= rect.top && y <= rect.bottom
	)

	if (targetIndex !== -1) {
		const draggedIndex = data.list.findIndex(item => item.id === draggingItem.value.id)
		if (draggedIndex !== -1 && draggedIndex !== targetIndex) {
			// 交换逻辑：将原位置删掉，插入新位置
			const item = data.list.splice(draggedIndex, 1)[0]
			data.list.splice(targetIndex, 0, item)
		}
	}
}

const onRightClick = () => {
	// 保存到缓存
	storage.set('fastEntranceList', data.list)

	uni.showToast({
		title: '保存成功',
		icon: 'success',
		duration: 500
	})

	setTimeout(() => {
		uni.navigateBack()
	}, 500)
}

</script>

<style>
page {
	background-color: #F5F5F5;
}
</style>

<style lang="less" scoped>
.container {
	min-height: 100vh;
}

.content {
	padding: 12px;
}

.grid-card {
	background-color: #FFFFFF;
	border-radius: 12px;
	padding: 20px 0;
	padding-bottom: 12px;

	.footer-tip {
		text-align: right;
		font-size: 20rpx;
		color: #767676;
		padding: 0 16rpx;
	}
}

.grid-list {
	display: flex;
	flex-wrap: wrap;
}

.grid-item {
	width: 20%;
	display: flex;
	flex-direction: column;
	align-items: center;
	margin-bottom: 24px;
}

.icon-box {
	width: 36px;
	height: 36px;
	border: 1px dashed #cccccc;
	border-radius: 4px;
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 8px;
}

.icon {
	width: 20px;
	/* Adjusted based on visual ratio in screenshot inside the box */
	height: 20px;
}

.name {
	font-size: 12px;
	color: #333333;
}

.dragging-placeholder {
	opacity: 0;
}

.floating-item {
	pointer-events: none;
	/* Let touches pass through to underlying elements for detection */
}
</style>
