<template>
  <view class="voice-mask" v-show="showVoiceMask">
    <!--语音条 -->
    <view
      class="voice-bar voice-del"
      :class="{ voiceDel: needCancel }"
      :style="{ width: getVoiceBarWidth }"
    >
      <image
        src="../../static/images/chat/yinping.png"
        class="voice-volume"
      ></image>
      <view class="trangle-bottom" :class="{ trangleDel: needCancel }"></view>
    </view>
    <view class="voice-send">
      <!-- 取消和转文字图标 -->
      <view class="voice-middle-wrapper">
        <!-- 取消 -->
        <view class="voice-left-wrapper">
          <view class="cancel-del" :class="{ delTip: needCancel }">
            松开 取消
          </view>
          <view
            class="voice-middle-inner close"
            :class="{ bigger: needCancel }"
          >
            <u-icon name="close" color="#fff" size="24"></u-icon>
          </view>
        </view>
        <!-- 转文字 -->
        <view class="send-tip" :class="{ sendTipNone: needCancel }">
          松开 发送
        </view>
      </view>
      <!-- 底部语音按钮 -->
      <view
        ref="maskBottom"
        class="mask-bottom"
        @touchstart="handleTouchStart"
        @touchmove="handleTouchMove"
        @touchend="handleTouchEnd"
      >
        <image src="../../static/images/chat/voice.png"></image>
      </view>
    </view>
  </view>
</template>

<script>
const recorderManager = uni.getRecorderManager();
export default {
  props: {
    showVoiceMask: {
      type: Boolean,
      default: false,
    },
    voicePopupTouches: {
      type: Object,
      default: {},
    },
  },
  data() {
    return {
      voicelength: 0,
      needCancel: false,
      startX: 0,
      startY: 0,
      timer: 0,
      maskBottomRect: null,
      isRecording: false,
      isOutside: false,
      tempFilePath: null,
      startTime: 0,
      isOutside: false,
    };
  },
  computed: {
    // 计算语音条宽度
    getVoiceBarWidth() {
      return 230 + this.voicelength * 4 + "rpx";
    },
  },
  watch: {
    showVoiceMask: {
      handler: function (val, oldVal) {
        if (val) {
          console.log("showVoicePopupTouches", this.voicePopupTouches);

          console.log(this.$refs["maskBottom"].$el.dispatchEvent);
          const mockEvent = new TouchEvent("touchstart", {
            touches: [{ pageX: 100, pageY: 100 }], // 模拟触摸坐标
          });

          this.$refs["maskBottom"].$el.dispatchEvent(mockEvent);
          this.handleTouchStart(this.voicePopupTouches);
        }
      },
    },
  },
  created() {
    // 初始化录音管理器
    recorderManager.onStart(() => {
      console.log("录音开始");
      this.isRecording = true;
      this.startTime = Date.now();
    });

    recorderManager.onPause(() => {
      console.log("录音暂停");
      this.isRecording = false;
    });

    recorderManager.onResume(() => {
      console.log("录音继续");
      this.isRecording = true;
    });
  },
  methods: {
    async getMaskBottomRect() {
      return new Promise((resolve) => {
        const query = uni.createSelectorQuery().in(this);
        query
          .select(".mask-bottom")
          .boundingClientRect((data) => {
            this.maskBottomRect = data;
            console.log("元素位置信息:", data); // 调试用
            resolve(data);
          })
          .exec();
      });
    },

    async handleTouchStart(e) {
      console.log("handleTouchStart", e);

      if (!this.maskBottomRect) {
        await this.getMaskBottomRect();
      }

      recorderManager.start();
      this.length = 1;
      this.startX = e.touches[0].pageX;
      this.startY = e.touches[0].pageY;
      this.timer = setInterval(() => {
        this.length += 1;
        if (this.length >= 60) {
          clearInterval(this.timer);
          this.handleTouchEnd();
        }
      }, 1000);
      this.isRecording = true;
      this.isOutside = false;
    },

    handleTouchMove(e) {
      // 检查是否在mask-bottom区域外
      if (!this.maskBottomRect) return;

      const touchX = e.touches[0].pageX;
      const touchY = e.touches[0].pageY;

      // 检查是否在mask-bottom区域外
      // 更精确的边界检查
      const SAFE_MARGIN = 5; // 像素单位
      const isNowOutside =
        touchX < this.maskBottomRect.left - SAFE_MARGIN ||
        touchX >
          this.maskBottomRect.left + this.maskBottomRect.width + SAFE_MARGIN ||
        touchY < this.maskBottomRect.top - SAFE_MARGIN ||
        touchY >
          this.maskBottomRect.top + this.maskBottomRect.height + SAFE_MARGIN;

      // 调试输出
      console.log(
        `触摸点: (${touchX}, ${touchY})`,
        `元素区域: [${this.maskBottomRect.left}, ${this.maskBottomRect.top}, ${this.maskBottomRect.width}, ${this.maskBottomRect.height}]`,
        `是否在外: ${isNowOutside}`
      );

      // 如果状态发生变化（进入或离开区域）
      if (isNowOutside !== this.isOutside) {
        this.isOutside = isNowOutside;

        if (this.isOutside) {
          // 离开区域，暂停录制
          recorderManager.pause();
          console.log("已离开区域，暂停录制");
        } else {
          // 回到区域，继续录制
          recorderManager.resume();
          console.log("已回到区域，继续录制");
        }
      }

      // 原有的取消逻辑
      if (this.startX - touchX > 14 && this.startY - touchY > 50) {
        this.needCancel = true;
      } else {
        this.needCancel = false;
      }
    },

    handleTouchEnd(e) {
      clearInterval(this.timer);
      recorderManager.stop();
      recorderManager.onStop((res) => {
        const message = {
          voice: res.tempFilePath,
          length: this.length,
        };
        if (!this.needCancel) {
          this.inputSubmit(message, 2);
        } else {
          this.inputSubmit();
        }
        this.needCancel = false;
      });
    },

    inputSubmit(msg, types) {
      if (msg && types) {
        this.$emit("voiceEnd", msg, types);
      } else {
        this.$emit("voiceEnd");
      }
    },
  },
};
</script>

