<script setup>
import { ref, watch, onMounted, onBeforeUnmount, computed } from "vue";
import StartCountdown from "@/components/StartCountdown.vue";
import { MESSAGETYPES } from "@/constants";
import { simulShootAPI } from "@/apis";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user, device } = storeToRefs(store);

const props = defineProps({
  currentRound: {
    type: Number,
    default: 0,
  },
  totalRound: {
    type: Number,
    default: 0,
  },
  avatar: {
    type: String,
    default: "",
  },
  scores: {
    type: Array,
    default: () => [],
  },
  blueScores: {
    type: Array,
    default: () => [],
  },
  mode: {
    type: String,
    default: "solo", // solo 单排，team 双排
  },
  // start: {
  //   type: Boolean,
  //   default: false,
  // },
  stop: {
    type: Boolean,
    default: false,
  },
});

const latestOne = ref(null);
const bluelatestOne = ref(null);
const prevScores = ref([]);
const prevBlueScores = ref([]);
const timer = ref(null);
const dirTimer = ref(null);
const angle = ref(null);
const circleColor = ref("");

watch(
  () => props.scores,
  (newVal) => {
    if (newVal.length - prevScores.value.length === 1) {
      latestOne.value = newVal[newVal.length - 1];
      if (timer.value) clearTimeout(timer.value);
      timer.value = setTimeout(() => {
        latestOne.value = null;
      }, 1000);
    }
    prevScores.value = [...newVal];
  },
  {
    deep: true,
  }
);

watch(
  () => props.blueScores,
  (newVal) => {
    if (newVal.length - prevBlueScores.value.length === 1) {
      bluelatestOne.value = newVal[newVal.length - 1];
      if (timer.value) clearTimeout(timer.value);
      timer.value = setTimeout(() => {
        bluelatestOne.value = null;
      }, 1000);
    }
    prevBlueScores.value = [...newVal];
  },
  {
    deep: true,
  }
);

function calcRealX(num, offset = 3.4) {
  const len = 20.4 + num;
  return `calc(${(len / 40.8) * 100 - offset / 2}%)`;
}
function calcRealY(num, offset = 3.4) {
  const len = num < 0 ? Math.abs(num) + 20.4 : 20.4 - num;
  return `calc(${(len / 40.8) * 100 - offset / 2}%)`;
}
const simulShoot = async () => {
  if (device.value.deviceId) await simulShootAPI(device.value.deviceId);
};
const simulShoot2 = async () => {
  if (device.value.deviceId) await simulShootAPI(device.value.deviceId, 1, 1);
};

const env = computed(() => {
  const accountInfo = uni.getAccountInfoSync();
  return accountInfo.miniProgram.envVersion;
});

const arrowStyle = computed(() => {
  return {
    transform: `rotateX(180deg) translate(-50%, -50%) rotate(${
      360 - angle.value
    }deg) translateY(105%)`,
  };
});

async function onReceiveMessage(messages = []) {
  messages.forEach((msg) => {
    if (
      msg.constructor === MESSAGETYPES.ShootSyncMeArrowID ||
      msg.constructor === MESSAGETYPES.ShootResult
    ) {
      if (
        msg.userId === user.value.id &&
        !msg.target.ring &&
        msg.target.angle >= 0
      ) {
        angle.value = null;
        setTimeout(() => {
          if (props.scores[0]) {
            circleColor.value =
              msg.userId === props.scores[0].playerId ? "#ff4444" : "blue";
          }
          angle.value = msg.target.angle;
        }, 200);
      }
    }
  });
}

onMounted(() => {
  uni.$on("socket-inbox", onReceiveMessage);
});

onBeforeUnmount(() => {
  if (timer.value) {
    clearTimeout(timer.value);
    timer.value = null;
  }
  if (dirTimer.value) {
    clearTimeout(dirTimer.value);
    dirTimer.value = null;
  }
  uni.$off("socket-inbox", onReceiveMessage);
});
</script>

