<template>
	<view class="danmaku-container" :style="{ height: height + 'px' }">
		<view class="danmaku-stage">
			<view 
				v-for="item in visibleDanmakus" 
				:key="item.id"
				class="danmaku-item"
				:class="[`danmaku-track`, { 'danmaku-scrolling': item.isScrolling }]"
				:style="getDanmakuStyle(item)"
			>
				<view class="danmaku-content">
					<image class="danmaku-avatar" :src="item.avatar || defaultAvatar" mode="aspectFill"></image>
					<view class="danmaku-text">{{ item.text }}</view>
				</view>
			</view>
		</view>
	</view>
</template>

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

const props = defineProps({
	danmakuList: {
		type: Array,
		default: () => []
	},
	height: {
		type: Number,
		default: 200
	},
	infinite: {
		type: Boolean,
		default: true
	},
	speed: {
		type: Number,
		default: 100
	},
	trackCount: {
		type: Number,
		default: 8
	},
	spacing: {
		type: Number,
		default: 20
	}
})

const emit = defineEmits(['danmakuComplete'])

const visibleDanmakus = ref([])
const animationTimer = ref(null)
const danmakuIdCounter = ref(0)
const trackOccupancy = ref(new Array(props.trackCount).fill(0)) // 记录每个轨道的占用情况

const trackHeight = computed(() => props.height / props.trackCount)

// 默认头像
const defaultAvatar = 'https://birdseye-img.sysuimars.com/youwei-uniapp/img/default-avatar.png'

const getDanmakuStyle = (danmaku) => {
	// 获取屏幕宽度，兼容不同平台
	const screenWidth = uni.getSystemInfoSync().screenWidth || 375
	// 增加更多的额外距离确保弹幕完全离开可视范围
	const extraDistance = 200 // 增加缓冲距离
	const duration = (screenWidth + danmaku.width + extraDistance) / props.speed
	const trackSpacing = calculateTrackSpacing()
	const danmakuHeight = calculateDanmakuHeight()
	
	// 计算弹幕的垂直位置，确保在轨道中居中且不超出容器边界
	const trackTop = danmaku.track * trackSpacing
	const centerOffset = trackSpacing / 2
	const topPosition = Math.max(
		danmakuHeight / 2, // 确保不超出顶部
		Math.min(
			trackTop + centerOffset, // 轨道中心位置
			props.height - danmakuHeight / 2 // 确保不超出底部
		)
	)
	
	return {
		top: `${topPosition}px`,
		left: `${danmaku.left}px`,
		transition: `left ${duration}s linear`
	}
}

// 计算弹幕实际宽度
const calculateDanmakuWidth = (text) => {
	// 更精确的宽度计算：每个字符约16px，头像32px，内边距40px，额外缓冲20px
	return text.length * 16 + 32 + 40 + 20
}

// 计算弹幕实际高度
const calculateDanmakuHeight = () => {
	return 48 // 弹幕高度约48rpx
}

// 计算轨道间距
const calculateTrackSpacing = () => {
	const danmakuHeight = calculateDanmakuHeight()
	const trackHeight = props.height / props.trackCount
	// 对于低高度容器，增加轨道间距避免叠加
	const minSpacing = props.height < 150 ? danmakuHeight + 20 : danmakuHeight + 10
	return Math.max(minSpacing, trackHeight) // 确保轨道间距足够
}

// 查找可用轨道
const findAvailableTrack = () => {
	const screenWidth = uni.getSystemInfoSync().screenWidth || 375
	const currentTime = Date.now()
	const danmakuHeight = calculateDanmakuHeight()
	const trackSpacing = calculateTrackSpacing()
	
	// 清理过期的轨道占用记录
	for (let i = 0; i < trackOccupancy.value.length; i++) {
		if (trackOccupancy.value[i] < currentTime) {
			trackOccupancy.value[i] = 0
		}
	}
	
	// 计算可用的轨道数量，确保弹幕不会超出容器边界
	const maxTracks = Math.floor((props.height - danmakuHeight) / trackSpacing) + 1
	const availableTracks = Math.min(props.trackCount, maxTracks)
	
	// 对于低高度容器，减少可用轨道数量避免叠加
	const finalTracks = props.height < 150 ? Math.min(availableTracks, 3) : availableTracks
	
	// 首先尝试寻找完全空闲的轨道
	for (let i = 0; i < finalTracks; i++) {
		if (trackOccupancy.value[i] === 0) {
			// 检查相邻轨道是否被占用
			const prevTrack = i > 0 ? trackOccupancy.value[i - 1] : 0
			const nextTrack = i < finalTracks - 1 ? trackOccupancy.value[i + 1] : 0
			
			// 优先选择完全空闲的轨道
			if (prevTrack === 0 && nextTrack === 0) {
				return i
			}
		}
	}
	
	// 如果没有完全空闲的轨道，寻找任何空闲轨道
	for (let i = 0; i < finalTracks; i++) {
		if (trackOccupancy.value[i] === 0) {
			return i
		}
	}
	
	// 如果所有轨道都被占用，选择最早释放的轨道
	let earliestTrack = 0
	let earliestTime = trackOccupancy.value[0]
	for (let i = 1; i < finalTracks; i++) {
		if (trackOccupancy.value[i] < earliestTime) {
			earliestTime = trackOccupancy.value[i]
			earliestTrack = i
		}
	}
	
	return earliestTrack
}

