<script setup>
import { ref, onMounted } from "vue";
import { getElementRect, calcRing } from "@/util";

const props = defineProps({
  id: {
    type: Number,
    default: 0,
  },
  src: {
    type: String,
    default: "",
  },
  arrows: {
    type: Array,
    default: () => [],
  },
  onChange: {
    type: Function,
    default: null,
  },
});

const rect = ref({});
const arrow = ref(null);
const isDragging = ref(false);
const dragStartPos = ref({ x: 0, y: 0 });
const capsuleHeight = ref(0);
const scale = ref(1);
const zoomPos = ref({ x: 0, y: 0 });
const targetPos = ref({ x: 0, y: 0 });
let lastMoveTime = 0;

// 点击靶纸创建新的点
const onClick = async (e) => {
  if (
    arrow.value !== null ||
    !props.onChange ||
    Date.now() - lastMoveTime < 300
  ) {
    return;
  }

  const newArrow = {
    x: e.detail.x - zoomPos.value.x - 6 / scale.value,
    y:
      e.detail.y -
      rect.value.top -
      capsuleHeight.value -
      zoomPos.value.y -
      6 / scale.value,
  };

  targetPos.value = {
    x: zoomPos.value.x,
    y: zoomPos.value.y,
  };
  const side = rect.value.width;
  newArrow.ring = calcRing(
    props.id,
    newArrow.x / scale.value - rect.value.width * 0.05,
    newArrow.y / scale.value - rect.value.width * 0.05,
    rect.value.width * 0.9
  );
  arrow.value = {
    ...newArrow,
    x: newArrow.x / side,
    y: newArrow.y / side,
  };
};

// 确认添加箭矢
const confirmAdd = () => {
  if (props.onChange) {
    targetPos.value = {
      x: zoomPos.value.x,
      y: zoomPos.value.y,
    };
    props.onChange({
      x: arrow.value.x / scale.value,
      y: arrow.value.y / scale.value,
      ring: arrow.value.ring || "M",
    });
  }
  arrow.value = null;
};

// 删除箭矢
const deleteArrow = () => {
  arrow.value = null;
  targetPos.value = {
    x: zoomPos.value.x,
    y: zoomPos.value.y,
  };
};

// 开始拖拽 - 同样修复坐标获取
const startDrag = async (e) => {
  if (!e.touches[0]) return;
  isDragging.value = true;
  dragStartPos.value = {
    x: e.touches[0].clientX,
    y: e.touches[0].clientY,
  };
};

// 拖拽移动 - 同样修复坐标获取
const onDrag = async (e) => {
  lastMoveTime = Date.now();
  if (!isDragging.value || !e.touches[0] || !arrow.value) return;
  let clientX = e.touches[0].clientX;
  let clientY = e.touches[0].clientY;

  // 计算移动距离
  const deltaX = clientX - dragStartPos.value.x;
  const deltaY = clientY - dragStartPos.value.y;
  const side = rect.value.width;
  // 更新坐标
  arrow.value.x = Math.max(
    0,
    Math.min(side * scale.value, arrow.value.x * side + deltaX)
  );
  arrow.value.y = Math.max(
    0,
    Math.min(side * scale.value, arrow.value.y * side + deltaY)
  );
  arrow.value.ring = calcRing(
    props.id,
    arrow.value.x / scale.value - rect.value.width * 0.05,
    arrow.value.y / scale.value - rect.value.width * 0.05,
    rect.value.width * 0.9
  );

  arrow.value.x = arrow.value.x / side;
  arrow.value.y = arrow.value.y / side;

  // 更新拖拽起始位置
  dragStartPos.value = { x: clientX, y: clientY };
};

// 结束拖拽
const endDrag = (e) => {
  isDragging.value = false;
};
const onScale = (e) => {
  lastMoveTime = Date.now();
  const lastScale = scale.value;
  scale.value = e.detail.scale;
  zoomPos.value = { x: e.detail.x, y: e.detail.y };
  if (arrow.value) {
    arrow.value.x = arrow.value.x * (scale.value / lastScale);
    arrow.value.y = arrow.value.y * (scale.value / lastScale);
  }
};

const onMove = (e) => {
  if (e.detail.source) {
    zoomPos.value = { x: e.detail.x, y: e.detail.y };
  }
};

