<script setup>
import { computed, ref, onMounted, onBeforeUnmount } from "vue";
import Guide from "@/components/Guide.vue";
import SButton from "@/components/SButton.vue";
import Swiper from "@/components/Swiper.vue";
import BowTarget from "@/components/BowTarget.vue";
import ShootProgress from "@/components/ShootProgress.vue";
import ScoreResult from "@/components/ScoreResult.vue";
import ScorePanel from "@/components/ScorePanel.vue";
import Container from "@/components/Container.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,
  getPractiseAPI,
  startPractiseAPI,
  laserAimAPI,
  laserCloseAPI,
} from "@/apis";
import { connectMatchWebSocket, closeMatchWebSocket } from "@/matchWebsocket";
import { sharePractiseData } from "@/canvas";
import { wxShare, debounce } from "@/util";
import { MESSAGETYPESV2 } from "@/constants";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user, device } = storeToRefs(store);
const scores = ref([]);
const isSvip = ref(false);
const step = ref(0);
const total = 12;
const stepButtonTexts = [
  "开始",
  "进入下一个任务",
  "我已校准",
  "进入下一个任务",
  "我准备好了，开始",
  "",
  "退出新手试炼",
];
const title = ref("新手试炼场");
const start = ref(false);
const practiseResult = ref({});
const btnDisabled = ref(false);
const practiseId = ref("");
const showGuide = ref(false);
const laserActive = ref(false);
const guideSwiperIndex = ref(0);
const sharing = ref(false);
const RESULT_TIP_CDN = "https://static.shelingxingqiu.com/shootmini/static";

const guideImages = [
  "https://static.shelingxingqiu.com/shootmini/static/target.png",
  "https://static.shelingxingqiu.com/attachment/2026-02-08/dg9ev0wwdpgwt9e6du.png",
  "https://static.shelingxingqiu.com/attachment/2026-02-08/dg9ev0wvv9sw4zioqk.png",
  "https://static.shelingxingqiu.com/attachment/2026-02-08/dg9ev0ww3khaycallu.png",
  "https://static.shelingxingqiu.com/attachment/2026-02-08/dg9ev0wtkcvaxxv0s8.png",
  "https://static.shelingxingqiu.com/attachment/2026-02-08/dg9ev0wry5tw7ltmxr.png",
  "https://static.shelingxingqiu.com/attachment/2026-02-08/dg9ev0wu3kcdrwzwpd.png",
  "https://static.shelingxingqiu.com/attachment/2026-02-08/dg9ev0wwr6hfjhyfn5.png",
];

const calibrationGuides = [
  {
    title: "箭头面向靶子",
    src: "https://static.shelingxingqiu.com/attachment/2025-10-30/ddv9p5fk5wscg7hrfo.png",
  },
  {
    title: "摆出拉弓姿势",
    src: "https://static.shelingxingqiu.com/attachment/2025-10-30/ddv9p5fk5b7ljrhx3o.png",
  },
  {
    title: "调整瞄准器",
    src: "https://static.shelingxingqiu.com/attachment/2025-10-29/dduexjgrcxf9wjaiv4.png",
  },
];

const onSwiperIndexChange = (index) => {
  guideSwiperIndex.value = index;
  showGuide.value = index + 1 === guideImages.length;
};

const isGuideLastImage = computed(
  () => guideSwiperIndex.value + 1 === guideImages.length
);

const currentStepButtonText = computed(() => {
  if (step.value === 1 && isGuideLastImage.value) return "去校准智能弓";
  return stepButtonTexts[step.value];
});

const openCalibrationLaser = async () => {
  if (laserActive.value) return;
  await laserAimAPI();
  laserActive.value = true;
};

const closeCalibrationLaser = async () => {
  if (!laserActive.value) return;
  await laserCloseAPI();
  laserActive.value = false;
};

const createPractise = async (arrows) => {
  closeMatchWebSocket({ reason: "practice-recreate" });
  const result = await createPractiseAPI(
    arrows,
    120,
    1,
    device.value.deviceId
  );
  if (result) practiseId.value = result.id;
  if (!result?.serverAddr) {
    uni.showToast({
      title: "练习连接信息异常，请重试",
      icon: "none",
    });
    return null;
  }
  connectMatchWebSocket({
    serverAddr: result.serverAddr,
    matchId: result.id,
    userId: user.value.id,
  });
  return result;
};

const onOver = async (message) => {
  practiseResult.value = Array.isArray(message?.details)
    ? message
    : await getPractiseAPI(practiseId.value);
  start.value = false;
};

const beginPractise = async () => {
  if (!practiseId.value) {
    uni.showToast({
      title: "练习未创建，请重试",
      icon: "none",
    });
    return false;
  }
  await startPractiseAPI(practiseId.value);
  return true;
};

