<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from "vue";
import { cssAssetUrl } from "@/commons/assets.ts";
import MobileStage from "@/components/MobileStage.vue";
import {
  useGameSocket,
  sendGameMessage,
  userJoinStatus,
  joinSharedRoom,
  userTop10RankStatus,
} from "@/composables/useGameSocket";
import LoadingView from "./views/LoadingView.vue";
import PlayingView from "./views/PlayingView.vue";
import ScoreView from "./views/ScoreView.vue";
import { $alreadyRankedToast, $getWechat, $toast, $is_run_local } from "@/commons/utils.ts";

const gameId = "game4";
type GameView = "loading" | "playing" | "score";

// 本地模式检测
const isLocalMode = $is_run_local();
console.log('[Game4 H5] 本地模式:', isLocalMode);

const imageUrls = {
  bg: cssAssetUrl("game4/h5-game4-bg.webp"),
  bg2: cssAssetUrl("game1/bg2.png"),
  playBg: cssAssetUrl("game4/h5-game4-bg2.webp"),
  logo: cssAssetUrl("game4/logo.webp"),
  time: cssAssetUrl("game4/h5-game4-clock.svg"),
  title: cssAssetUrl("game4/h5-game4-title1.webp"),
  title2: cssAssetUrl("game4/h5-game4-title2.webp"),
  // avatarBg: cssAssetUrl('game4/h5-game4-join.svg'),
  userBg: cssAssetUrl("game4/user-bg.svg"),
  startBg: cssAssetUrl("game4/start-bg.svg"),
  gift: cssAssetUrl("game4/h5-game4-gift.webp"),
  avatar: cssAssetUrl("game1/avatar.png"),
  gu: cssAssetUrl("game4/h5-game4-horse.webp"),
  clock: cssAssetUrl("game1/clock.png"),
  horse: cssAssetUrl("game4/h5-game4-horse.webp"),
  yaoyiyao: cssAssetUrl("game4/h5-game4-yaoyiyao.svg"),
  scoreBg: cssAssetUrl("game1/score-bg.png"),
  back: cssAssetUrl("game4/back.svg"),
  replay: cssAssetUrl("game4/replay.svg"),

  close: cssAssetUrl("game1/close.png"),
  rule: cssAssetUrl("game1/rule.png"),
};

const wechat = $getWechat();
const currentView = ref<GameView>("loading");

const stageBackground = computed(() => {
  if (currentView.value === "playing") {
    return `${imageUrls.playBg} center/cover`;
  }
  return `${imageUrls.bg} center/cover`;
});
const countdownInterval = ref(60);
const isDivDescVisible = ref(false);
const isGameEnded = ref(false);
const tick = ref(0); // 点击次数/摇动次数
const rank = ref(0); // 排名
const roomStatus = ref(0)
const hasFinalScoreResult = ref(false)
const currentHorse = ref(imageUrls.horse);
const currentYaoyiyao = ref(imageUrls.yaoyiyao);
const token = ref(wechat?.token ?? "");
const nickname = ref(wechat?.nickname ?? "");
const avatar = ref(wechat?.avatar ?? "");
const showGameRule = ref(true);

const mobileStageRef = ref<InstanceType<typeof MobileStage> | null>(null);
const _offSocketMessage = ref<(() => void) | undefined>();

let gameCountdownTimer: ReturnType<typeof window.setTimeout> | undefined;

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

function getServerRank(data: any, fallback?: unknown) {
  const value =
    typeof data === "object" && data
      ? data.rank ?? data.rank_no ?? data.rankNo ?? data.game_rank ?? data.gameRank ?? fallback
      : data;
  const nextRank = Number(value);
  return Number.isFinite(nextRank) && nextRank > 0 ? nextRank : 0;
}


function showFinalScoreIfReady() {
    if (roomStatus.value !== 4 || !hasFinalScoreResult.value) return
    hasFinalScoreResult.value = false
    showScoreView()
}

function markFinalScoreResult() {
    hasFinalScoreResult.value = true
    showFinalScoreIfReady()
}

function syncFinalStatus(data: any) {
    const nextStatus = Number(data?.status)
    if (!Number.isFinite(nextStatus)) return

    roomStatus.value = nextStatus
    if (nextStatus === 3) {
        return
    }
    if (nextStatus !== 4) return

    const nextRank = getServerRank(data)
    const nextScore = Number(data?.score)
    if (nextRank > 0) {
        rank.value = nextRank
    }
    if (Number.isFinite(nextScore) && nextScore >= 0) {
        tick.value = nextScore
    }
    showFinalScoreIfReady()
}

