<script setup>
import { ref, onMounted, onBeforeUnmount, nextTick } from "vue";
import { onLoad, onShow, onHide } from "@dcloudio/uni-app";
import Container from "@/components/Container.vue";
import BattleHeader from "@/components/BattleHeader.vue";
import BowTarget from "@/components/BowTarget.vue";
import PlayersRow from "@/components/PlayersRow.vue";
import BattleFooter from "@/components/BattleFooter.vue";
import ScreenHint from "@/components/ScreenHint.vue";
import SButton from "@/components/SButton.vue";
import RoundEndTip from "@/components/RoundEndTip.vue";
import TestDistance from "@/components/TestDistance.vue";
import TeamAvatars from "@/components/TeamAvatars.vue";
import ShootProgress2 from "@/components/ShootProgress2.vue";
import { laserCloseAPI, getBattleAPI } from "@/apis";
import { isGameEnded, formatTimestamp } from "@/util";
import { MESSAGETYPES, MESSAGETYPESV2, roundsName } from "@/constants";
import audioManager from "@/audioManager";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user } = storeToRefs(store);
const start = ref(null);
const tips = ref("");
const battleId = ref("");
const currentRound = ref(0);
const goldenRound = ref(0);
const currentRedPoint = ref(0);
const currentBluePoint = ref(0);
const scores = ref([]);
const blueScores = ref([]);
const redTeam = ref([]);
const blueTeam = ref([]);
const currentShooterId = ref(0);
const roundResults = ref([]);
const redPoints = ref(0);
const bluePoints = ref(0);
const showRoundTip = ref(false);
const isFinalShoot = ref(false);

const recoverData = (battleInfo, { force = false, arrowOnly = false } = {}) => {
  try {
    battleId.value = battleInfo.matchId;
    blueTeam.value = battleInfo.teams[1].players || [];
    redTeam.value = battleInfo.teams[2].players || [];
    start.value = battleInfo.status !== 0;
    if (battleInfo.status === 0) {
      const readyRemain = (Date.now() - battleInfo.createTime) / 1000;
      console.log(`对局已进行${readyRemain}秒`);
      if (readyRemain > 0 && readyRemain < 15) {
        setTimeout(() => {
          uni.$emit("update-timer", 15 - readyRemain - 0.2);
        }, 200);
      }
      return;
    }
    if (!arrowOnly) {
      currentShooterId.value = battleInfo.current.playerId;
      const redPlayer = battleInfo.teams[2].players.find(
        (item) => item.id === battleInfo.current.playerId
      );
      let nextTips = redPlayer ? "请红队射箭" : "请蓝队射箭";
      if (force) nextTips += "重回";
      if (
        battleInfo.current.playerId === user.value.id &&
        redTeam.value.length > 1
      ) {
        nextTips += "你";
      }
      tips.value = nextTips;
      uni.$emit("update-tips", nextTips);
      if (force) {
        const remain = (Date.now() - battleInfo.current.startTime) / 1000;
        console.log(
          `当前轮已进行${remain}秒,${Date.now()},${
            battleInfo.current.startTimeText
          }`
        );
        if (remain > 0 && remain < 15) {
          setTimeout(() => {
            uni.$emit("update-remain", 15 - remain - 0.2);
          }, 200);
        }
      } else {
        uni.$emit("update-remain", battleInfo.readyTime);
      }
    } else {
      currentRound.value = battleInfo.current.round || 1;
      const latestRound = battleInfo.rounds[currentRound.value - 1];
      if (latestRound) {
        blueScores.value = latestRound.shoots[1];
        scores.value = latestRound.shoots[2];
      }
    }
    roundResults.value = battleInfo.rounds || [];
    isFinalShoot.value = battleInfo.current.goldRound;
    bluePoints.value = battleInfo.teams[1].score;
    redPoints.value = battleInfo.teams[2].score;
  } catch (err) {
    console.log(err);
  }
};

async function onReceiveMessage(msg) {
  if (Array.isArray(msg)) return;
  if (msg.type === MESSAGETYPESV2.BattleStart) {
    start.value = true;
  } else if (msg.type === MESSAGETYPESV2.ToSomeoneShoot) {
    recoverData(msg);
  } else if (msg.type === MESSAGETYPESV2.ShootResult) {
    recoverData(msg, { arrowOnly: true });
  } else if (msg.type === MESSAGETYPESV2.NewRound) {
    showRoundTip.value = true;
    const latestRound = msg.rounds[currentRound.value - 1];
    if (latestRound) {
      currentBluePoint.value = latestRound.scores[1].score;
      currentRedPoint.value = latestRound.scores[2].score;
    }
  } else if (msg.type === MESSAGETYPESV2.BattleEnd) {
    uni.redirectTo({
      url: "/pages/battle-result?battleId=" + msg.matchId,
    });
  }
}

onLoad(async (options) => {
  if (options.battleId) battleId.value = options.battleId;
  uni.enableAlertBeforeUnload({
    message: "离开比赛可能导致比赛失败，是否继续？",
    success: (res) => {
      console.log("已启用离开提示");
    },
  });
});
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) {
    const result = await getBattleAPI(battleId.value);
    if (result.status === 2) {
      uni.showToast({
        title: "比赛已结束",
        icon: "none",
      });
      uni.navigateBack({
        delta: 2,
      });
    } else {
      recoverData(result, { force: true });
    }
  }
});
</script>

<template>
  <Container :bgType="start ? 3 : 1">
    <view class="container">
      <BattleHeader
        v-if="start === false"
        :redTeam="redTeam"
        :blueTeam="blueTeam"
      />
      <TestDistance v-if="start === false" :guide="false" :isBattle="true" />
      <view v-if="start" class="players-row">
        <TeamAvatars
          :team="blueTeam"
          :isRed="false"
          :currentShooterId="currentShooterId"
        />
        <ShootProgress2
          :tips="tips"
          :currentRound="
            goldenRound > 0 ? 'gold' + goldenRound : 'round' + currentRound
          "
        />
        <TeamAvatars :team="redTeam" :currentShooterId="currentShooterId" />
      </view>
      <BowTarget
        v-if="start"
        mode="team"
        :scores="scores"
        :blueScores="blueScores"
      />
      <BattleFooter
        v-if="start"
        :roundResults="roundResults"
        :redPoints="redPoints"
        :bluePoints="bluePoints"
        :goldenRound="goldenRound"
      />
      <ScreenHint
        :show="showRoundTip"
        :onClose="() => (showRoundTip = false)"
        :mode="isFinalShoot ? 'tall' : 'normal'"
      >
        <RoundEndTip
          v-if="showRoundTip"
          :isFinal="isFinalShoot"
          :round="currentRound"
          :bluePoint="currentBluePoint"
          :redPoint="currentRedPoint"
          :roundData="
            roundResults[currentRound - 1] ? roundResults[currentRound - 1] : []
          "
          :onAutoClose="() => (showRoundTip = false)"
        />
      </ScreenHint>
    </view>
  </Container>
</template>

<style scoped>
.container {
  width: 100%;
  height: 100%;
}
.players-row {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: -2%;
  margin-bottom: 6%;
}
</style>