onMounted(async () => {
  const menuBtnInfo = uni.getMenuButtonBoundingClientRect();
  capsuleHeight.value = menuBtnInfo.top - 9;
  const result = await getElementRect(".container");
  rect.value = result;
});
</script>

<template>
  <view
    class="container"
    @tap="onClick"
    @touchmove="onDrag"
    @touchend="endDrag"
  >
    <movable-area class="move-area" scale-area>
      <movable-view
        class="move-view"
        direction="all"
        scale
        :x="targetPos.x"
        :y="targetPos.y"
        :scale-min="1"
        :scale-max="2"
        :scale-value="scale"
        :animation="false"
        @scale="onScale"
        @change="onMove"
        :out-of-bounds="true"
      >
        <image :src="src" mode="widthFix" />
        <view
          v-for="(arrow, index) in arrows"
          :key="index"
          class="arrow-point"
          :style="{
            left: (arrow.x !== undefined ? arrow.x : 0) * 100 + '%',
            top: (arrow.y !== undefined ? arrow.y : 0) * 100 + '%',
          }"
        >
          <view
            v-if="arrow.x !== undefined && arrow.y !== undefined"
            class="point"
          >
            <text>{{ index + 1 }}</text>
          </view>
        </view>
        <movable-view
          v-if="arrow"
          class="arrow-point"
          direction="all"
          :animation="false"
          :out-of-bounds="true"
          :x="arrow ? (rect.width * arrow.x) / scale : 0"
          :y="arrow ? (rect.width * arrow.y) / scale : 0"
        >
          <view class="point"> </view>
          <view
            v-if="arrow"
            class="edit-buttons"
            @touchstart.stop
            :style="{ transform: `scale(${1 / scale})` }"
          >
            <view class="edit-btn-text">
              <!-- <text v-if="arrow.ring === 0" :style="{ width: '100%' }"
                >未上靶</text
              > -->
              <text>{{ arrow.ring === 0 ? "M" : arrow.ring }}</text>
              <!-- <text
                v-if="arrow.ring > 0"
                :style="{
                  fontSize: '16px',
                  marginLeft: '2px',
                }"
                >环</text
              > -->
            </view>
            <view class="edit-btn confirm-btn" @touchstart.stop="confirmAdd">
              <image src="../static/arrow-edit-save.png" mode="widthFix" />
            </view>
            <view class="edit-btn delete-btn" @touchstart.stop="deleteArrow">
              <image src="../static/arrow-edit-delete.png" mode="widthFix" />
            </view>
            <view
              class="edit-btn drag-btn"
              @touchstart.stop="startDrag($event)"
            >
              <image src="../static/arrow-edit-move.png" mode="widthFix" />
            </view>
          </view>
        </movable-view>
      </movable-view>
    </movable-area>
  </view>
</template>

<style scoped>
.container {
  width: 100vw;
  height: 100vw;
  overflow: hidden;
  transform: translateY(-10px);
}

.move-area {
  width: 100%;
  height: 100%;
  position: relative;
}

.move-view {
  width: 90vw;
  height: 90vw;
  padding: 5vw;
  position: relative;
}

.move-view > image {
  width: 100%;
}

.arrow-point {
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
}

.point {
  min-width: 12px;
  min-height: 12px;
  border-radius: 50%;
  border: 1px solid #fff;
  color: #fff;
  font-size: 8px;
  text-align: center;
  line-height: 10px;
  box-sizing: border-box;
  background-color: #ff4444;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
  transition: all 0.1s linear;
}

.point > text {
  transform: scaleX(0.7);
  display: block;
  font-weight: bold;
}

.edit-buttons {
  position: absolute;
  top: calc(50% - 44px);
  left: calc(50% - 44px);
  background: #18ff6899;
  width: 88px;
  height: 88px;
  display: flex;
  align-items: flex-end;
  transition: all 0.1s linear;
}

.edit-btn-text {
  width: 100%;
  display: flex;
  /* justify-content: center; */
  margin-left: 10px;
}

.edit-btn-text > text {
  line-height: 50px;
  font-size: 24px;
  font-weight: bold;
  color: #fff;
  text-align: center;
}

.edit-btn {
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
}

.edit-btn > image {
  width: 24px;
  height: 24px;
}

.confirm-btn {
  left: calc(50% - 12px);
  bottom: -12px;
}

.delete-btn {
  left: calc(50% - 12px);
  top: -12px;
}

.drag-btn {
  right: -12px;
  bottom: -12px;
}
</style>
