<script setup>
import { ref, watch, onMounted, onBeforeUnmount, computed } from "vue";
import audioManager from "@/audioManager";
import { MESSAGETYPESV2 } from "@/constants";
import { getDirectionText } from "@/util";
import Avatar from "@/components/Avatar.vue";

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

const props = defineProps({
  show: {
    type: Boolean,
    default: true,
  },
  start: {
    type: Boolean,
    default: false,
  },
  tips: {
    type: String,
    default: "",
  },
  total: {
    type: Number,
    default: 120,
  },
  countdownEnabled: {
    type: Boolean,
    default: true,
  },
  trainingType: {
    type: String,
    default: "precision",
  },
  isVip: {
    type: Boolean,
    default: false,
  },
  isSvip: {
    type: Boolean,
    default: false,
  },
  externalShootResultAudio: {
    type: Boolean,
    default: false,
  },
  currentRound: {
    type: Number,
    default: 0,
  },
  battleId: {
    type: String,
    default: "",
  },
  melee: {
    type: Boolean,
    default: false,
  },
  onStop: {
    type: Function,
    default: () => {},
  },
});

const trainingTitleIconMap = Object.freeze({
  base:
    "https://static.shelingxingqiu.com/shootmini/static/training-difficulty-design/text-icon-jcxl.png",
  precision:
    "https://static.shelingxingqiu.com/shootmini/static/training-difficulty-design/text-icon-jingzxl.png",
  rhythm:
    "https://static.shelingxingqiu.com/shootmini/static/training-difficulty-design/text-icon-jzxl.png",
  endurance:
    "https://static.shelingxingqiu.com/shootmini/static/training-difficulty-design/text-icon-nlxl.png",
});
const trainingTitleIcon = computed(
  () =>
    trainingTitleIconMap[props.trainingType] || trainingTitleIconMap.precision
);

const barColor = ref("#fed847");
const remain = ref(props.countdownEnabled ? props.total : 0);
const timer = ref(null);
const sound = ref(true);
const currentRound = ref(props.currentRound);
const currentRoundEnded = ref(false);
const halfTime = ref(false);
const wait = ref(0);
const transitionStyle = ref("all 1s linear");

const progressPercent = computed(() => {
  if (!props.countdownEnabled || !props.total) return 0;
  return Math.max(0, Math.min(100, (remain.value / props.total) * 100));
});

const displayName = computed(() => {
  return (
    user.value?.nickName ||
    user.value?.nickname ||
    user.value?.name ||
    "Archer"
  );
});

const avatarSrc = computed(() => {
  return user.value?.avatar || "/static/shooter2.png";
});

watch(
  () => props.tips,
  (newVal) => {
    let key = "";
    if (newVal.includes("红队")) key = "请红方射箭";
    if (newVal.includes("蓝队")) key = "请蓝方射箭";
    if (key) {
      if (currentRoundEnded.value) {
        currentRound.value += 1;
        currentRoundEnded.value = false;
        if (currentRound.value === 1) audioManager.play("第一轮");
        if (currentRound.value === 2) audioManager.play("第二轮");
        if (currentRound.value === 3) audioManager.play("第三轮");
        if (currentRound.value === 4) audioManager.play("第四轮");
        if (currentRound.value === 5) audioManager.play("第五轮");
        setTimeout(() => {
          audioManager.play(key);
        }, 1000);
      } else {
        audioManager.play(key);
      }
    }
  }
);

const clearTimer = () => {
  if (!timer.value) return;
  clearInterval(timer.value);
  timer.value = null;
};

const resetTimer = (count) => {
  clearTimer();
  if (!props.countdownEnabled) {
    remain.value = 0;
    return;
  }

  const countValue = Number(count);
  const newVal = Number.isFinite(countValue)
    ? Math.max(0, Math.round(countValue))
    : 0;

  if (newVal >= remain.value) {
    transitionStyle.value = "none";
    remain.value = newVal;
    setTimeout(() => {
      transitionStyle.value = "all 1s linear";
    }, 50);
  } else {
    remain.value = newVal;
  }

  if (remain.value > 0) {
    timer.value = setInterval(() => {
      if (remain.value === 0) {
        clearTimer();
        props.onStop();
      }
      if (remain.value > 0) remain.value--;
    }, 1000);
  }
};

watch(
  () => [props.start, props.countdownEnabled],
  ([started, countdownEnabled]) => {
    if (started && countdownEnabled) {
      resetTimer(props.total);
    } else {
      clearTimer();
      remain.value = 0;
    }
  },
  {
    immediate: true,
  }
);

const tipContent = computed(() => {
  if (halfTime.value) {
    return props.battleId ? "中场休息" : `中场休息(${wait.value}秒)`;
  }
  return props.start && remain.value === 0 ? "时间到！" : props.tips;
});

const updateSound = () => {
  sound.value = !sound.value;
  audioManager.setMuted(!sound.value);
};

