<template>
	<view class="notice-page" :class="{ 'bg-gray': hasNotify }">
		<!-- 默认展示背景图 -->
		<image v-if="!hasNotify" class="bg" src="/static/images/deviceunlogin.png" mode="aspectFit" />

		<!-- Mock：后续接 WebSocket 有消息时展示 -->
		<!-- 动态布局优化 by xu 2025-12-29 -->
		<view v-else class="notify-container">
			<view class="notify-card"
				:class="{ 'has-message': item.hasMessage }"
				v-for="(item, index) in layoutInfo?.positions"
				:key="item.id + '_' + index"
				:style="{
					left: item.left + 'px',
					top: item.top + 'px',
					width: item.width + 'px',
					height: item.height + 'px',
					gap: item.gap + 'px'
				}">
				<image class="avatar" :src="item.avatar" mode="aspectFill"
					:style="{ width: item.avatarSize + 'px', height: item.avatarSize + 'px' }" />
				<view class="name" :style="{ fontSize: item.fontSize + 'px' }">{{ item.name }}</view>
			</view>
		</view>

		<view class="footer">
			<view class="footer-text">
				<view class="triangles">
					<view class="triangle" />
					<view class="triangle" />
					<view class="triangle" />
				</view>
				请刷卡登录查看留言
			</view>
		</view>

		<!-- 测试按钮 by xu 2025-12-29 -->
		<view class="test-buttons">
			<view class="test-btn" @click="removeUser">-</view>
			<view class="test-count">{{ notifyUsers.length }}</view>
			<view class="test-btn" @click="addUser">+</view>
			<view class="test-btn reset-btn" @click="resetUsers">重置</view>
		</view>
	</view>
</template>

<script setup>
import { computed, ref } from 'vue'

const notifyUsers = ref([
	{
		id: '1',
		name: '张三',
		avatar: '/static/logo.png',
		hasMessage: true,
	},
	{
		id: '1',
		name: '张三',
		avatar: '/static/logo.png',
		hasMessage: true,
	},
	{
		id: '1',
		name: '张三',
		avatar: '/static/logo.png',
		hasMessage: true,
	},
	
])

const hasNotify = computed(() => notifyUsers.value.length > 0)

// 屏幕尺寸（px）
// 原始需求：竖屏 800×1280，屏幕比例 5:8 (宽:高) = 1.6
const SCREEN_WIDTH = 800
const SCREEN_HEIGHT = 1280
const FOOTER_HEIGHT = 50 * (SCREEN_WIDTH / 750) // 50rpx 转 px by xu 2025-12-29
const HORIZONTAL_PADDING = 10 * (SCREEN_WIDTH / 750) * 2 // 左右各10rpx by xu 2025-12-29
const VERTICAL_PADDING = 10 * (SCREEN_WIDTH / 750) * 2 // 上下各10rpx by xu 2025-12-29
const AVAILABLE_WIDTH = SCREEN_WIDTH - HORIZONTAL_PADDING // 减去水平边距
const AVAILABLE_HEIGHT = (SCREEN_HEIGHT - FOOTER_HEIGHT) - VERTICAL_PADDING // 容器高度减去垂直边距 by xu 2025-12-29
const SCREEN_RATIO = AVAILABLE_HEIGHT / AVAILABLE_WIDTH // 调整后的屏幕比例
console.log(`[初始化] 屏幕:${SCREEN_WIDTH}×${SCREEN_HEIGHT}, 可用:${AVAILABLE_WIDTH.toFixed(2)}×${AVAILABLE_HEIGHT.toFixed(2)}, 比例:${SCREEN_RATIO.toFixed(3)}`)

