<script setup lang="ts">
import { nextTick, onMounted, onUnmounted, ref, watch } from "vue";
import { playApplauseMusic, playGame4Music, stopAllMusic, stopApplauseMusic, stopGame4Music } from '@/commons/music'
import Loading from "./views/LoadingView.vue";
import Rank1 from "./views/Rank1View.vue";
import Rank2 from "./views/Rank2View.vue";
import { useAdminGameSocket } from "@/composables/useAdminGameSocket";
import { onSocketMessage } from "@/commons/ws";
import type Player from "@/commons/player.ts";
import { useRouter } from 'vue-router'
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 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 confirmRefresh = (event: BeforeUnloadEvent) => {
    // closeRoom();
    event.preventDefault()
    event.returnValue = ''
}

const renderPlayers = (data: any) => {
    const players = Array.isArray(data?.list) ? data.list : []
    playerCount.value = Number(data?.count ?? players.length)
    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 => ({
    telephone: player?.telephone ?? '',
    userid: player?.userid ?? '',
    wechat_id: player?.wechat_id || `empty-${index}`,
    nickname: player?.nickname || '虚位以待',
    avatar: player?.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)
        },
    )
}

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
}

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

    screen.value = 'loading'
}

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

    isPlayingStartAnimation = true
    seedRankPlayersFromLoading()
    // 对齐 game3：进入赛马画面前确保背景音乐播放中
    // 必须在 startIntro 之前调用，因为 startIntro 内部会 stopApplauseMusic() 误伤 BGM
    playGame4Music()
    screen.value = 'rank1'
    await nextTick()
    await rank1Ref.value?.startIntro()
    // 结果页已在 Rank1View 内部渲染（showResult + result-overlay），不需要切到 rank2
    isPlayingStartAnimation = false
}

const horseBoosts = ref<Record<string, number>>({});

const gameId = 'game4'
const { startGame, createRoom, backRoom, closeRoom } = useAdminGameSocket({
    gameId,
    onAny: (evt, payload) => {
        const data = payload?.data ?? payload;

        // 调试日志：打印 WebSocket 原始数据
        console.log("[Game4 WebSocket] 收到消息:", {
            event: evt,
            payloadType: typeof payload,
            dataType: typeof data,
            isArray: Array.isArray(data),
            rawPayload: payload,
        });

        if (!Array.isArray(data)) return;

        const boosts: Record<string, number> = {};
        let hasBoost = false;

        data.forEach((item: any) => {
            // WebSocket 数据无 userid/wechat_id，用 avatar 作为稳定标识
            const id = item.userid || item.wechat_id || item.avatar || "";
            if (!id) return;
            // 尝试多种字段名: score / boost / acceleration / speed / progress
            const raw = item.score ?? item.boost ?? item.acceleration ?? item.speed ?? item.progress;
            if (raw === undefined || raw === null) return;
            const val = Number(raw);
            if (isNaN(val)) return;
            // score/boost 范围 0~N，0 表示无加速，越大越快
            boosts[id] = Math.max(0, val);
            hasBoost = true;
        });

        if (hasBoost) {
            console.log("[Game4 WebSocket] 解析到加速数据:", boosts);
            horseBoosts.value = { ...boosts };
        }
    },
    onRoomState: (data: any) => {
        if (Array.isArray(data?.list)) {
            renderPlayers(data)
        }
        switch (data?.status) {
            case 0:
                gotoLoading(true)
                createRoom(4)
                break
            case 1:
                // if(data.gameId && data.gameId!=gameId){
                //     return;
                // }
                gotoLoading()
                break
            case 2:
                seedRankPlayersFromLoading()
                screen.value = 'rank1'
                break
            case 3:
                screen.value = 'rank1'
                break
        }
    },
    onRoomJoin: (data) => {
        renderPlayers(data)
        gotoLoading()
    },
    onGameStart: gotoRank1WithIntro,
    onRoomRank: updateRankPlayers,
    onRelogin: async () => {
        $remove_socket_storage();
        await router.replace('/')
    }
})