async function onReceiveMessage(msg) {
  if (Array.isArray(msg)) return;
  if (msg.type === MESSAGETYPESV2.BattleStart) {
    halfTime.value = false;
    audioManager.play("比赛开始");
  } else if (msg.type === MESSAGETYPESV2.BattleEnd) {
    audioManager.play("练习结束", false);
  } else if (msg.type === MESSAGETYPESV2.ShootResult) {
    // 精准训练由页面统一等待语音和飞箭结束，其他训练保持原播放链路。
    if (props.externalShootResultAudio) return;
    const latestDetail =
      Array.isArray(msg.details) && msg.details.length > 0
        ? msg.details[msg.details.length - 1]
        : null;
    // 语音和 ACK 优先使用同一份当前箭数据，details 仅作为兼容兜底。
    const arrow = msg.shootData || latestDetail;
    if (!arrow) return;
    if (
      arrow.playerId !== undefined &&
      arrow.playerId !== null &&
      String(arrow.playerId) !== String(user.value?.id)
    ) {
      return;
    }

    const key = [];
    key.push(arrow.ring ? `${arrow.ringX ? "X" : arrow.ring}环` : "未上靶");
    if (arrow.angle !== null && arrow.angle !== undefined) {
      key.push(`向${getDirectionText(arrow.angle)}调整`);
    }
    if (arrow.threeConsecutive10Rings === true) {
      key.push("tententen");
    }
    audioManager.play(key, false);
  } else if (msg.type === MESSAGETYPESV2.HalfRest) {
    halfTime.value = true;
    audioManager.play("中场休息");
  } else if (msg.type === MESSAGETYPESV2.InvalidShot) {
    uni.showToast({
      title: "距离不足，无效",
      icon: "none",
    });
    audioManager.play("射击无效");
  }
}

const playSound = (key) => {
  audioManager.play(key);
};

onMounted(() => {
  uni.$on("update-remain", resetTimer);
  uni.$on("socket-inbox", onReceiveMessage);
  uni.$on("play-sound", playSound);
});

onBeforeUnmount(() => {
  uni.$off("update-remain", resetTimer);
  uni.$off("socket-inbox", onReceiveMessage);
  uni.$off("play-sound", playSound);
  clearTimer();
});
</script>

<template>
  <view v-if="show" class="progress-card">
    <view class="progress-card__header">
      <view class="progress-card__profile">
        <view class="progress-card__avatar-shell">
          <Avatar
            :src="avatarSrc"
            :size="80"
            size-unit="rpx"
            image-mode="aspectFill"
          />
        </view>
        <view
          :class="[
            'progress-card__name',
            'member-nickname',
            isVip && !isSvip ? 'member-nickname--vip' : '',
            isSvip ? 'member-nickname--svip' : '',
          ]"
        >
          <text class="member-nickname__text">{{ displayName }}</text>
          <text v-if="isSvip" class="member-nickname__shine">
            {{ displayName }}
          </text>
        </view>
      </view>

      <!-- <button class="progress-card__sound" hover-class="none" @click="updateSound">
        <image
          class="progress-card__sound-icon"
          :src="`/static/sound${sound ? '' : '-off'}-yellow.png`"
          mode="aspectFit"
        />
      </button> -->
    </view>

    <view class="progress-card__track-wrap">
      <image
          class="progress-card__titile"
          :src="trainingTitleIcon"
          mode="aspectFit"
        />
      <view v-if="countdownEnabled" class="progress-card__track">
        <view
          class="progress-card__fill"
          :style="{
            width: `${progressPercent}%`,
            backgroundColor: barColor,
            right: tips.includes('红队') ? 0 : 'unset',
            transition: transitionStyle,
          }"
        />
        <view class="progress-card__badge">
          <text class="progress-card__badge-text">剩余{{ remain }}秒</text>
        </view>
      </view>
      <!-- <text v-if="tipContent" class="progress-card__tip">{{ tipContent }}123</text> -->
    </view>
  </view>
</template>

<style scoped>
.progress-card {
  box-sizing: border-box;
  /* padding: 50rpx 30rpx 0 30rpx; */
  margin: 70rpx 30rpx 0 30rpx;
}

.progress-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}

.progress-card__profile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.progress-card__avatar-shell {
  width: 86rpx;
  height: 86rpx;
  padding: 3rpx;
  box-sizing: border-box;
  border-radius: 50%;
  background: linear-gradient(180deg, rgba(255, 209, 153, 1), rgba(162, 119, 55, 1));
  display: flex;
  align-items: center;
  justify-content: center;
}

.progress-card__avatar {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 50%; 
}

.progress-card__name {
  width: 86rpx;
  color: #fff;
  font-size: 18rpx;
  line-height: 1;
  justify-content: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
  margin-top: 10rpx;
}

.progress-card__sound {
  width: 68rpx;
  height: 68rpx;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(28, 24, 21, 0.72);
  box-shadow: 0 8rpx 18rpx rgba(0, 0, 0, 0.18);
}

.progress-card__sound::after {
  border: none;
}

.progress-card__sound-icon {
  width: 34rpx;
  height: 34rpx;
}

.progress-card__track-wrap {
  margin-top: -156rpx;
  padding-left: 102rpx;
}

.progress-card__titile{
  width: 260rpx;
  height: 72rpx;
  margin-left: 110rpx;
}

.progress-card__track {
  position: relative;
  width: 100%;
  height: 24rpx;
  border-radius: 18rpx;
  overflow: hidden;
  background: #444444;
}

.progress-card__fill {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  border-radius: 18rpx;
  background: linear-gradient( 133deg, #FFD19A 0%, #A17636 100%);
}

.progress-card__badge {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  min-width: 156rpx;
  height: 40rpx;
  padding: 0 24rpx;
  box-sizing: border-box;
  border-radius: 999rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  /* background: rgba(164, 117, 47, 0.94); */
  /* box-shadow: 0 4rpx 10rpx rgba(76, 45, 7, 0.22); */
}

.progress-card__badge-text {
  color: #fff7de;
  font-size: 18rpx;
  line-height: 1;
  white-space: nowrap;
}

.progress-card__tip {
  display: block;
  margin-top: 16rpx;
  color: rgba(255, 243, 216, 0.88);
  font-size: 24rpx;
  line-height: 1.4;
  text-align: center;
}
</style>
