<script setup>
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
import { onShow } from "@dcloudio/uni-app";

import { getBattleAPI, getUserGameState } from "@/apis";
import { debounce } from "@/util";
import { returnToBattle } from "@/utils/matchReturn";

import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user, game } = storeToRefs(store);
const { updateGame } = store;

const props = defineProps({
  signin: {
    type: Function,
    default: () => {},
  },
});
const loading = ref(false);
const navigating = ref(false);

/** 统一获取当前环境 token，用于守卫：无有效 token 时不发起接口请求 */
const getToken = () =>
  uni.getStorageSync(`${uni.getAccountInfoSync().miniProgram.envVersion}_token`);

onShow(async () => {
  navigating.value = false;
  if (user.value.id && getToken()) {
    setTimeout(async () => {
      const state = await getUserGameState();
      updateGame(state.gaming, state.roomId);
    }, 1000);
  }
});

watch(
  () => user.value,
  async (value) => {
    if (!value.id) {
      updateGame(false, "");
    } else if (getToken()) {
      // 有有效 token 时才查询在局状态，避免 token 失效时反复发起无效请求
      const state = await getUserGameState();
      updateGame(state.gaming, state.roomId);
    }
  }
);

const navigateOnce = (url) =>
  new Promise((resolve, reject) => {
    navigating.value = true;
    uni.navigateTo({
      url,
      success: resolve,
      fail: (error) => {
        navigating.value = false;
        reject(error);
      },
    });
  });

const onClick = debounce(async () => {
  if (loading.value || navigating.value) return;
  try {
    loading.value = true;
    const result = await getBattleAPI();
    if (result && result.matchId) {
      await returnToBattle(result, navigateOnce);
      return;
    }
    if (game.value.roomID) {
      await navigateOnce("/pages/battle-room?roomNumber=" + game.value.roomID);
    } else {
      updateGame(false, "");
    }
  } finally {
    loading.value = false;
  }
});
const gameOver = () => {
  updateGame(false, "");
};
onMounted(() => {
  uni.$on("game-over", gameOver);
});
onBeforeUnmount(() => {
  uni.$off("game-over", gameOver);
});
</script>

<template>
  <view
    v-if="game.inBattle || game.roomID"
    class="back-to-game"
    @click="onClick"
  >
    <image src="https://static.shelingxingqiu.com/shootmini/static/back-to-game-bg.png" mode="widthFix" />
    <block v-if="game.inBattle">
      <image src="https://static.shelingxingqiu.com/shootmini/static/pk-icon.png" mode="widthFix" />
      <text>返回进行中的对局</text>
    </block>
    <block v-else-if="game.roomID">
      <text>返回房间</text>
    </block>
    <image src="../../../static/back.png" mode="widthFix" />
  </view>
</template>

<style scoped>
.back-to-game {
  position: fixed;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  width: 56vw;
  left: calc(50% - 28vw);
  top: 12%;
  z-index: 999;
}
.back-to-game > image:first-child {
  position: absolute;
  width: 100%;
  height: 100rpx;
}
.back-to-game > image:nth-child(2) {
  position: relative;
  width: 60px;
  height: 60px;
}
.back-to-game > text {
  position: relative;
  font-size: 14px;
}
.back-to-game > image:last-child {
  position: relative;
  width: 15px;
  margin-left: 5px;
  transform: rotate(180deg);
}
</style>
