<script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import { onShow } from "@dcloudio/uni-app";
import Container from "@/components/Container.vue";
import ShootProgress from "@/components/ShootProgress.vue";
import BowTarget from "@/components/BowTarget.vue";
import ScorePanel2 from "@/components/ScorePanel2.vue";
import ScoreResult from "@/components/ScoreResult.vue";
import SButton from "@/components/SButton.vue";
import Avatar from "@/components/Avatar.vue";
import BowPower from "@/components/BowPower.vue";
import TestDistance from "@/components/TestDistance.vue";
import BubbleTip from "@/components/BubbleTip.vue";
import audioManager from "@/audioManager";
import { createPractiseAPI } from "@/apis";
import { generateCanvasImage, wxShare, debounce } from "@/util";
import { MESSAGETYPES, roundsName } from "@/constants";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user } = storeToRefs(store);
const start = ref(false);
const scores = ref([]);
const total = 12;
const currentRound = ref(0);
const practiseResult = ref({});
const practiseId = ref("");
const showGuide = ref(false);
const tips = ref("");
const wait = ref(0);
const timer = ref(null);

const onReady = async () => {
  const result = await createPractiseAPI(total, 2);
  if (result) practiseId.value = result.id;
  currentRound.value = 0;
  scores.value = [];
  start.value = true;
  audioManager.play("练习开始");
};

async function onReceiveMessage(messages = []) {
  messages.forEach((msg) => {
    if (msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) {
      if (scores.value.length < total) {
        scores.value.push(msg.target);
        currentRound.value += 1;
        if (currentRound.value === 4) {
          currentRound.value = 1;
        }
        if (practiseId && scores.value.length === total / 2) {
          showGuide.value = true;
          setTimeout(() => {
            showGuide.value = false;
          }, 3000);
        }
      }
    } else if (msg.constructor === MESSAGETYPES.ShootSyncMePracticeID) {
      if (practiseId.value && practiseId.value === msg.practice.id) {
        if (timer.value) {
          clearInterval(timer.value);
          timer.value = null;
        }
        setTimeout(() => {
          start.value = false;
          practiseResult.value = {
            ...msg.practice,
            arrows: JSON.parse(msg.practice.arrows),
            lvl: msg.lvl,
          };
        }, 1500);
      }
    } else if (msg.constructor === MESSAGETYPES.HalfTimeOver) {
      wait.value = msg.wait;
      if (msg.wait === 20) {
        uni.$emit("update-ramain", 0);
        for (let i = 0; i < 6; i++) {
          if (!scores.value[i]) scores.value[i] = { x: -30, y: -30, ring: 0 };
        }
      }
      if (msg.wait === 0) {
        let count = 60;
        uni.$emit("update-ramain", count);
        audioManager.play("练习开始");
        if (!timer.value) {
          timer.value = setInterval(() => {
            count -= 1;
            if (count === 30) {
              audioManager.play("最后30秒");
              clearInterval(timer.value);
              timer.value = null;
            }
          }, 1000);
        }
      }
    }
  });
}

async function onComplete() {
  const validArrows = (practiseResult.value.arrows || []).filter(
    (a) => a.x !== -30 && a.y !== -30
  );
  if (validArrows.length === total) {
    uni.navigateBack();
  } else {
    practiseId.value = "";
    practiseResult.value = {};
    start.value = false;
    scores.value = [];
    currentRound.value = 0;
  }
}

const onClickShare = debounce(async () => {
  await generateCanvasImage("shareCanvas", 2, user.value, practiseResult.value);
  await wxShare("shareCanvas");
});

onMounted(() => {
  audioManager.play("第一轮");
  uni.setKeepScreenOn({
    keepScreenOn: true,
  });
  uni.$on("socket-inbox", onReceiveMessage);
  uni.$on("share-image", onClickShare);
});

onBeforeUnmount(() => {
  uni.setKeepScreenOn({
    keepScreenOn: false,
  });
  uni.$off("socket-inbox", onReceiveMessage);
  uni.$off("share-image", onClickShare);
  audioManager.stopAll();
  if (timer.value) {
    clearTimeout(timer.value);
    timer.value = null;
  }
});
</script>

<template>
  <Container :bgType="1" title="个人单组练习">
    <view>
      <TestDistance v-if="!practiseId" />
      <block v-if="practiseId">
        <ShootProgress
          :tips="`${
            !start || scores.length === 12
              ? ''
              : `请开始射箭第${
                  roundsName[Math.ceil((scores.length + 1) / 3)]
                }轮`
          }`"
          :start="start"
          :total="60"
        />
        <view class="user-row">
          <Avatar :src="user.avatar" :size="35" />
          <BubbleTip v-if="showGuide" type="normal2">
            <text>还有两场，坚持</text>
            <text>就是胜利！💪</text>
          </BubbleTip>
          <BowPower />
        </view>
        <BowTarget
          :totalRound="start ? total / 4 : 0"
          :currentRound="currentRound"
          :scores="scores"
          :stop="wait > 0"
        />
        <ScorePanel2 :scores="scores.map((s) => s.ring)" />
        <ScoreResult
          v-if="practiseResult.arrows"
          :rowCount="6"
          :total="total"
          :onClose="onComplete"
          :result="practiseResult"
          :tipSrc="`../static/${
            practiseResult.arrows.filter(
              (arrow) => arrow.x !== -30 && arrow.y !== -30
            ).length < total
              ? 'un'
              : ''
          }finish-tip.png`"
        />
        <canvas class="share-canvas" canvas-id="shareCanvas"></canvas>
      </block>
    </view>
    <view :style="{ marginBottom: '20px' }">
      <SButton v-if="!start" :onClick="onReady">准备好了，直接开始</SButton>
    </view>
  </Container>
</template>

<style scoped></style>
