<template>
  <div>
    <Transition :enter-active-class="proxy?.animate.mask.enter">
      <div class="mask" v-if="actionState"></div>
    </Transition>
    <Transition :enter-active-class="proxy?.animate.rankingWindow.enter"
      :leave-active-class="proxy?.animate.rankingWindow.leave">
      <div class="confirmDiaBg" v-if="actionState">
        <div class="confirmDiaWindow">
          <div class="prompt"><i></i> {{ actionText }}</div>
          <div class="confirmDiaWindow-con">
            <div class="picBox">
              <div class="pic">
                <div class="gamePic">
                  <template v-if="currentGame == 'game_fruit'">
                    <img src="@/assets/images/game/img2.png" width="200" />
                  </template>
                  <template v-if="currentGame == 'game_basketball'">
                    <img src="@/assets/images/game/img1.png" width="200" />
                  </template>
                  <template v-if="currentGame == 'game_football'">
                    <img src="@/assets/images/game/img3.png" width="200" />
                  </template>
                  <div class="time" v-if="timerNum>0"><div>{{timerNum}}</div></div>
                </div>
                <div class="gamePlayer">
                  <div class="item" v-for="item in areaStateList" :key="item.area">
                    <div class="player">
                      <template v-if="currentGame == 'bodyposecontroller'">
                        <div><img src="@/assets/images/game/fruit1.png" class="fade-image"
                            :class="{ 'fade-image1': !item.state }"></img></div>
                        <div><img v-if="!item.state" src="@/assets/images/game/fruit2.png" class="fade-image"
                            :class="{ 'fade-image2': !item.state }"></img></div>
                      </template>
                      <template v-if="currentGame == 'game_fruit'">
                        <div><img src="@/assets/images/game/fruit1.png" class="fade-image"
                            :class="{ 'fade-image1': !item.state }"></img></div>
                        <div><img v-if="!item.state" src="@/assets/images/game/fruit2.png" class="fade-image"
                            :class="{ 'fade-image2': !item.state }"></img></div>
                      </template>
                      <template v-if="currentGame == 'game_basketball'">
                        <div><img src="@/assets/images/game/basketball1.png" class="fade-image"
                            :class="{ 'fade-image1': !item.state }"></img></div>
                        <div><img v-if="!item.state" src="@/assets/images/game/basketball2.png" class="fade-image"
                            :class="{ 'fade-image2': !item.state }"></img></div>
                      </template>
                      <template v-if="currentGame == 'game_football'">
                        <div><img src="@/assets/images/game/football1.png" class="fade-image"
                            :class="{ 'fade-image1': !item.state }"></img></div>
                        <div><img v-if="!item.state" src="@/assets/images/game/football2.png" class="fade-image"
                            :class="{ 'fade-image2': !item.state }"></img></div>
                      </template>
                      <div v-if="item.state" class="ok"><img src="@/assets/images/game/ok.png"></div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="name">
              <template v-if="currentGame == 'game_fruit'">玩法：挥动双手切开水果，失败三次结束游戏</template>
              <template v-if="currentGame == 'game_basketball'">玩法：身体左右移动对准篮筐，双手投篮</template>
              <template v-if="currentGame == 'game_football'">玩法：身体左右移动躲避雪糕筒，踢腿射门</template>
            </div>
          </div>
        </div>
        <div @click="getExit" class="close"></div>
      </div>
    </Transition>
  </div>

</template>
<script setup lang="ts">
import { initSpeech, speckText, playMusic, controlMusic, speckCancel, chineseNumber } from '@/utils/speech';
const { proxy } = getCurrentInstance() as any;
const emit = defineEmits(['confirmExit', 'confirmStart']);

const data = reactive<any>({
  currentGame: "",
  currentGameArea: [],
  actionState: false,//窗口状态
  areaStateList: [],
  lock: false,
  actionText: "",
  timer: null,
  timerNum: null,
});

const { currentGame, currentGameArea, actionState, areaStateList, lock, actionText, timer, timerNum } = toRefs(data);



onBeforeMount(() => {
  //初始化语音
  initSpeech();
})

onMounted(() => {
})

/**
 * 初始化
 */