<template>
  <view class="container">
    <view class="header" v-if="totalRound > 0">
      <text v-if="totalRound > 0" class="round-count">{{
        (currentRound > totalRound ? totalRound : currentRound) +
        "/" +
        totalRound
      }}</text>
    </view>
    <view class="target">
      <view v-if="angle !== null" class="arrow-dir" :style="arrowStyle">
        <view :style="{ background: circleColor }">
          <image src="../static/dot-circle.png" mode="widthFix" />
        </view>
      </view>
      <view v-if="stop" class="stop-sign">中场休息</view>
      <view
        v-if="latestOne && latestOne.ring && user.id === latestOne.playerId"
        class="e-value fade-in-out"
        :style="{
          left: calcRealX(latestOne.ring ? latestOne.x : 0, 20),
          top: calcRealY(latestOne.ring ? latestOne.y : 0, 40),
        }"
      >
        经验 +1
      </view>
      <view
        v-if="latestOne"
        class="round-tip fade-in-out"
        :style="{
          left: calcRealX(latestOne.ring ? latestOne.x : 0, 28),
          top: calcRealY(latestOne.ring ? latestOne.y : 0, 28),
        }"
        >{{ latestOne.ring || "未上靶" }}<text v-if="latestOne.ring">环</text>
      </view>
      <view
        v-if="
          bluelatestOne &&
          bluelatestOne.ring &&
          user.id === bluelatestOne.playerId
        "
        class="e-value fade-in-out"
        :style="{
          left: calcRealX(bluelatestOne.ring ? bluelatestOne.x : 0, 20),
          top: calcRealY(bluelatestOne.ring ? bluelatestOne.y : 0, 40),
        }"
      >
        经验 +1
      </view>
      <view
        v-if="bluelatestOne"
        class="round-tip fade-in-out"
        :style="{
          left: calcRealX(bluelatestOne.ring ? bluelatestOne.x : 0, 28),
          top: calcRealY(bluelatestOne.ring ? bluelatestOne.y : 0, 28),
        }"
        >{{ bluelatestOne.ring || "未上靶"
        }}<text v-if="bluelatestOne.ring">环</text></view
      >
      <block v-for="(bow, index) in scores" :key="index">
        <view
          v-if="bow.ring > 0"
          :class="`hit ${
            index === scores.length - 1 && latestOne ? 'pump-in' : ''
          }`"
          :style="{
            left: calcRealX(bow.x),
            top: calcRealY(bow.y),
            backgroundColor:
              index === scores.length - 1 &&
              !blueScores.length &&
              latestOne &&
              mode !== 'team'
                ? 'green'
                : '#ff4444',
          }"
          ><text>{{ index + 1 }}</text></view
        >
      </block>
      <block v-for="(bow, index) in blueScores" :key="index">
        <view
          v-if="bow.ring > 0"
          :class="`hit ${
            index === blueScores.length - 1 && bluelatestOne ? 'pump-in' : ''
          }`"
          :style="{
            left: calcRealX(bow.x),
            top: calcRealY(bow.y),
            backgroundColor: 'blue',
          }"
        >
          <text>{{ index + 1 }}</text>
        </view>
      </block>
      <image src="../static/bow-target.png" mode="widthFix" />
    </view>
    <view v-if="avatar" class="footer">
      <image :src="avatar" mode="widthFix" />
    </view>
    <view class="simul" v-if="env !== 'release'">
      <button @click="simulShoot">模拟</button>
      <button @click="simulShoot2">射箭</button>
    </view>
    <!-- <text :style="{ color: '#fff', wordBreak: 'break-all' }">{{
      scores.length ? scores[scores.length - 1] : ""
    }}</text> -->
    <!-- <StartCountdown :start="startCount" /> -->
  </view>
</template>

<style scoped>
.container {
  width: calc(100vw - 30px);
  height: calc(100vw - 30px);
  padding: 0px 15px;
  position: relative;
}
.target {
  position: relative;
  margin: 10px;
  width: calc(100% - 20px);
  height: calc(100% - 20px);
}
.e-value {
  position: absolute;
  /* top: 30%;
  left: 60%; */
  background-color: #0006;
  color: #fff;
  font-size: 12px;
  padding: 4px 7px;
  border-radius: 5px;
  z-index: 2;
  width: 50px;
  text-align: center;
}
.round-tip {
  position: absolute;
  /* top: 38%; */
  /* left: 60%; */
  color: #fff;
  font-size: 30px;
  font-weight: bold;
  z-index: 2;
  width: 100px;
  text-align: center;
}
.round-tip > text {
  font-size: 24px;
  margin-left: 5px;
}
.target > image:last-child {
  width: 100%;
  height: 100%;
}
.hit {
  position: absolute;
  width: 22rpx;
  height: 22rpx;
  min-width: 22rpx;
  min-height: 22rpx;
  border-radius: 50%;
  border: 1px solid #fff;
  z-index: 1;
  color: #fff;
  font-size: 2.1vw;
  box-sizing: border-box;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
  display: flex;
  justify-content: center;
  align-items: center;
  /* transform: translate(-50%, -50%); */
}
.hit > text {
  transform: scaleX(0.7);
  display: block;
  font-weight: bold;
  width: 100%;
  text-align: center;
  line-height: 22rpx;
}
.header {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: -40px;
}
.header > image:first-child {
  width: 40px;
  height: 40px;
}
.round-count {
  font-size: 20px;
  color: #fed847;
  top: 75px;
  font-weight: bold;
}
.footer {
  width: calc(100% - 20px);
  padding: 0 10px;
  display: flex;
  margin-top: -40px;
}
.footer > image {
  width: 40px;
  min-height: 40px;
  max-height: 40px;
  border-radius: 50%;
  border: 1px solid #fff;
}
.simul {
  position: absolute;
  bottom: 40px;
  right: 20px;
  margin-left: 20px;
}
.simul > button {
  color: #fff;
}
.stop-sign {
  position: absolute;
  font-size: 44px;
  color: #fff9;
  text-align: center;
  width: 200px;
  height: 60px;
  left: calc(50% - 100px);
  top: calc(50% - 30px);
  z-index: 99;
  font-weight: bold;
}
.arrow-dir {
  position: absolute;
  width: 100%;
  height: 52%;
  left: 50%;
  bottom: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.arrow-dir > view {
  width: 40rpx;
  height: 40rpx;
  border-radius: 50%;
}
.arrow-dir > view > image {
  width: 100rpx;
  height: 100rpx;
  transform: translate(-30%, -30%);
}
@keyframes spring-in {
  0% {
    transform: scale(2);
    opacity: 0.4;
  }
  15% {
    transform: scale(3);
    opacity: 1;
  }
  30% {
    transform: scale(2);
    opacity: 0.4;
  }
  45% {
    transform: scale(3);
    opacity: 1;
  }
  60% {
    transform: scale(2);
    opacity: 0.4;
  }
  75% {
    transform: scale(3);
    opacity: 1;
  }
  100% {
    transform: scale(1);
    opacity: 0;
  }
}
@keyframes disappear {
  0% {
    opacity: 1;
  }
  75% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
.arrow-dir > view {
  animation: disappear 3s ease forwards;
}
.arrow-dir > view > image {
  animation: spring-in 3s ease forwards;
  width: 100%;
}
</style>
