<script setup>
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
import { onLoad, onShow, onHide } from "@dcloudio/uni-app";
import Container from "@/components/Container.vue";
import BowTarget from "@/components/BowTarget.vue";
import ShootProgress from "@/components/ShootProgress.vue";
import BattleHeader from "@/components/BattleHeader.vue";
import PlayerScore from "@/components/PlayerScore.vue";
import SButton from "@/components/SButton.vue";
import Avatar from "@/components/Avatar.vue";
import ScreenHint from "@/components/ScreenHint.vue";
import TestDistance from "@/components/TestDistance.vue";
import audioManager from "@/audioManager";
import { getCurrentGameAPI, laserCloseAPI } from "@/apis";
import { isGameEnded } from "@/util";
import { MESSAGETYPES } from "@/constants";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user } = storeToRefs(store);
const title = ref("大乱斗");
const start = ref(false);
const startCount = ref(true);
const battleId = ref("");
const currentRound = ref(1);
const scores = ref([]);
const tips = ref("即将开始...");
const players = ref([]);
const playersSorted = ref([]);
const playersScores = ref({});
const halfTimeTip = ref(false);
const isEnded = ref(false);

watch(
  () => [players.value, playersScores.value],
  ([n_players, n_scores]) => {
    if (n_players.length) {
      playersSorted.value = Object.keys(n_scores)
        .sort((a, b) => n_scores[b].length - n_scores[a].length)
        .map((pid) => n_players.find((p) => p.id == pid));
    }
  },
  {
    deep: true, // 添加深度监听
    immediate: true,
  }
);

function recoverData(battleInfo) {
  uni.removeStorageSync("last-awake-time");
  // 注释用于测试
  battleId.value = battleInfo.id;
  players.value = [...battleInfo.blueTeam, ...battleInfo.redTeam];
  players.value.forEach((p) => {
    playersScores.value[p.id] = [...p.arrows];
    if (p.id === user.value.id) scores.value = [...p.arrows];
  });
  const remain = Date.now() / 1000 - battleInfo.startTime;
  console.log(`当前局已进行${remain}秒`);
  if (battleInfo.status === 0) {
    if (remain > 0) {
      setTimeout(() => {
        uni.$emit("update-timer", 15 - remain);
      }, 200);
    }
  } else {
    start.value = true;
  }
  if (battleInfo.status === 2) {
    const elapsedTime = (Date.now() - Date.parse(battleInfo.createdAt)) / 1000;
    console.log("elapsedTime:", elapsedTime);
    startCount.value = true;
    // 这里的开始时间不是游戏开始时间，而是上半场或者下半场或者中场的开始时间，还要根据状态来判断
    tips.value = battleInfo.halfGame
      ? "下半场：请再射6箭"
      : "上半场：请先射6箭";
    setTimeout(() => {
      uni.$emit("update-ramain", 90 - remain);
    }, 200);
  } else if (battleInfo.status === 9) {
    startCount.value = false;
    tips.value = "准备下半场";
    setTimeout(() => {
      uni.$emit("update-ramain", 0);
    }, 200);
  }
}

onLoad(async (options) => {
  if (options.gameMode == 1) title.value = "好友约战 - 大乱斗";
  if (options.gameMode == 2) title.value = "排位赛 - 大乱斗";
  if (options.battleId) {
    battleId.value = options.battleId;
    const players = uni.getStorageSync("melee-players");
    if (players) {
      players.value = players;
      players.value.forEach((p) => {
        playersScores.value[p.id] = [];
      });
    }
    const battleInfo = uni.getStorageSync("current-battle");
    if (battleInfo) {
      recoverData(battleInfo);
      setTimeout(getCurrentGameAPI, 2000);
    }
  }
  uni.enableAlertBeforeUnload({
    message: "离开比赛可能导致比赛失败，是否继续？",
    success: (res) => {
      console.log("已启用离开提示");
    },
  });
});