function setDivDescVisible(visible: boolean) {
  isDivDescVisible.value = visible;
}

function stopGameCountdown() {
  if (gameCountdownTimer) {
    window.clearTimeout(gameCountdownTimer);
    gameCountdownTimer = undefined;
  }
}

function submitScore(save: boolean = false, currentTick = tick.value) {
  // 最后提交保存在数据库中
  if (save) {
    // item_num 游戏项目(1到6)
    // wechat 原始token
    return sendGameMessage("submit_score_save", {
      score: currentTick,
      wechat: wechat.token,
      item_num: 4,
      nickname: wechat.nickname,
      avatar: wechat.avatar,
      rank: rank.value,
    });
  } else {
    return sendGameMessage("submit_score", { score: currentTick });
  }
}

function startGameCountdown(seconds = 60) {
  stopGameCountdown();
  countdownInterval.value = seconds;
  setDivDescVisible(true);

  const tickCountdown = () => {
    countdownInterval.value -= 1;

    if (countdownInterval.value <= 0) {
      countdownInterval.value = 0;
      gameCountdownTimer = undefined;
      setDivDescVisible(false);
      isGameEnded.value = true;
      const sent = submitScore(true);
      if (userTop10RankStatus.value) {
        userJoinStatus.value = false;
        // showGameRank.value = false;
        $alreadyRankedToast()
      } else if (sent) {
        $toast('成绩提交中，请稍候...', 5000)
      }
      return;
    }

    gameCountdownTimer = window.setTimeout(tickCountdown, 1000);
  };

  gameCountdownTimer = window.setTimeout(tickCountdown, 1000);
}

function syncGameCountdown(seconds: number) {
  const syncedSeconds = Math.max(0, Math.floor(seconds));
  if (countdownInterval.value - syncedSeconds <= 1) return;

  if (syncedSeconds === 0) {
    countdownInterval.value = 0;
    return;
  }

  startGameCountdown(syncedSeconds);
}

function showLoadingView() {
  stopGameCountdown();
  currentView.value = "loading";
  setDivDescVisible(false);
  // alert('管理员关闭了游戏房间')
  $toast("管理员关闭了游戏房间");
}

function resetToLoadingView() {
  stopGameCountdown();
  tick.value = 0;
  rank.value = 0;
  countdownInterval.value = 60;
  currentHorse.value = imageUrls.horse;
  currentYaoyiyao.value = imageUrls.yaoyiyao;
  userJoinStatus.value = false;
  currentView.value = "loading";
  setDivDescVisible(false);
}

function startGameView() {
  stopGameCountdown();
  tick.value = 0;
  currentHorse.value = imageUrls.horse;
  isGameEnded.value = false;
  currentView.value = "playing";
  startGameCountdown(60);
}

function showScoreView() {
  stopGameCountdown();
  setDivDescVisible(false);
  currentView.value = "score";
}

function replayGame() {
  startGameView();
}

function backToWaiting() { }

function handleRoomBack() { }

const touchHandler = () => {
  const nextTick = tick.value + 5;
  if (!submitScore(false, nextTick)) return;
  tick.value = nextTick;
};

const showGameRuleHandler = () => {
  showGameRule.value = !showGameRule.value;
};

if (wechat || isLocalMode) {
  if (isLocalMode) {
    // 本地模式：模拟用户数据
    console.log('[Game4 H5] 本地模式启动，模拟用户数据');
    token.value = 'local-token';
    nickname.value = '本地测试玩家';
    avatar.value = 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=local';
    userJoinStatus.value = true;
  }
  
  const { offSocketMessage } = useGameSocket({
    gameId,
    auth: {
      userid: wechat?.token || 'local-token',
    },
    onConnect: () => {
      if (isLocalMode) {
        console.log('[Game4 H5] 本地模式：跳过 WebSocket 连接');
        return;
      }
      window.setTimeout(() => {
        const joined = joinSharedRoom(
          nickname.value,
          token.value,
          avatar.value,
          gameId,
        );
      }, 200);
    },
    onGameStart: async () => {
      showGameRule.value = false;
      await mobileStageRef.value?.startCountdown();
      startGameView();
    },
    onScoreSubmitted: (is_save, data) => {
      const nextScore = Number(typeof data === "object" ? data?.score : NaN);
      const nextRank = getServerRank(data);
      const remainingSeconds = Number(
        typeof data === "object" ? data?.remainingSeconds : NaN,
      );
      if (!is_save && Number.isFinite(nextScore) && nextScore >= 0) {
        tick.value = nextScore;
      }
      if (
        !is_save &&
        Number.isFinite(remainingSeconds) &&
        remainingSeconds >= 0
      ) {
        syncGameCountdown(remainingSeconds);
      }
      if (nextRank > 0) {
        rank.value = nextRank;
      }
      if (is_save) {
        markFinalScoreResult();
      }
      return { code: "CMYF", score: tick.value, rank_no: rank.value };
    },
    onStatus: syncFinalStatus,
        onRescoreSubmitted: (_recount) => {
            submitScore(true)
        },
    onRoomClosed: showLoadingView,
    onRoomBack: handleRoomBack,
    onGameRecover: () => {
      debugger;
    },
  });
  _offSocketMessage.value = offSocketMessage;
}