// 计算最优行列数 by xu 2025-12-29
// 原则：优先保证x轴贴满，y轴可以有空隙
function calculateOptimalGrid(n) {
	if (n === 1) return { rows: 1, cols: 1 }

	const CARD_RATIO = 49 / 40 // 卡片宽高比

	let bestRows = 1, bestCols = n
	let bestScore = Infinity

	// 遍历可能的行数
	for (let rows = 1; rows <= n; rows++) {
		const cols = Math.ceil(n / rows)
		const capacity = rows * cols
		const waste = capacity - n
		const wasteRatio = waste / n

		// 计算这个组合下的卡片尺寸
		const maxWidth = AVAILABLE_WIDTH / cols
		const maxHeight = AVAILABLE_HEIGHT / rows / CARD_RATIO
		const isWidthLimited = maxWidth < maxHeight // x轴是否贴满

		const gridRatio = rows / cols
		const ratioDiff = Math.abs(gridRatio - SCREEN_RATIO)

		// 综合评分：
		// 1. 优先选择x轴贴满的组合（isWidthLimited=true）
		// 2. 其次考虑浪费比例
		// 3. 最后考虑屏幕比例匹配
		const widthPenalty = isWidthLimited ? 0 : 2.0 // x轴不贴满时重罚
		const score = widthPenalty + wasteRatio * 0.5 + ratioDiff * 0.3

		console.log(`  ${rows}×${cols}: maxW=${maxWidth.toFixed(1)}, maxH=${maxHeight.toFixed(1)}, ${isWidthLimited ? 'x轴贴满' : 'y轴贴满'}, 评分=${score.toFixed(3)}`)

		if (score < bestScore) {
			bestScore = score
			bestRows = rows
			bestCols = cols
		}
	}

	console.log(`[行列选择] ${n}人 -> ${bestRows}×${bestCols} (容量:${bestRows * bestCols}, 浪费:${bestRows * bestCols - n}, 评分:${bestScore.toFixed(3)})`)
	return { rows: bestRows, cols: bestCols }
}

// 计算布局信息 by xu 2025-12-29
const layoutInfo = computed(() => {
	const n = notifyUsers.value.length
	if (n === 0) return null

	const { rows, cols } = calculateOptimalGrid(n)
	console.log(`[布局] 人数:${n}, 行列:${rows}×${cols}`)

	// 卡片宽高比 by xu 2025-12-29
	const CARD_RATIO = 49 / 40 // 宽:高 = 40:49

	// 计算卡片最大尺寸（考虑宽高比）
	const maxWidth = AVAILABLE_WIDTH / cols // 使用可用宽度 by xu 2025-12-29
	const maxHeight = AVAILABLE_HEIGHT / rows / CARD_RATIO // 使用可用高度除以比例 by xu 2025-12-29
	let cardWidth = Math.min(maxWidth, maxHeight)
	console.log(`[尺寸] maxWidth:${maxWidth.toFixed(2)}, maxHeight:${maxHeight.toFixed(2)}, cardWidth:${cardWidth.toFixed(2)}`)

	// 单张卡片时限制最大宽度 by xu 2025-12-29
	if (n === 1) {
		const maxSingleCardWidth = 600 // 单卡最大宽度500px
		cardWidth = Math.min(cardWidth, maxSingleCardWidth)
	}

	const cardHeight = cardWidth * CARD_RATIO

	// 计算整体布局的实际宽高
	const totalWidth = cols * cardWidth
	const totalHeight = rows * cardHeight

	// 计算起始偏移（居中）
	const offsetX = (AVAILABLE_WIDTH - totalWidth) / 2 + HORIZONTAL_PADDING / 2 // 使用可用宽度+左边距 by xu 2025-12-29
	const offsetY = VERTICAL_PADDING / 2 + (AVAILABLE_HEIGHT - totalHeight) / 2 // 上边距+居中偏移 by xu 2025-12-29
	console.log(`[偏移] offsetX:${offsetX.toFixed(2)}, offsetY:${offsetY.toFixed(2)}`)
	console.log(`[总尺寸] totalWidth:${totalWidth.toFixed(2)}, totalHeight:${totalHeight.toFixed(2)}`)
	console.log(`[可用空间] AVAILABLE_WIDTH:${AVAILABLE_WIDTH.toFixed(2)}, AVAILABLE_HEIGHT:${AVAILABLE_HEIGHT.toFixed(2)}`)
	console.log(`[边距] HORIZONTAL_PADDING:${HORIZONTAL_PADDING.toFixed(2)}, VERTICAL_PADDING:${VERTICAL_PADDING.toFixed(2)}`)

	// 动态计算字体大小、间距和头像尺寸 by xu 2025-12-29
	// 基准：4×4时卡片宽度约194px，字体30rpx(32px)
	const baseCardWidth = AVAILABLE_WIDTH / 4 // 4列时的卡片宽度
	const baseFontSize = 30 * (SCREEN_WIDTH / 750) // 30rpx转px
	const fontSize = Math.max(12, cardWidth / baseCardWidth * baseFontSize) // 按比例缩放，最小12px
	const gap = Math.max(6, cardWidth * 0.06) // 间距为卡片宽度的6%，最小6px
	const avatarSize = cardWidth * 0.55 // 头像尺寸为卡片宽度的55%，保持正方形

	// 计算每个用户的位置
	const positions = notifyUsers.value.map((user, index) => {
		const row = Math.floor(index / cols)
		const col = index % cols

		// 计算当前行的元素数量 by xu 2025-12-29
		const itemsInCurrentRow = Math.min(cols, n - row * cols)
		// 如果当前行元素少于列数，计算居中偏移
		const rowCenterOffset = itemsInCurrentRow < cols
			? (cols - itemsInCurrentRow) * cardWidth / 2
			: 0

		return {
			...user,
			left: offsetX + col * cardWidth + rowCenterOffset,
			top: offsetY + row * cardHeight,
			width: cardWidth,
			height: cardHeight,
			fontSize,
			gap,
			avatarSize
		}
	})

	return { positions, cardWidth, cardHeight, fontSize, gap, avatarSize }
})