const getInit = (e: any) => {
  let area = e.ctrl_name.replace('bodyposecontroller_', '');
  let arr = e.data.result.boxes;
  let myArr = e.data.result.keypoints;
  let result = [];
  for (let i = 0; i < myArr.length; i += 3) {
    result.push(myArr.slice(i, i + 2));
  }
  //console.log("result", result)
  if (currentGame.value == 'bodyposecontroller') {
    let leftA = result[6][1];//右肩Y
    let rightA = result[5][1];//左肩Y
    let leftB = result[10][1];//右手Y
    let rightB = result[9][1];//左手Y
    let bizi = result[0][1];//鼻子Y
    if (leftB < leftA || rightB < rightA || leftB < bizi || rightB < bizi) {
      let myIndex = areaStateList.value.findIndex((item: any) => {
        return item.area == area;
      })
      let boxes = [{ x: arr[0], y: arr[3] }, { x: arr[0], y: arr[1] }, { x: arr[2], y: arr[1] }, { x: arr[2], y: arr[3] }];
      areaStateList.value[myIndex].state = true;
      areaStateList.value[myIndex].boxes = boxes;
    }
  }
  if (currentGame.value == 'game_basketball') {
    let leftA = result[6][1];//右肩Y
    let rightA = result[5][1];//左肩Y
    let leftB = result[10][1];//右手Y
    let rightB = result[9][1];//左手Y
    let bizi = result[0][1];//鼻子Y
    if (leftB < leftA || rightB < rightA || leftB < bizi || rightB < bizi) {
      let myIndex = areaStateList.value.findIndex((item: any) => {
        return item.area == area;
      })
      let boxes = [{ x: arr[0], y: arr[3] }, { x: arr[0], y: arr[1] }, { x: arr[2], y: arr[1] }, { x: arr[2], y: arr[3] }];
      areaStateList.value[myIndex].state = true;
      areaStateList.value[myIndex].boxes = boxes;
    }
  }
  if (currentGame.value == 'game_football') {
    let leftA = { x: result[12][0], y: result[12][1] };//大腿
    let leftB = { x: result[14][0], y: result[14][1] };//膝盖
    let leftC = { x: result[16][0], y: result[16][1] };//脚

    let rightA = { x: result[11][0], y: result[11][1] };//大腿
    let rightB = { x: result[13][0], y: result[13][1] };//膝盖
    let rightC = { x: result[15][0], y: result[15][1] };//脚

    let jiaodu1 = calculateAngleAtB(leftA, leftB, leftC)
    let jiaodu2 = calculateAngleAtB(rightA, rightB, rightC)
    // console.log("jiaodu1",jiaodu1)
    // console.log("jiaodu2",jiaodu2)
    if (jiaodu1 <= 80 && jiaodu2 >= 120 || jiaodu2 <= 80 && jiaodu2 >= 120) {
      let myIndex = areaStateList.value.findIndex((item: any) => {
        return item.area == area;
      })
      let boxes = [{ x: arr[0], y: arr[3] }, { x: arr[0], y: arr[1] }, { x: arr[2], y: arr[1] }, { x: arr[2], y: arr[3] }];
      areaStateList.value[myIndex].state = true;
      areaStateList.value[myIndex].boxes = boxes;
    }
  }
  if (currentGame.value == 'game_fruit') {
    let leftA = result[6][1];//右肩Y
    let rightA = result[5][1];//左肩Y
    let leftB = result[10][1];//右手Y
    let rightB = result[9][1];//左手Y
    let bizi = result[0][1];//鼻子Y
    if (leftB < leftA || rightB < rightA || leftB < bizi || rightB < bizi) {
      let myIndex = areaStateList.value.findIndex((item: any) => {
        return item.area == area;
      })
      let boxes = [{ x: arr[0], y: arr[3] }, { x: arr[0], y: arr[1] }, { x: arr[2], y: arr[1] }, { x: arr[2], y: arr[3] }];
      areaStateList.value[myIndex].state = true;
      areaStateList.value[myIndex].boxes = boxes;
    }
  }
};

/**
 * 计算B点的夹角度数（∠ABC）
 * @param {Object} pointA - A点坐标 {x, y, z可选}
 * @param {Object} pointB - B点坐标 {x, y, z可选}
 * @param {Object} pointC - C点坐标 {x, y, z可选}
 * @returns {number} B点的夹角度数（保留两位小数）
 */
const calculateAngleAtB = (pointA, pointB, pointC) => {
  // 计算向量BA和向量BC
  const vectorBA = {
    x: pointA.x - pointB.x,
    y: pointA.y - pointB.y,
    z: (pointA.z || 0) - (pointB.z || 0)
  };

  const vectorBC = {
    x: pointC.x - pointB.x,
    y: pointC.y - pointB.y,
    z: (pointC.z || 0) - (pointB.z || 0)
  };

  // 计算点积
  const dotProduct =
    vectorBA.x * vectorBC.x +
    vectorBA.y * vectorBC.y +
    vectorBA.z * vectorBC.z;

  // 计算向量BA的模长
  const lengthBA = Math.sqrt(
    vectorBA.x ** 2 +
    vectorBA.y ** 2 +
    vectorBA.z ** 2
  );

  // 计算向量BC的模长
  const lengthBC = Math.sqrt(
    vectorBC.x ** 2 +
    vectorBC.y ** 2 +
    vectorBC.z ** 2
  );

  // 防止除以零的情况
  if (lengthBA === 0 || lengthBC === 0) {
    throw new Error("点A、B、C不能重合");
  }

  // 计算余弦值
  const cosine = dotProduct / (lengthBA * lengthBC);

  // 由于计算误差可能导致cosine略超出[-1, 1]范围，需要修正
  const clampedCosine = Math.max(Math.min(cosine, 1), -1);

  // 计算弧度并转换为角度
  const angleRadians = Math.acos(clampedCosine);
  const angleDegrees = angleRadians * (180 / Math.PI);

  // 保留两位小数并返回
  return parseFloat(angleDegrees.toFixed(2));
}

/**
 * 打开
 */