const createDanmaku = (text, avatar = null) => {
	const id = ++danmakuIdCounter.value
	const track = findAvailableTrack()
	
	const width = calculateDanmakuWidth(text)
	// 获取屏幕宽度，兼容不同平台
	const screenWidth = uni.getSystemInfoSync().screenWidth || 375
	const left = screenWidth + props.spacing
	
	// 计算弹幕持续时间并记录轨道占用，增加缓冲时间
	const extraDistance = 200
	const duration = (screenWidth + width + extraDistance) / props.speed
	const endTime = Date.now() + duration * 1000
	trackOccupancy.value[track] = endTime
	
	return {
		id,
		text,
		avatar,
		track,
		width,
		left,
		isScrolling: false,
		startTime: Date.now()
	}
}

const addDanmaku = (text, avatar = null) => {
	const danmaku = createDanmaku(text, avatar)
	
	visibleDanmakus.value.push(danmaku)
	
	setTimeout(() => {
		danmaku.isScrolling = true
		// 确保弹幕完全离开可视范围才消失，增加更多缓冲距离
		danmaku.left = -(danmaku.width + 100)
	}, 50)
	
	// 获取屏幕宽度，兼容不同平台
	const screenWidth = uni.getSystemInfoSync().screenWidth || 375
	// 增加更多的额外距离确保弹幕完全离开可视范围
	const extraDistance = 200 // 增加缓冲距离
	const duration = (screenWidth + danmaku.width + extraDistance) / props.speed
	setTimeout(() => {
		removeDanmaku(danmaku.id)
	}, duration * 1000)
}

const removeDanmaku = (id) => {
	const index = visibleDanmakus.value.findIndex(item => item.id === id)
	if (index > -1) {
		visibleDanmakus.value.splice(index, 1)
		emit('danmakuComplete', id)
	}
}

const clearDanmakus = () => {
	visibleDanmakus.value = []
	// 清空轨道占用记录
	trackOccupancy.value = new Array(props.trackCount).fill(0)
}

const startDanmakuAnimation = () => {
	if (props.danmakuList.length === 0) return
	
	let currentIndex = 0
	
	const playNext = () => {
		if (currentIndex >= props.danmakuList.length) {
			if (props.infinite) {
				currentIndex = 0
			} else {
				return
			}
		}
		
		const danmaku = props.danmakuList[currentIndex]
		addDanmaku(danmaku.text, danmaku.avatar)
		currentIndex++
		
		// 根据容器高度动态调整间隔时间，低高度容器需要更大的间隔避免叠加
		const baseInterval = props.height < 150 ? 
			Math.max(2000, props.height * 2) : // 低高度容器使用适中的基础间隔
			Math.max(1500, props.height * 2)   // 正常高度容器
		const minInterval = baseInterval
		const maxInterval = baseInterval + (props.height < 150 ? 2000 : 2000)
		const interval = Math.random() * (maxInterval - minInterval) + minInterval
		animationTimer.value = setTimeout(playNext, interval)
	}
	
	playNext()
}

const stopDanmakuAnimation = () => {
	if (animationTimer.value) {
		clearTimeout(animationTimer.value)
		animationTimer.value = null
	}
}

watch(() => props.danmakuList, (newList) => {
	if (newList.length > 0) {
		stopDanmakuAnimation()
		clearDanmakus()
		startDanmakuAnimation()
	}
}, { deep: true })

onMounted(() => {
	if (props.danmakuList.length > 0) {
		startDanmakuAnimation()
	}
})

onUnmounted(() => {
	stopDanmakuAnimation()
})

defineExpose({
	addDanmaku,
	clearDanmakus,
	startDanmakuAnimation,
	stopDanmakuAnimation
})
</script>

<style lang="scss" scoped>
.danmaku-container {
	width: 100%;
	position: relative;
	overflow: hidden;
	// background: rgba(0, 0, 0, 0.1);
	border-radius: 8rpx;
}

.danmaku-stage {
	width: 100%;
	height: 100%;
	position: relative;
}

.danmaku-item {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 10;
	pointer-events: none;
	
	&.danmaku-scrolling {
		transition: left linear;
	}
	
	// 确保弹幕在轨道中居中显示
	transform: translateY(-50%);
}

.danmaku-content {
	display: flex;
	align-items: center;
	background: rgba(0, 0, 0, 0.6);
	border-radius: 20rpx;
	padding: 8rpx 20rpx;
	backdrop-filter: blur(10rpx);
	border: 1rpx solid rgba(255, 255, 255, 0.2);
	// box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.3);
	width: fit-content;
	min-width: 120rpx;
	// 确保弹幕内容不会超出容器边界
	max-height: 48rpx;
	overflow: hidden;
	// 防止弹幕在滚动过程中高度变化
	line-height: 1.2;
	// 增加内边距确保文字有足够空间
	box-sizing: border-box;
}

.danmaku-avatar {
	width: 32rpx;
	height: 32rpx;
	border-radius: 50%;
	margin-right: 12rpx;
	border: 2rpx solid rgba(255, 255, 255, 0.3);
	flex-shrink: 0;
	// 确保头像高度稳定
	object-fit: cover;
}

.danmaku-text {
	color: #000;
	font-size: 24rpx;
	font-weight: 500;
	// text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.5);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	max-width: 400rpx;
	flex: 1;
	// 确保文字高度稳定
	line-height: 1.2;
	height: 32rpx;
	display: flex;
	align-items: center;
	// 增加文字间距确保显示完整
	letter-spacing: 1rpx;
}

.danmaku-track .danmaku-content {
	background: rgba(244, 246, 248, 0.6);
}
</style>
