<script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import { getElementRect, calcRing, capsuleHeight } 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 scale = ref(1);
const scrollTop = ref(0);
const selected = ref(null);
let lastMoveTime = 0;

// 点击靶纸创建新的点
const onClick = async (e) => {
  if (
    arrow.value !== null ||
    !props.onChange ||
    Date.now() - lastMoveTime < 300
  ) {
    return;
  }
  if (props.id === 7 || props.id === 9) {
    if (
      e.detail.x < rect.value.width * 0.2 ||
      e.detail.x > rect.value.width * 0.8
    )
      return;
    // 放大并通过滚动将点击位置置于视窗中心
    scale.value = 1.4;
    const viewportH = rect.value.width; // 容器高度等于宽度（100vw）
    const contentH = scale.value * rect.value.width; // 内容高度
    const clickYInContainer = e.detail.y - rect.value.top;
    let target = clickYInContainer * scale.value - viewportH / 2;
    target = Math.max(0, Math.min(contentH - viewportH, target));
    setTimeout(() => {
      scrollTop.value = target > 180 ? target + 10 : target;
    }, 200);
  }
  const newArrow = {
    x: (e.detail.x - 6) * scale.value,
    y: (e.detail.y - rect.value.top - capsuleHeight - 6) * scale.value,
  };

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

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

// 删除箭矢
const deleteArrow = () => {
  arrow.value = null;
  scale.value = 1;
  scrollTop.value = 0;
};

// 开始拖拽 - 同样修复坐标获取
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 - side * 0.05,
    arrow.value.y / scale.value - side * 0.05,
    side * 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 getNewPos = () => {
  if (props.id === 7 || props.id === 9) {
    if (arrow.value.y >= 1.33)
      return { left: "-12px", bottom: "calc(50% - 12px)" };
  } else {
    if (arrow.value.y > 0.88) {
      if (arrow.value.x < 0.05) {
        return { left: "calc(100% - 12px)", bottom: "calc(100% - 12px)" };
      }
      return { left: "-12px", bottom: "calc(50% - 12px)" };
    }
  }
  return { left: "calc(50% - 12px)", bottom: "-12px" };
};

const setEditArrow = (data) => {
  selected.value = data;
  // if (data === null) {
  //   arrow.value = null;
  //   scale.value = 1;
  //   scrollTop.value = 0;
  //   return;
  // }
  // if (props.id === 7 || props.id === 9) {
  //   scale.value = 1.4;
  //   const viewportH = rect.value.width; // 容器高度等于宽度（100vw）
  //   const contentH = scale.value * rect.value.width; // 内容高度
  //   const clickYInContainer = contentH * data.y - rect.value.top;
  //   let target = clickYInContainer * scale.value - viewportH / 2;
  //   target = Math.max(0, Math.min(contentH - viewportH, target));
  //   setTimeout(() => {
  //     scrollTop.value = target > 180 ? target + 10 : target;
  //   }, 200);
  // }
  // arrow.value = {
  //   ...data,
  //   x: data.x * scale.value,
  //   y: data.y * scale.value,
  // };
};

onMounted(async () => {
  const result = await getElementRect(".container");
  rect.value = result;
  uni.$on("set-edit-arrow", setEditArrow);
});

onBeforeUnmount(() => {
  uni.$off("set-edit-arrow", setEditArrow);
});
</script>

<template>
  <scroll-view
    :scroll-y="scale > 1"
    scroll-with-animation
    :scroll-top="scrollTop"
    :show-scrollbar="false"
    :enhanced="true"
    class="container"
    @tap="onClick"
    @touchmove="onDrag"
    @touchend="endDrag"
  >
    <movable-area
      class="move-area"
      :style="{
        width: scale * 100 + 'vw',
        height: scale * 100 + 'vw',
        transform: `translateX(${(100 - scale * 100) / 2}vw)`,
      }"
    >
      <image :src="src" mode="widthFix" />
      <view
        v-for="(arrow, index) in arrows"
        :key="index"
        :class="`arrow-point ${
          selected !== null && index === selected ? 'selected-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 : 0"
        :y="arrow ? rect.width * arrow.y : 0"
      >
        <view
          class="point"
          :style="{ minWidth: 10 * scale + 'px', minHeight: 10 * scale + 'px' }"
        >
          <view v-if="arrow" class="edit-buttons" @touchstart.stop>
            <view class="edit-btn-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"
              :style="{ ...getNewPos() }"
            >
              <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>
        </view>
      </movable-view>
      <!-- <view class="test-view"></view> -->
    </movable-area>
  </scroll-view>
</template>

<style scoped>
.container {
  width: 100vw;
  height: 100vw;
  overflow-x: hidden;
}
.container::-webkit-scrollbar {
  width: 0;
  height: 0;
  color: transparent;
}

.move-area {
  width: 100%;
  height: 100%;
  transition: all 0.3s ease;
}

.move-area > image {
  width: 90%;
  height: 90%;
  margin: 5%;
}

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

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

.arrow-point {
  position: absolute;
}

.point {
  min-width: 10px;
  min-height: 10px;
  border-radius: 50%;
  border: 1px solid #fff;
  color: #fff;
  text-align: center;
  line-height: 10px;
  box-sizing: border-box;
  background-color: #00bf04;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  transition: all 0.1s linear;
  position: relative;
  transform: translate(-50%, -50%);
}

.point > text {
  display: block;
  font-size: 16rpx;
  line-height: 10px;
  position: absolute;
  top: 50%;
  left: 50%;
  font-family: "DINCondensed", "PingFang SC", "Helvetica Neue", Arial,
    sans-serif;
  transform: translate(-50%, -50%);
  margin-top: 1px;
}

.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;
}

.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 {
  transition: all 0.3s ease;
}

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

.drag-btn {
  right: -12px;
  bottom: -12px;
}
.test-view {
  position: absolute;
  top: 29px;
  left: 138px;
  width: 115px;
  height: 115px;
  background-color: #ff000055;
}
.selected-arrow-point .point {
  background: linear-gradient(180deg, #ffdaa6 0%, #e9a333 100%) !important;
  box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.18);
  animation: duang 0.35s ease-out;
}
@keyframes duang {
  0% {
    transform: translate(-50%, -50%) scale(0.7);
  }
  45% {
    transform: translate(-50%, -50%) scale(1.4);
  }
  70% {
    transform: translate(-50%, -50%) scale(0.9);
  }
  100% {
    transform: translate(-50%, -50%) scale(1);
  }
}
</style>