// 测试功能：增加用户 by xu 2025-12-29
function addUser() {
	notifyUsers.value.push({
		id: String(notifyUsers.value.length + 1),
		name: '张三',
		avatar: '/static/logo.png',
		hasMessage: true,
	})
}

// 测试功能：减少用户 by xu 2025-12-29
function removeUser() {
	if (notifyUsers.value.length > 0) {
		notifyUsers.value.pop()
	}
}

// 测试功能：重置用户 by xu 2025-12-29
function resetUsers() {
	notifyUsers.value = [
		{
			id: '1',
			name: '张三',
			avatar: '/static/logo.png',
			hasMessage: true,
		},
		{
			id: '2',
			name: '张三',
			avatar: '/static/logo.png',
			hasMessage: true,
		},
		{
			id: '3',
			name: '张三',
			avatar: '/static/logo.png',
			hasMessage: true,
		},
	]
}
</script>

<style>
.notice-page {
	width: 100vw;
	height: 100vh;
	background: #000;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	padding-bottom: 50rpx;
	box-sizing: border-box;
}

.bg-gray {
	background: #b2b2b2;
}

.bg {
	width: 100%;
	height: 100%;
}

.notify-container {
	width: 100%;
	height: 100%;
	position: relative;
}

.notify-card {
	position: absolute;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	border: 1px solid #888;
}

.avatar {
	border-radius: 50%;
	border: 2px solid #fff;
	box-sizing: border-box;
	background: #f2f2f2;
}

.name {
	color: #000;
	font-weight: 600;
	text-align: center;
	word-break: break-all;
}

.footer {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 50rpx;
	background: #b2b2b2;
	display: flex;
	align-items: center;
	justify-content: center;
}

.footer-text {
	color: #000;
	font-size: 26rpx;
	line-height: 1;
	display: inline-flex;
	align-items: center;
}

.triangles {
	display: inline-flex;
	align-items: center;
	gap: 6rpx;
	margin-right: 12rpx;
}

.triangle {
	width: 0;
	height: 0;
	border-top: 10rpx solid transparent;
	border-bottom: 10rpx solid transparent;
	border-left: 14rpx solid #000;
}

.test-buttons {
	position: fixed;
	right: 20rpx;
	bottom: 100rpx;
	display: flex;
	align-items: center;
	gap: 20rpx;
	background: rgba(0, 0, 0, 0.7);
	padding: 20rpx;
	border-radius: 10rpx;
	z-index: 9999;
}

.test-btn {
	width: 60rpx;
	height: 60rpx;
	background: #fff;
	color: #000;
	font-size: 40rpx;
	font-weight: bold;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	cursor: pointer;
}

.test-count {
	color: #fff;
	font-size: 32rpx;
	font-weight: bold;
	min-width: 40rpx;
	text-align: center;
}

.reset-btn {
	width: auto;
	padding: 0 20rpx;
	font-size: 24rpx;
	border-radius: 30rpx;
}
</style>