const startGameWithMusic = () => {
    // 本地调试模式：跳过 WebSocket，直接进入赛马画面（对齐 game3）
    // 注意：不在这里调 playGame4Music()，因为 onMounted 中已注册 pointerdown 监听器，
    // 点击按钮时 pointerdown 事件先于 click 触发，会自动播放 BGM。
    // 如果在此额外调用 playGame4Music()，会导致 stopAllMusic 销毁并重建 Audio，
    // 在复杂时序下可能 play() 失败，需要再点一次页面才能听到音乐。
    if ($is_local_mode()) {
        gotoRank1WithIntro()
        return
    }
    if (playerCount.value == 0) {
        // alert('房间中没有玩家')
        $toast('房间中没有玩家');
        return;
    }
    // 对齐 game3：点击"开始挑战"时确保背景音乐播放中
    playGame4Music()
    startGame()
}

const nextRound = () => {
    // 立刻停止喝彩音乐并移除指针事件监听，防止点击按钮时重新触发 playApplauseMusic
    stopApplauseMusic()
    if ($is_local_mode()) {
        // 本地模式：回到 loading 页，用户点击"开始挑战"后再进入赛马（对齐 game3）
        gotoLoading(true)
        return
    }
    gotoLoading(true)
    // 等待 Rank1View 卸载完成后再确保 BGM 播放（对齐 game3 的 watch 模式）
    // 用 nextTick 确保在组件卸载、watch 触发的 BGM 之后再次保证
    nextTick().then(() => playGame4Music())
    //重开房间
    backRoom(4)
}

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

const backHandler = async() => {
    // 立刻停止喝彩音乐并移除指针事件监听，防止点击按钮时重新触发 playApplauseMusic
    stopApplauseMusic()
    if ($is_local_mode()) {
        stopAllMusic()
        router.replace('/main')
        return
    }
    const ok = await $confirm({
        title: '提示',
        message: '是否关闭当前房间回到首页',
        confirmText: '确定',
        cancelText: '取消',
    })
    if (ok) {
        closeRoom();
        stopAllMusic()
        router.replace('/main');
    }
}

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

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

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

// type GameScreen = "loading" | "rank1" | "rank2";

// const PLAYER_LIMIT = 20;
// const RANK_LIMIT = 10;

// const emptyLoadingPlayer = () => ({
//   score: 0,
//   telephone: "",
//   userid: "",
//   wechat_id: "",
//   nickname: "虚位以待",
//   avatar: "",
// });

// const emptyRankPlayer = (index: number): Player => ({
//   active: false,
//   wechat_id: `empty-${index}`,
//   nickname: "虚位以待",
//   avatar: "",
//   score: 0,
// });

// const screen = ref<GameScreen>("loading");
// 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;

// // H5 操控传来的加速度: { [userid]: boost(叠加系数, 0~N) }
// const horseBoosts = ref<Record<string, number>>({});

// let offHorseBoost: (() => void) | undefined;

// // 监听 WebSocket 获取 H5 玩家操控的马匹加速度
// offHorseBoost = onSocketMessage((evt, payload) => {
//   const data = payload?.data ?? payload;

//   // 调试日志：打印 WebSocket 原始数据
//   console.log("[Game4 WebSocket] 收到消息:", {
//     event: evt,
//     payloadType: typeof payload,
//     dataType: typeof data,
//     isArray: Array.isArray(data),
//     rawPayload: payload,
//   });

//   if (!Array.isArray(data)) return;

//   const boosts: Record<string, number> = {};
//   let hasBoost = false;