async function onReceiveMessage(msg) {
  if (msg.type === MESSAGETYPESV2.ShootResult) {
    isSvip.value = msg.sVip === true;
    scores.value = Array.isArray(msg.details) ? msg.details : scores.value;
  } else if (msg.type === MESSAGETYPESV2.BattleEnd) {
    setTimeout(() => onOver(msg), 1500);
  } else if (msg.type === MESSAGETYPESV2.TestDistance && step.value === 3) {
    if (msg.shootData.distance / 100 >= 5) {
      audioManager.play("距离合格");
      btnDisabled.value = false;
      showGuide.value = true;
    } else audioManager.play("距离不足");
  }
  // messages.forEach((msg) => {
  //   if (msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) {
  //     if (step.value === 2 && msg.target.dst / 100 >= 5) {
  //       btnDisabled.value = false;
  //       showGuide.value = true;
  //     } else if (scores.value.length < total) {
  //       scores.value.push(msg.target);
  //     }
  //     if (scores.value.length === total) {
  //       setTimeout(onOver, 1500);
  //     }
  //   }
  // });
}

const onClickShare = debounce(async () => {
  if (sharing.value) return;
  sharing.value = true;
  try {
    await sharePractiseData("shareCanvas", 1, user.value, practiseResult.value);
    await wxShare("shareCanvas");
  } catch (e) {
    uni.showToast({
      title: "海报生成失败，请稍后重试",
      icon: "none",
    });
  } finally {
    sharing.value = false;
  }
});

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

onBeforeUnmount(async () => {
  uni.setKeepScreenOn({
    keepScreenOn: false,
  });
  uni.$off("socket-inbox", onReceiveMessage);
  uni.$off("share-image", onClickShare);
  await closeCalibrationLaser();
  audioManager.stopAll();
  closeMatchWebSocket({ reason: "practice-leave" });
});

const nextStep = async () => {
  if (step.value === 0) {
    step.value = 1;
    title.value = "-箭前准备";
  } else if (step.value === 1) {
    if (!isGuideLastImage.value) {
      guideSwiperIndex.value += 1;
      showGuide.value = guideSwiperIndex.value + 1 === guideImages.length;
      return;
    }
    showGuide.value = false;
    step.value = 2;
    // title.value = "-校准智能弓";
    await openCalibrationLaser();
  } else if (step.value === 2) {
    await closeCalibrationLaser();
    showGuide.value = false;
    btnDisabled.value = true;
    step.value = 3;
    title.value = "-感知距离";
    const result = await createPractise(total);
    if (!result) {
      btnDisabled.value = false;
      step.value = 2;
      return;
    }
  } else if (step.value === 3) {
    showGuide.value = false;
    step.value = 4;
    title.value = "-小试牛刀";
  } else if (step.value === 4) {
    title.value = "小试牛刀";
    const result = await beginPractise();
    if (!result) return;
    scores.value = [];
    isSvip.value = false;
    step.value = 5;
    start.value = true;
    setTimeout(() => {
      uni.$emit("play-sound", "请开始射击");
    }, 300);
  } else if (step.value === 6) {
    uni.navigateBack({
      delta: 1,
    });
  }
};

const onClose = async () => {
  const validArrows = (practiseResult.value.details || []).filter(
    (a) => a.x !== -30 && a.y !== -30
  );
  if (validArrows.length === total) {
    setTimeout(() => {
      practiseResult.value = {};
      showGuide.value = false;
      step.value = 6;
    }, 500);
  } else {
    practiseResult.value = {};
    start.value = false;
    scores.value = [];
    isSvip.value = false;
    step.value = 4;
    await createPractise(total);
  }
};

const getResultTipSrc = (result = {}) => {
  const validCount = (result.details || []).filter(
    (arrow) => arrow.x !== -30 && arrow.y !== -30
  ).length;
  return `${RESULT_TIP_CDN}/${validCount < total ? "un" : ""}finish-tip.png`;
};
</script>

