<script setup lang="ts">
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import Loading from './views/LoadingView.vue'
import Rank1 from './views/Rank1View.vue'
import Rank2 from './views/Rank2View.vue'
import { useAdminGameSocket } from '@/composables/useAdminGameSocket'
import type Player from '@/commons/player.ts'
import { playApplauseMusic, playGame5Music, stopAllMusic, stopApplauseMusic, stopGame5Music } from '@/commons/music'
import { $confirm, $is_local_mode, $remove_socket_storage, $notify, $toast } from '@/commons/utils.ts'

const router = useRouter()

type GameScreen = 'loading' | 'rank1' | 'rank2'

const PLAYER_LIMIT = 20
const RANK_LIMIT = 10

const emptyLoadingPlayer = () => ({
    score: '-',
    telephone: '',
    userid: '',
    wechat_id: '',
    nickname: '虚位以待',
    avatar: '',
})

const emptyRankPlayer = (index: number): Player => ({
    wechat_id: `empty-${index}`,
    nickname: '虚位以待',
    avatar: '',
    score: '-',
})

const screen = ref<GameScreen>('loading')

// 本地模式下使用模拟玩家数据（已关闭）
const mockPlayers = [
  { userid: 'local-1', nickname: '疾风骑士', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Felix', score: 45 },
  { userid: 'local-2', nickname: '闪电侠', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Aneka', score: 38 },
  { userid: 'local-3', nickname: '追风者', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Salem', score: 30 },
  { userid: 'local-4', nickname: '千里马', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Midnight', score: 22 },
  { userid: 'local-5', nickname: '飞毛腿', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Lucky', score: 15 },
  { userid: 'local-6', nickname: '烈焰驹', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Bandit', score: 52 },
  { userid: 'local-7', nickname: '暴风战士', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Misty', score: 41 },
  { userid: 'local-8', nickname: '神行者', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Pepper', score: 35 },
  { userid: 'local-9', nickname: '银鞍客', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Oreo', score: 28 },
  { userid: 'local-10', nickname: '踏雪无痕', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Tiger', score: 18 },
];

const loadingPlayers = ref<any[]>(Array.from({ length: PLAYER_LIMIT }, emptyLoadingPlayer))
const playerCount = ref(0)
const rankPlayers = ref<Player[]>(Array.from({ length: RANK_LIMIT }, (_, index) => emptyRankPlayer(index)))
const rank1Ref = ref<InstanceType<typeof Rank1> | null>(null)
let isPlayingStartAnimation = false
const isSubmitWaiting = ref(false)
const submitWaitingSeconds = ref(5)
let submitWaitingTimer: ReturnType<typeof window.setInterval> | undefined

const confirmRefresh = (event: BeforeUnloadEvent) => {
    event.preventDefault()
    event.returnValue = ''
}

const renderPlayers = (data: any) => {
    const players = Array.isArray(data?.list) ? data.list : []
    const count = Number(data?.count ?? players.length)
    console.log('[WebSocket] 玩家列表更新 - 在线人数:', count, '玩家数:', players.length, '数据:', JSON.stringify(players.map((p: any) => ({ nickname: p.nickname, userid: p.userid ?? p.wechat_id }))))
    playerCount.value = count
    loadingPlayers.value = Array.from(
        { length: PLAYER_LIMIT },
        (_, index) => players[index] ?? emptyLoadingPlayer(),
    )
}

const updateRankPlayers = (data: any) => {
    if (!Array.isArray(data)) return

    rankPlayers.value = Array.from(
        { length: RANK_LIMIT },
        (_, index) => data[index] ?? emptyRankPlayer(index),
    )
}

const playerToRankPlayer = (player: any, index: number): Player => {
    // WebSocket 数据可能没有 userid/wechat_id，用 avatar 作为唯一标识
    const hasId = player?.userid || player?.wechat_id || player?.openid || player?.user_id;
    const avatar = player?.avatar || '';
    const nickname = player?.nickname || '虚位以待';
    const isRealPlayer = nickname && nickname !== '-' && nickname !== '虚位以待';
    const wechat_id = hasId || (isRealPlayer && avatar ? `avt:${avatar}` : `empty-${index}`);
    
    return {
        telephone: player?.telephone ?? '',
        userid: hasId || (isRealPlayer && avatar ? `avt:${avatar}` : ''),
        wechat_id,
        nickname,
        avatar,
        score: player?.score ?? '-',
    };
}

const seedRankPlayersFromLoading = () => {
    rankPlayers.value = Array.from(
        { length: RANK_LIMIT },
        (_, index) => {
            const player = loadingPlayers.value[index]

            if (!player?.userid && !player?.wechat_id) {
                return emptyRankPlayer(index)
            }

            return playerToRankPlayer(player, index)
        },
    )
}

function showSubmitWaiting() {
    if (!isSubmitWaiting.value) {        submitWaitingSeconds.value = 5
        if (submitWaitingTimer) {
            window.clearInterval(submitWaitingTimer)
        }
        submitWaitingTimer = window.setInterval(() => {
            submitWaitingSeconds.value = Math.max(0, submitWaitingSeconds.value - 1)
            if (submitWaitingSeconds.value <= 0 && submitWaitingTimer) {
                window.clearInterval(submitWaitingTimer)
                submitWaitingTimer = undefined
            }
        }, 1000)
    }
    isSubmitWaiting.value = true
}

function clearSubmitWaiting() {
    isSubmitWaiting.value = false
    submitWaitingSeconds.value = 5
    if (submitWaitingTimer) {
        window.clearInterval(submitWaitingTimer)
        submitWaitingTimer = undefined
    }
}

const resetRoundState = () => {
    playerCount.value = 0
    loadingPlayers.value = Array.from({ length: PLAYER_LIMIT }, emptyLoadingPlayer)
    rankPlayers.value = Array.from({ length: RANK_LIMIT }, (_, index) => emptyRankPlayer(index))
    isPlayingStartAnimation = false
    clearSubmitWaiting()
}

const gotoLoading = (reset = false) => {
    if (reset) {
        resetRoundState()
    }

    screen.value = 'loading'
}

const gotoRank1WithIntro = async () => {
    if (isPlayingStartAnimation) return

    isPlayingStartAnimation = true
    seedRankPlayersFromLoading()
    // 进入游戏画面前确保背景音乐播放中
    playGame5Music()
    screen.value = 'rank1'
    await nextTick()
    await rank1Ref.value?.startIntro()
    showSubmitWaiting()
    isPlayingStartAnimation = false
}

function handleRoomState(data: any) {
    console.log('[WebSocket] 房间状态更新 - status:', data?.status, '数据:', JSON.stringify(data))
    if ((data?.status === 0 || data?.status === 1) && Array.isArray(data?.list)) {
            renderPlayers(data)
        }

    switch (data?.status) {
        case 0:
            gotoLoading(true)
            createRoom(5)
            break
        case 1:
            gotoLoading()
            break
        case 2:
                        screen.value = 'rank1'
            clearSubmitWaiting()
                break
        case 3:
                showSubmitWaiting()
                break
            case 4:
                clearSubmitWaiting()
                if (Array.isArray(data?.list)) {
                    updateRankPlayers(data.list)
                }
                screen.value = 'rank2'
                break
    }
}

const { startGame, createRoom, closeRoom, backRoom } = useAdminGameSocket({
    gameId: 'game5',
    onAny: (evt, payload) => {
        console.log("[Game5 WebSocket] 🔥 onAny 触发 - event:", evt, "payload:", JSON.stringify(payload));
    },
    onRoomState: handleRoomState,
    onRoomJoin: (data) => {
        console.log('[Game5] onRoomJoin 触发 - 数据:', JSON.stringify(data))
        renderPlayers(data)
        gotoLoading()
    },
    onGameStart: () => {
        console.log('[Game5] 游戏开始！')
        gotoRank1WithIntro()
    },
    onRoomRank: (data) => {
        console.log('[Game5] onRoomRank 触发 - 数据:', JSON.stringify(data))
        updateRankPlayers(data)
    },
    onRelogin: async () => {
        $remove_socket_storage();
        await router.replace('/')
    }
})

const startGameWithMusic = () => {
    // 确保背景音乐播放
    playGame5Music()
    

    if (playerCount.value == 0) {
        $toast('房间中没有玩家');
        return;
    }
    startGame()
}

const nextRound = () => {
    // 立刻停止喝彩音乐并移除指针事件监听，防止点击按钮时重新触发 playApplauseMusic
    stopApplauseMusic()
    

    gotoLoading(true)
    // 等待组件卸载完成后再确保 BGM 播放
    nextTick().then(() => playGame5Music())
    //重开房间
    backRoom(5)
}

const nextRoundWithMusic = () => {
    nextRound()
}

onMounted(() => {
    window.addEventListener('beforeunload', confirmRefresh)
    playGame5Music()
})

onUnmounted(() => {
    stopAllMusic()
    window.removeEventListener('beforeunload', confirmRefresh)
})

const backHandler = async() => {
    // 立刻停止喝彩音乐并移除指针事件监听，防止点击按钮时重新触发 playApplauseMusic
    stopApplauseMusic()
    

    const ok = await $confirm({
        title: '提示',
        message: '是否关闭当前房间回到首页',
        confirmText: '确定',
        cancelText: '取消',
    })
    if (ok) {
        closeRoom();
        stopAllMusic()
        router.replace('/main');
    }
}

watch(screen, (value) => {
    // console.log(value);
    if(value == 'rank2'){
        playApplauseMusic();
    }else if(value == 'loading'){
        playGame5Music();
    }
})
</script>

<template>
    <Loading v-if="screen === 'loading'" :players="loadingPlayers" :player-count="playerCount"
        @start="startGameWithMusic" @back="backHandler" />
    <Rank1 v-else-if="screen === 'rank1'" ref="rank1Ref" :rank-list="rankPlayers" @start="startGameWithMusic"
        @next="nextRoundWithMusic" />
    <!-- <Rank1 v-else ref="rank1Ref" :rank-list="rankPlayers" @start="startGameWithMusic" -->
    <Rank2 v-else :rank-list="rankPlayers" @next="nextRoundWithMusic" @back="backHandler" />
    <div v-if="isSubmitWaiting" class="submit-waiting-overlay">
        <div class="submit-waiting-title">正在等待玩家提交分数</div>
        <div :key="submitWaitingSeconds" class="submit-waiting-count">{{ submitWaitingSeconds }}</div>
    </div>
</template>

<style scoped>
.submit-waiting-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.22) 0%, rgba(0, 0, 0, 0.08) 48%, transparent 72%);
    color: #fff;
    pointer-events: none;
}

.submit-waiting-title {
    position: absolute;
    bottom: 8vh;
    left: 0;
    width: 100%;
    font-size: 56px;
    font-weight: 700;
    line-height: 1;
    text-align: center;
    text-shadow: 0 10px 24px rgba(0, 0, 0, 0.35);
}

.submit-waiting-count {
    color: white;
    font-size: 300pt;
    font-weight: 800;
    line-height: 1;
    text-shadow: 0 18px 38px rgba(0, 0, 0, 0.25);
    animation: submit-countdown-pop 1s ease both;
}

@keyframes submit-countdown-pop {
    0% {
        opacity: 0;
        transform: scale(0.45);
    }

    18% {
        opacity: 1;
        transform: scale(1.14);
    }

    58% {
        opacity: 1;
        transform: scale(1);
    }

    100% {
        opacity: 0;
        transform: scale(0.84);
    }
}
</style>