async function onReceiveMessage(messages = []) {
  messages.forEach((msg) => {
    if (msg.id !== battleId.value) return;
    if (msg.constructor === MESSAGETYPES.MeleeAllReady) {
      start.value = true;
      startCount.value = true;
      tips.value = scores.value.length
        ? "下半场：请再射6箭"
        : "上半场：请先射6箭";
      halfTimeTip.value = false;
    }
    if (msg.constructor === MESSAGETYPES.ShootResult) {
      if (!start.value) getCurrentGameAPI();
      if (msg.userId === user.value.id) {
        scores.value.push({ ...msg.target });
      }
      playersScores.value[msg.userId].push({ ...msg.target });
    }
    if (msg.constructor === MESSAGETYPES.HalfTimeOver) {
      uni.$emit("update-ramain", 0);
      [...msg.groupUserStatus.redTeam, ...msg.groupUserStatus.blueTeam].forEach(
        (player) => {
          playersScores.value[player.id] = [...player.arrows];
          if (player.id === user.value.id) scores.value = [...player.arrows];
        }
      );
      startCount.value = false;
      halfTimeTip.value = true;
      tips.value = "准备下半场";
    }
    if (msg.constructor === MESSAGETYPES.MatchOver) {
      isEnded.value = true;
      uni.setStorageSync("last-battle", msg.endStatus);
      setTimeout(() => {
        uni.redirectTo({
          url: "/pages/battle-result",
        });
      }, 1000);
    }
    if (msg.constructor === MESSAGETYPES.BackToGame) {
      uni.$emit("update-header-loading", false);
      if (msg.battleInfo) recoverData(msg.battleInfo);
    }
  });
}
onMounted(async () => {
  uni.setKeepScreenOn({
    keepScreenOn: true,
  });
  uni.$on("socket-inbox", onReceiveMessage);
  await laserCloseAPI();
});
onBeforeUnmount(() => {
  uni.setKeepScreenOn({
    keepScreenOn: false,
  });
  uni.$off("socket-inbox", onReceiveMessage);
  audioManager.stopAll();
});
const refreshTimer = ref(null);
onShow(async () => {
  if (battleId.value) {
    if (!isEnded.value && (await isGameEnded(battleId.value))) return;
    getCurrentGameAPI();
    const refreshData = () => {
      const lastAwakeTime = uni.getStorageSync("last-awake-time");
      if (lastAwakeTime) {
        getCurrentGameAPI();
      } else {
        clearInterval(refreshTimer.value);
      }
    };
    refreshTimer.value = setInterval(refreshData, 2000);
  }
});
onHide(() => {
  if (refreshTimer.value) clearInterval(refreshTimer.value);
  uni.setStorageSync("last-awake-time", Date.now());
});
</script>

<template>
  <Container :title="title" :bgType="1">
    <view class="container">
      <BattleHeader v-if="!start" :players="players" />
      <TestDistance v-if="!start" :guide="false" :isBattle="true" />
      <ShootProgress
        :show="start"
        :start="start && startCount"
        :tips="tips"
        :total="90"
        :melee="true"
        :battleId="battleId"
      />
      <view v-if="start" class="user-row">
        <Avatar :src="user.avatar" :size="35" />
        <BowPower />
      </view>
      <BowTarget
        v-if="start"
        :currentRound="scores.length"
        :totalRound="12"
        :scores="scores"
        :stop="!startCount"
      />
      <view :style="{ paddingBottom: '20px' }">
        <PlayerScore
          v-if="start"
          v-for="(player, index) in playersSorted"
          :key="index"
          :player="player"
          :scores="playersScores[player.id] || []"
        />
      </view>
      <ScreenHint
        :show="halfTimeTip"
        mode="small"
        :onClose="() => (halfTimeTip = false)"
      >
        <view class="half-time-tip">
          <text>上半场结束，休息一下吧:）</text>
          <text>20秒后开始下半场</text>
        </view>
      </ScreenHint>
    </view>
  </Container>
</template>

<style scoped>
.container {
  width: 100%;
  height: 100%;
}
</style>