//   data.forEach((item: any) => {
//     // WebSocket 数据无 userid/wechat_id，用 avatar 作为稳定标识
//     const id = item.userid || item.wechat_id || item.avatar || "";
//     if (!id) return;
//     // 尝试多种字段名: score / boost / acceleration / speed / progress
//     const raw = item.score ?? item.boost ?? item.acceleration ?? item.speed ?? item.progress;
//     if (raw === undefined || raw === null) return;
//     const val = Number(raw);
//     if (isNaN(val)) return;
//     // score/boost 范围 0~N，0 表示无加速，越大越快
//     boosts[id] = Math.max(0, val);
//     hasBoost = true;
//   });

//   if (hasBoost) {
//     console.log("[Game4 WebSocket] 解析到加速数据:", boosts);
//     horseBoosts.value = { ...boosts };
//   }
// });

// const confirmRefresh = (event: BeforeUnloadEvent) => {
//   event.preventDefault();
//   event.returnValue = "";
// };

// const renderPlayers = (data: any) => {
//   const players = Array.isArray(data?.list) ? data.list : [];
//   playerCount.value = Number(data?.count ?? players.length);
//   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 gotoLoading = (reset = false) => {
//   if (reset) {
//     playerCount.value = 0;
//     loadingPlayers.value = Array.from(
//       { length: PLAYER_LIMIT },
//       emptyLoadingPlayer,
//     );
//     rankPlayers.value = Array.from(
//       { length: RANK_LIMIT },
//       (_, index) => emptyRankPlayer(index),
//     );
//     isPlayingStartAnimation = false;
//   }
//   screen.value = "loading";
// };

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

//   isPlayingStartAnimation = true;
//   screen.value = "rank1";
//   await nextTick();
//   await rank1Ref.value?.startIntro();
//   // 结果页已在 Rank1View 内部渲染，不需要切到 rank2
//   isPlayingStartAnimation = false;
// };

// function handleRoomState(data: any) {
//   if (Array.isArray(data?.list)) {
//     renderPlayers(data);
//   }

//   switch (data?.status) {
//     case 0:
//       gotoLoading(true);
//       createRoom(4);
//       break;
//     case 1:
//       gotoLoading();
//       break;
//     case 2:
//       screen.value = "rank1";
//       break;
//     case 3:
//       screen.value = "rank2";
//       break;
//   }
// }

// const { startGame, createRoom, backRoom, requestRoomState, closeRoom } = useAdminGameSocket({
//   gameId: "game4",
//   // loginRedirectPath: '/game4',
//   onRoomState: handleRoomState,
//   onRoomJoin: (data) => {
//     renderPlayers(data);
//     gotoLoading();
//   },
//   onGameStart: gotoRank1WithIntro,
//   onRoomRank: updateRankPlayers,
// });

// const nextRound = () => {
//   gotoLoading(true);
//   // 使用 backRoom 重置已有房间，而非 createRoom 重复创建
//   backRoom(1);
//   setTimeout(() => {
//     requestRoomState();
//   }, 200);
// };

// onMounted(() => {
//   window.addEventListener("beforeunload", confirmRefresh);
//   playGame4Music()
// });

// onUnmounted(() => {
//   stopGame4Music()
//   window.removeEventListener("beforeunload", confirmRefresh);
//   offHorseBoost?.();
// });

// const backHandler = () => {
//   if (confirm('是否关闭当前房间回到首页')) {
//     closeRoom();
//     stopGame4Music()
//     router.replace('/main');
//   }
// }
</script>

<template>
    <Loading v-if="screen === 'loading'" :players="loadingPlayers" :player-count="playerCount"
        @start="startGameWithMusic" @back="backHandler" />
    <Rank1 v-if="screen === 'rank1'" ref="rank1Ref" :rank-list="rankPlayers" :horse-boosts="horseBoosts"
        @start="startGameWithMusic" @next="nextRound" @back="backHandler" />
    <!-- <Rank2 v-else-if="screen === 'rank2'" :rank-list="rankPlayers" @next="nextRound" /> -->
</template>