<template>
  <Container :bgType="1" :title="title" :showBottom="step !== 5">
    <view class="container">
      <Guide
        v-if="step !== 5"
        :type="
          step === 3
            ? 2
            : step === 6 || (step === 0 && user.nickName.length > 6)
            ? 1
            : 0
        "
      >
        <text
          v-if="step === 0"
          :style="{
            fontSize: '28rpx',
            marginTop: user.nickName.length > 6 ? '-10rpx' : '0',
          }"
        >
          hi，<text :style="{ color: '#fed847' }">{{ user.nickName }}</text>
          ，这是新人必刷小任务，0基础小白也能快速掌握弓箭技巧和游戏规则哦~：）
        </text>
        <text v-if="step === 1" :style="{ fontSize: '28rpx' }"
          >这位就是人帅技高的高教练！接下来请跟随教练指引，做好射箭前期准备。</text
        >
        <text v-if="step === 2" :style="{ fontSize: '28rpx' }"
          >请按下方步骤完成智能弓校准，让瞄准器和靶子保持对齐。</text
        >
        <view
          class="guide-tips"
          :style="{ marginTop: '8rpx' }"
          v-if="step === 3"
        >
          <text>你知道5米射程有多远吗？</text>
          <text>
            在我们的排位赛中，射程小于5米的成绩无效、哦！建议平时练习距离至少5米。现在，来边射箭边调整你的站位点吧！
          </text>
        </view>
        <view class="guide-tips" v-if="step === 4">
          <text>一切准备就绪</text>
          <text :style="{ fontSize: '28rpx' }"
            >试着完成一个真正的弓箭手任务吧！</text
          >
        </view>
        <view class="guide-tips" v-if="step === 6">
          <text>新手试炼场通关啦，优秀！</text>
          <text :style="{ fontSize: '28rpx' }"
            >反曲弓运动基本知识和射灵世界系统规则你已Get，是不是挺容易呀：）</text
          >
        </view>
      </Guide>
      <image
        src="https://static.shelingxingqiu.com/attachment/2025-07-01/db0ehhek5yutxsetyi.png"
        class="try-tip"
        mode="widthFix"
        v-if="step === 0"
      />
      <image
        src="https://static.shelingxingqiu.com/attachment/2025-11-17/deas80ef1sf9td0leq.png"
        class="try-tip"
        mode="widthFix"
        v-if="step === 4"
      />
      <image
        src="https://static.shelingxingqiu.com/attachment/2025-07-01/db0ehpz9lav58g5drl.png"
        class="try-tip"
        mode="widthFix"
        v-if="step === 6"
      />
      <view style="height: 570px" v-if="step === 1">
        <Swiper
          :current="guideSwiperIndex"
          :onChange="onSwiperIndexChange"
          :data="guideImages"
        />
      </view>
      <view class="calibration-container" v-if="step === 2">
        <view
          v-for="(guide, index) in calibrationGuides"
          :key="guide.title"
          class="calibration-guide"
        >
          <view>
            <text>{{ index + 1 }}</text>
            <text>{{ guide.title }}</text>
          </view>
          <image :src="guide.src" mode="widthFix" />
        </view>
        <text>请完成以上步骤校准智能弓</text>
      </view>
      <ShootProgress v-if="step === 5" tips="请开始连续射箭" :start="start" />
      <TestDistance v-if="step === 3" :guide="false" />
      <view
        class="user-row"
        v-if="step === 5"
        :style="{ marginBottom: '0' }"
      >
        <Avatar :src="user.avatar" :size="35" />
        <BowPower />
      </view>
      <BowTarget
        v-if="step === 5"
        :currentRound="step === 5 ? scores.length : 0"
        :totalRound="step === 5 ? total : 0"
        :scores="scores"
        :isSvip="isSvip"
      />
      <ScorePanel
        v-if="step === 5"
        :total="total"
        :rowCount="6"
        :arrows="scores"
      />
      <ScoreResult
        v-if="practiseResult.details"
        :rowCount="6"
        :total="total"
        :onClose="onClose"
        :result="practiseResult"
        :tipSrc="getResultTipSrc(practiseResult)"
      />
      <canvas class="share-canvas" id="shareCanvas" type="2d"></canvas>
    </view>
    <template #bottom>
      <SButton :onClick="nextStep" :disabled="btnDisabled">
        <BubbleTip v-if="showGuide" :type="step === 1 ? 'long' : 'short'">
          <text :style="{ transform: 'translateY(-18rpx)' }">{{
            step === 1 ? "学会了，我摆得比教练还帅" : "我找到合适的点位了"
          }}</text>
        </BubbleTip>
        {{ currentStepButtonText }}
      </SButton>
    </template>
  </Container>
</template>

<style scoped>
.container {
  width: 100%;
}
.try-tip {
  width: calc(100% - 20px);
  margin: 0 10px;
}
.calibration-container {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.calibration-guide {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 26rpx;
  color: #ffffff;
  margin-bottom: 15rpx;
}
.calibration-guide > view {
  width: 100%;
  margin: 25rpx 0;
  display: flex;
  align-items: center;
}
.calibration-guide > view > text:first-child {
  font-size: 24rpx;
  background: #e89024;
  border-radius: 50%;
  width: 32rpx;
  height: 32rpx;
  line-height: 32rpx;
  display: block;
  text-align: center;
  margin-right: 15rpx;
}
.calibration-guide > image {
  width: 630rpx;
  height: 250rpx;
}
.calibration-container > text {
  font-size: 24rpx;
  color: #fff9;
  margin: 30rpx;
}
</style>
