<template>
  <view>
    <view
      id="_drag_button"
      class="drag"
      :style="'left: ' + left + 'px; top:' + top + 'px;'"
      @touchstart="touchstart"
      @touchmove.stop.prevent="touchmove"
      @touchend="touchend"
      @click.stop.prevent="click"
      :class="{ transition: isDock && !isMove }"
    >
      <text class="title">{{ text }}</text>
      <text class="price">{{ price }}</text>
    </view>
  </view>
</template>

<script>
export default {
  name: "drag-button",
  props: {
    // 是否开启贴边（拖拽结束后自动贴左右边缘）
    isDock: {
      type: Boolean,
      default: false,
    },
    // 显示的价格数值
    price: {
      type: Number,
      default: 0,
    },
    // 是否存在底部TabBar（存在时需调整屏幕可用高度）
    existTabBar: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      top: 0, // 按钮顶部距离屏幕顶部的距离
      left: 0, // 按钮左侧距离屏幕左侧的距离
      width: 0, // 按钮宽度
      height: 0, // 按钮高度
      offsetWidth: 0, // 按钮宽度的一半（用于拖拽时定位）
      offsetHeight: 0, // 按钮高度的一半（用于拖拽时定位）
      windowWidth: 0, // 屏幕可用宽度
      windowHeight: 0, // 屏幕可用高度
      isMove: true, // 是否处于拖拽中（控制过渡动画）
      edge: 15, // 按钮与屏幕边缘的间距（左右/上下通用）
      text: "实时金价", // 按钮顶部文本
    };
  },
  mounted() {
    // 获取系统信息（屏幕尺寸、状态栏等）
    const sys = uni.getSystemInfoSync();
    this.windowWidth = sys.windowWidth;
    this.windowHeight = sys.windowHeight;

    // APP端有TabBar时，减去TabBar高度（默认50px，可根据实际调整）
    // #ifdef APP-PLUS
    this.existTabBar && (this.windowHeight -= 50);
    // #endif

    // 处理部分设备顶部状态栏偏移（确保屏幕高度计算完整）
    if (sys.windowTop) {
      this.windowHeight += sys.windowTop;
    }

    // 获取按钮自身的尺寸（宽度/高度）
    const query = uni.createSelectorQuery().in(this);
    query
      .select("#_drag_button")
      .boundingClientRect((data) => {
        this.width = data.width;
        this.height = data.height;
        this.offsetWidth = data.width / 2;
        this.offsetHeight = data.height / 2;

        // 初始left：靠右显示，距离右侧边缘edge距离
        this.left = this.windowWidth - this.width - this.edge;

        // 核心修改：初始top = 屏幕高度的一半 - 按钮高度的一半（实现垂直居中）
        // 确保按钮的垂直中心与屏幕中心对齐，而非按钮顶部对齐屏幕中心
        this.top = this.windowHeight / 2 - this.height / 2;
      })
      .exec();
  },
  methods: {
    // 按钮点击事件（向父组件传参）
    click() {
      this.$emit("btnClick");
    },
    // 触摸开始事件（向父组件传参）
    touchstart(e) {
      this.$emit("btnTouchstart");
    },
    // 触摸移动事件（控制按钮拖拽位置）
    touchmove(e) {
      // 仅允许单指拖拽
      if (e.touches.length !== 1) {
        return false;
      }

      this.isMove = true; // 拖拽中关闭过渡动画

      // 水平方向定位：触摸点X坐标 - 按钮宽度的一半（确保触摸点在按钮中心）
      this.left = e.touches[0].clientX - this.offsetWidth;

      // 垂直方向定位：触摸点Y坐标 - 按钮高度的一半
      let clientY = e.touches[0].clientY - this.offsetHeight;
      // H5端特殊处理：补偿高度偏移（避免拖拽时位置偏移）
      // #ifdef H5
      clientY += this.height;
      // #endif

      // 计算垂直方向边界：底部最大可移动距离（避免按钮超出屏幕底部）
      let edgeBottom = this.windowHeight - this.height - this.edge;

      // 垂直方向边界限制：不允许超出屏幕上下边缘
      if (clientY < this.edge) {
        this.top = this.edge; // 上边界
      } else if (clientY > edgeBottom) {
        this.top = edgeBottom; // 下边界
      } else {
        this.top = clientY; // 正常拖拽位置
      }
    },
    // 触摸结束事件（控制贴边逻辑 + 向父组件传参）
    touchend(e) {
      // 开启贴边功能时，拖拽结束后自动贴左右边缘
      if (this.isDock) {
        const edgeRight = this.windowWidth - this.width - this.edge; // 右侧边缘位置
        // 判断按钮中心是否在屏幕左半区：是则贴左，否则贴右
        if (this.left < this.windowWidth / 2 - this.offsetWidth) {
          this.left = this.edge; // 贴左边缘
        } else {
          this.left = edgeRight; // 贴右边缘
        }
      }

      this.isMove = false; // 拖拽结束开启过渡动画
      this.$emit("btnTouchend"); // 向父组件传参
    },
  },
};
</script>

<style lang="scss">
.drag {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  background: linear-gradient(180deg, #fefcf9 0%, #fff2df 100%);
  box-shadow: 0rpx 3rpx 12rpx 0rpx rgba(0, 0, 0, 0.16);
  width: 105upx;
  height: 105upx;
  border-radius: 50%; // 圆形按钮
  position: fixed; // 固定定位（不随页面滚动）
  z-index: 999999; // 最高层级，避免被其他元素遮挡
  .title {
    font-size: 19rpx;
    color: #000000;
    margin-bottom: 4rpx; // 文本与价格间距
  }
  .price {
    font-size: 26rpx;
    color: #cc0000;
    font-weight: bold;
  }
  // 贴边/停止拖拽时的过渡动画
  &.transition {
    transition: left 0.3s ease, top 0.3s ease;
  }
}
</style>