onMounted(() => {
  document.title = "互动游戏 - 策马迎福";
  if (token.value) {
    window.addEventListener("beforeunload", confirmRefresh);
  }
  
  // 本地模式：自动开始游戏
  if (isLocalMode) {
    console.log('[Game4 H5] 本地模式：2秒后自动开始游戏');
    setTimeout(() => {
      startGameView();
    }, 3000);
  }
});

onBeforeUnmount(() => {
  _offSocketMessage.value?.();
  stopGameCountdown();
  if (token.value) {
    window.removeEventListener("beforeunload", confirmRefresh);
  }
});
</script>

<template>
  <MobileStage v-if="token || isLocalMode" :showGameRule="showGameRule" ref="mobileStageRef" :background="stageBackground">
    <template #gameRule>
      <div class="rule-container">
        <div class="rule-txt-container">
          <div class="rule-title">游戏规则</div>
          <div class="rule-txt">
            <!-- 微信用户通过扫描大屏幕二维码参与，可容纳多人同时进行，摇晃手机控制赛马奔跑，摇晃越快赛马跑得越快，游戏结束按分值高低先后排名，有机会获得新疆福彩定制周边礼品一份。 -->
            1. 主持人开赛即可摇手机，单次摇晃得 5 分；<br />
            2. 得分越高大屏幕上面的马跑得越快；<br />
            3. 限时比拼摇速，结束后按积分排名；<br />
            4. 高分用户有机会领取新疆福彩定制周边；<br />
            5. 禁止外挂作弊，违规账号取消成绩与领奖资格；<br /><br />
            祝您游戏愉快！
          </div>
          <div class="rule-close" @click="showGameRuleHandler"></div>
        </div>
      </div>
    </template>
    <LoadingView v-if="currentView === 'loading'" :image-urls="imageUrls" :user-join-status="userJoinStatus"
      @touchGameRule="showGameRuleHandler" />
    <!-- <PlayingView v-else :image-urls="imageUrls" :tick="tick" :rank="rank" -->
    <PlayingView v-else-if="currentView === 'playing'" :image-urls="imageUrls" :tick="tick" :rank="rank"
      :currentHorse="currentHorse" :currentYaoyiyao="currentYaoyiyao" :countdown-interval="countdownInterval"
      :is-div-desc-visible="isDivDescVisible" :is-game-ended="isGameEnded" @touch="touchHandler"
      :userTop10RankStatus="userTop10RankStatus" />
    <ScoreView v-else :image-urls="imageUrls" :tick="tick" :level="rank" @replay="replayGame" @back="backToWaiting" />
  </MobileStage>
  <div v-else style="
      text-align: center;
      width: 100vw;
      height: 100vh;
      line-height: 30;
      font-size: 20px;
    ">
    请使用微信扫码进入游戏
  </div>
</template>
<style scoped>
.rule-container {
  .rule-txt-container {
    background: v-bind("imageUrls.rule") center / cover no-repeat;
    width: 692px;
    height: 797px;
    margin-top: -20%;
    transform: scale(0.5);

    .rule-title {
      text-align: center;
      color: white;
      font-weight: bold;
      font-size: 26pt;
      line-height: 50pt;
      letter-spacing: 4px;
    }

    .rule-txt {
      font-size: 26pt;
      padding: 40px;
      margin-top: 10px;
      color: #aa0000;
    }
  }

  .rule-close {
    width: 57px;
    height: 57px;
    background: v-bind("imageUrls.close") center / cover no-repeat;
    transform: translateX(-50%) scale(1.5);
    position: absolute;
    top: -73px;
    left: 100%;
    margin-left: -48px;
  }
}
</style>