const getOpen = async (game: any, area: any) => {
  lock.value = false;
  currentGame.value = game;
  currentGameArea.value = area;
  let list = area.map((item: any) => {
    let obj = {
      area: item,
      state: false
    }
    return obj;
  }) || [];
  areaStateList.value = list;
  actionState.value = true;
  let txt = ""
  if (currentGame.value == 'bodyposecontroller') {
    txt = "举手开始游戏";
  }
  if (currentGame.value == 'game_fruit') {
    txt = "举手开始游戏";
  }
  if (currentGame.value == 'game_basketball') {
    txt = "请做投篮动作开始游戏";
  }
  if (currentGame.value == 'game_football') {
    txt = "请踢腿开始游戏";
  }
  actionText.value = txt;
  speckText(actionText.value);
};

/**
 * 关闭
*/
const getExit = () => {
  clearInterval(timer.value);
  timer.value = null;
  speckCancel(); //停止播报
  actionState.value = false;
  emit('confirmExit', {});
};

/**
 * 监听全部OK
 */
watch(
  () => areaStateList.value,
  (newData, oldData) => {
    //都准备就绪就开始
    if (lock.value) {
      return false;
    }
    let state = newData.every((item: any) => {
      return item.state;
    })
    if (state) {
      lock.value = true;
      timerNum.value = 3;
      timer.value = setInterval(() => {
        if (timerNum.value == 1) {
          actionState.value = false;
          clearInterval(timer.value);
          timer.value = null;
          emit('confirmStart', areaStateList.value);
        }
        speckText(timerNum.value);
        timerNum.value--;
      }, 1000)
    }
  },
  { deep: true }
);

//暴露给父组件用
defineExpose({
  getOpen,
  getInit
})
</script>
<style lang="scss" scoped>
.mask {
  position: fixed;
  height: 100vh;
  width: 100vw;
  top: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.6);
  z-index: 998;
}

.confirmDiaBg {
  width: 70rem;
  position: fixed;
  left: 50%;
  top: 50%;
  margin-left: calc(70rem / -2);
  margin-top: calc(((70rem / 2) + 12rem) / -2);
  display: flex;
  flex-direction: column;
  z-index: 999;

  .confirmDiaWindow {
    border-radius: 1.6rem;
    opacity: 1;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    margin-bottom: 20px;
    background: linear-gradient(59deg, #092941 -85%, #2A484B 96%);
    box-shadow: inset 0px 1px 0px 2px rgba(255, 255, 255, 0.5577);

    .prompt {
      color: #ffffff;
      font-size: 2.5vh;
      display: flex;
      line-height: 3vh;
      padding-top: 2vh;

      i {
        width: 3vh;
        height: 3vh;
        margin-right: 3px;
        display: block;
        background-image: url('@/assets/images/game/prompt.png');
        background-position: bottom;
        background-repeat: no-repeat;
        background-size: 100%;
      }
    }

    .confirmDiaWindow-con {
      width: 85%;
      padding: 25px;
      display: flex;
      justify-content: center;
      flex-direction: column;

      .picBox {

        width: 100%;
        background-image: url('@/assets/images/game/bg.png');
        background-position: bottom;
        background-repeat: no-repeat;
        background-size: 100%;
        display: flex;
        justify-content: center;
        padding-bottom: 10vh;

        .pic {
          display: flex;
          justify-content: center;
          flex-direction: column;

          .gamePic {
            border: 5px solid #3BDDCE;
            width: 60vh;
            height: calc(60vh * (1080 / 1920));
            position: relative;
            display: flex;
            .time{
              position: absolute;
              left: 0;
              top: 0;
              width: 100%;
              height: 100%;
              background: rgba(0, 0, 0, 0.5);
              color: #ffffff;
              font-size: 7rem;
              display: flex;
              align-items: center;
              justify-content: center;
            }
            img {
              width: 100%;
              height: 100%;
            }
          }

          .gamePlayer {
            display: flex;
            width: 60vh;
            margin-top: -20vh;

            .item {
              flex: 1;
              display: flex;
              justify-content: center;

              .player {
                position: relative;
                width: 22vh;
                height: calc(22vh * (1000 / 518));
              }

              .fade-image {
                width: 100%;
                height: 100%;
                position: absolute;
                left: 0;
                top: 0;
              }

              .fade-image1 {
                animation: fadeOpacity1 2s infinite;
              }

              .fade-image2 {
                animation: fadeOpacity2 2s infinite;
              }

              .ok {
                width: 8vh;
                height: 8vh;
                position: absolute;
                top: 50%;
                left: 50%;
                margin-top: 1vh;
                margin-left: -4vh;

                img {
                  width: 100%;
                }
              }

              @keyframes fadeOpacity1 {
                0% {
                  opacity: 1;
                }

                100% {
                  opacity: 0;
                }
              }

              @keyframes fadeOpacity2 {
                0% {
                  opacity: 0;
                }

                100% {
                  opacity: 1;
                }
              }
            }
          }
        }
      }

      .name {
        width: 100%;
        color: #ffffff;
        font-size: 2.8vh;
        padding-top: 20px;
      }
    }
  }

  .close {
    margin: 0 auto;
  }
}
</style>