<style lang="scss">
.voice-mask {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: rgba(0, 0, 0, 0.8);
  z-index: 9999; /* 确保足够高 */
  display: flex;
  justify-content: center;
  align-items: center;
}
.voice-bar {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -30%);
  height: 150rpx;
  background-color: #51ff50;
  border-radius: 26rpx;
  margin-bottom: 220rpx;
  z-index: 9999;
}
.voiceDel {
  left: 80rpx;
  top: 50%;
  width: 170rpx !important;
  transform: translateX(0%);
  transform: translateY(-30%);
  background-color: red;
}
.voice-volume {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 160rpx;
  height: 36rpx;
}
.volumeDel {
  width: 80rpx;
}
.trangle-bottom {
  position: absolute;
  bottom: -38rpx;
  left: 50%;
  transform: translateX(-50%);
  border-width: 20rpx;
  border-style: solid;
  border-color: #51ff50 transparent transparent transparent;
  z-index: 9999;
}
.trangleDel {
  border-color: red transparent transparent transparent;
}
.voice-send {
  position: relative;
  bottom: 0;
  width: 100%;
  height: 100%;
  z-index: 9999;
}
.voice-middle-wrapper {
  width: 100%;
  display: flex;
  position: absolute;
  justify-content: space-between;
  align-items: flex-end;
  margin-bottom: 40rpx;
  bottom: 15%;
}
.voice-left-wrapper {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-end;
}
.cancel-del {
  display: none;
}
.delTip {
  display: block;
  color: #bfbfbf;
  margin: 0 22rpx 18rpx 0;
}
.voice-middle-inner {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #595959;
  width: 140rpx;
  height: 140rpx;
  border-radius: 50%;
}
.close {
  transform: rotate(350deg);
  margin-left: 80rpx;
}
.bigger {
  width: 170rpx;
  height: 170rpx;
  background: #ececec;
}
.to-text {
  transform: rotate(10deg);
  margin-right: 80rpx;
}
.close-icon {
  width: 80rpx;
  height: 80rpx;
  color: #fff;
}
.wen {
  font-size: 40rpx;
  color: #bfbfbf;
}
.send-tip {
  position: absolute;
  left: 50%;
  bottom: 0rpx;
  transform: translate(-50%, 36%);
  color: #bfbfbf;
}
.sendTipNone {
  display: none;
}
.mask-bottom {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 180rpx;
  border-top: #bababb 8rpx solid;
  border-radius: 50% 50% 0 0;
  background-image: linear-gradient(#949794, #e1e3e1);
  z-index: 9999;
}
.mask-bottom image {
  position: absolute;
  width: 60rpx;
  height: 60rpx;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  margin: auto;
}
</style>
