<template>
  <div class="editable-subregion">
    <div
      ref="containerRef"
      class="mapBox blockArea"
      :style="{
        width: `${canvasSize}px`,
        height: `${canvasSize}px`,
        cursor: !editable ? 'no-drop' : isCreating ? 'crosshair' : 'default',
        position: 'relative',
      }"
      @mousedown="handleMouseDown"
    >
      <!-- 绘制临时选区 -->
      <div
        v-if="currentBlock"
        class="temp-block"
        :style="{
          left: `${Math.min(currentBlock.startX, currentBlock.currentX)}px`,
          top: `${Math.min(currentBlock.startY, currentBlock.currentY)}px`,
          width: `${Math.abs(currentBlock.currentX - currentBlock.startX)}px`,
          height: `${Math.abs(currentBlock.currentY - currentBlock.startY)}px`,
        }"
      ></div>

      <!-- 已创建区块 -->
      <div
        v-for="(block, index) in roomStore.localSubRegions"
        :key="block.nanoid"
        class="block-item"
        :style="getBlockStyle(block)"
        @mousedown.self="startDrag(block, $event)"
      >
        <div
          class="resize-handle"
          :style="{ backgroundColor: block.isBed ? '#1abc1a' : '#1890ff' }"
          @mousedown.stop="startResize(block, $event)"
        >
          {{ index + 1 }}
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, type CSSProperties, watch, nextTick } from 'vue'
import { message } from 'ant-design-vue'
import { nanoid } from 'nanoid'
import { useRoomStore } from '@/stores/room'
import type { LocalSubRegionItem } from '@/api/room/types'
import { convert_region_r2c, rotateRect } from '@/utils/coordTransform'

defineOptions({ name: 'EditableSubregion' })
const roomStore = useRoomStore()

// ✅ props
interface Props {
  angle: number
  canvasSize?: number
  editable?: boolean
  hasBed?: boolean
}
const props = withDefaults(defineProps<Props>(), {
  canvasSize: 500,
  editable: false,
  hasBed: false,
})
const emit = defineEmits<{
  // (e: 'update:subRegions', regions: LocalSubRegionItem[]): void
  (e: 'create'): void
  (e: 'update', regions: LocalSubRegionItem[]): void
}>()

// ✅ 工具函数
const debug = false
const log = (...args: unknown[]) => debug && console.log('[EditableSubregion]', ...args)

// ✅ refs / 状态
const containerRef = ref<HTMLElement>()
const isCreating = ref(false)
const currentBlock = ref<{
  startX: number
  startY: number
  currentX: number
  currentY: number
} | null>(null)

const editable = computed(() => props.editable)
const center = computed(() => props.canvasSize / 2)

// ✅ 坐标转换
const geoToPixel = (x: number, y: number) => ({
  x: center.value + x,
  y: center.value - y,
})
const pixelToGeo = (x: number, y: number) => ({
  x: x - center.value,
  y: center.value - y,
})

// ✅ Block 样式
const getBlockStyle = (block: LocalSubRegionItem): CSSProperties => ({
  left: `${block.pixelX}px`,
  top: `${block.pixelY}px`,
  width: `${block.pixelWidth}px`,
  height: `${block.pixelHeight}px`,
  border: `2px solid ${block.isBed ? '#1abc1a' : block.isActive ? 'yellow' : '#1890ff'}`,
  position: 'absolute',
  cursor: editable.value ? 'move' : 'no-drop',
  backgroundColor: block.isBed ? 'rgba(26,188,26,0.1)' : 'rgba(24,144,255,0.1)',
  zIndex: 1,
})

// ✅ 同步数据（像素→地理）
const updateSubRegionsData = () => {
  if (!roomStore.localSubRegions.length) {
    emit('update', [])
    return
  }

  const updated = roomStore.localSubRegions.map((block) => {
    const centerGeo = pixelToGeo(
      block.pixelX + block.pixelWidth / 2,
      block.pixelY + block.pixelHeight / 2
    )
    const w = block.pixelWidth
    const h = block.pixelHeight

    return {
      ...block,
      startXx: centerGeo.x - w / 2,
      stopXx: centerGeo.x + w / 2,
      startYy: centerGeo.y - h / 2,
      stopYy: centerGeo.y + h / 2,
      startZz: Number(block.startZz) || 0,
      stopZz: Number(block.stopZz) || 0,
    }
  })

  roomStore.localSubRegions = updated
  emit('update', updated)
}

// ✅ 新建区块
const createNewBlock = () => {
  if (roomStore.localSubRegions.length >= 6) {
    message.warn('最多只能创建6个区块')
    return
  }
  isCreating.value = true
  message.info('请在画布上拖拽创建子区域')
}
defineExpose({ createNewBlock })

// ✅ 鼠标操作通用工具
const getRect = () =>
  containerRef.value?.getBoundingClientRect() || { left: 0, top: 0, width: 0, height: 0 }

// ✅ 创建逻辑
const handleMouseDown = (e: MouseEvent) => {
  if (!editable.value || !isCreating.value) return

  const rect = getRect()
  const startX = e.clientX - rect.left
  const startY = e.clientY - rect.top
  currentBlock.value = { startX, startY, currentX: startX, currentY: startY }

  const move = (e: MouseEvent) => {
    if (!currentBlock.value) return
    currentBlock.value.currentX = Math.max(0, Math.min(e.clientX - rect.left, rect.width))
    currentBlock.value.currentY = Math.max(0, Math.min(e.clientY - rect.top, rect.height))
  }

  const up = () => {
    if (!currentBlock.value) return
    const { startX, startY, currentX, currentY } = currentBlock.value
    const width = Math.abs(currentX - startX)
    const height = Math.abs(currentY - startY)

    if (width > 10 && height > 10) {
      const minX = Math.min(startX, currentX)
      const minY = Math.min(startY, currentY)
      const centerGeo = pixelToGeo(minX + width / 2, minY + height / 2)

      const newBlock: LocalSubRegionItem = {
        nanoid: nanoid(),
        isDraging: false,
        isResizing: false,
        isActive: false,
        isTracking: false,
        isFalling: false,
        isBed: false,
        pixelX: minX,
        pixelY: minY,
        pixelWidth: width,
        pixelHeight: height,
        startXx: centerGeo.x - width / 2,
        stopXx: centerGeo.x + width / 2,
        startYy: centerGeo.y - height / 2,
        stopYy: centerGeo.y + height / 2,
        startZz: 0,
        stopZz: 0,
        isLowSnr: 0,
        isDoor: 0,
        presenceEnterDuration: 3,
        presenceExitDuration: 3,
        trackPresence: 0,
        excludeFalling: 0,
      }

      roomStore.localSubRegions.push(newBlock)
      emit('create')
    } else {
      message.warn('区域太小，请绘制更大的区域')
    }

    currentBlock.value = null
    isCreating.value = false
    document.removeEventListener('mousemove', move)
    document.removeEventListener('mouseup', up)
  }

  document.addEventListener('mousemove', move)
  document.addEventListener('mouseup', up)
}

// ✅ 拖动
const startDrag = (block: LocalSubRegionItem, e: MouseEvent) => {
  if (!editable.value) return
  e.stopPropagation()

  roomStore.localSubRegions.forEach((b) => (b.isActive = false))
  block.isDraging = true
  block.isActive = true

  const rect = getRect()
  const offsetX = e.clientX - rect.left - block.pixelX
  const offsetY = e.clientY - rect.top - block.pixelY
  const initX = block.pixelX
  const initY = block.pixelY

  const move = (e: MouseEvent) => {
    const newX = e.clientX - rect.left - offsetX
    const newY = e.clientY - rect.top - offsetY
    block.pixelX = Math.max(0, Math.min(newX, rect.width - block.pixelWidth))
    block.pixelY = Math.max(0, Math.min(newY, rect.height - block.pixelHeight))
  }

  const up = () => {
    block.isDraging = false
    block.isActive = false
    if (block.pixelX !== initX || block.pixelY !== initY) updateSubRegionsData()
    document.removeEventListener('mousemove', move)
    document.removeEventListener('mouseup', up)
  }

  document.addEventListener('mousemove', move)
  document.addEventListener('mouseup', up)
}

// ✅ 缩放
const startResize = (block: LocalSubRegionItem, e: MouseEvent) => {
  if (!editable.value) return
  e.stopPropagation()
  e.preventDefault()

  block.isResizing = true
  const startX = e.clientX
  const startY = e.clientY
  const initW = block.pixelWidth
  const initH = block.pixelHeight
  const rect = getRect()

  const move = (e: MouseEvent) => {
    const deltaX = e.clientX - startX
    const deltaY = e.clientY - startY
    block.pixelWidth = Math.max(20, Math.min(initW + deltaX, rect.width - block.pixelX))
    block.pixelHeight = Math.max(20, Math.min(initH + deltaY, rect.height - block.pixelY))
  }

  const up = () => {
    block.isResizing = false
    updateSubRegionsData()
    document.removeEventListener('mousemove', move)
    document.removeEventListener('mouseup', up)
  }

  document.addEventListener('mousemove', move)
  document.addEventListener('mouseup', up)
}

// ✅ 回显数据（地理→像素）
const echoSubRegions = () => {
  roomStore.localSubRegions = roomStore.localSubRegions.map((item, index) => {
    const itemRegion = convert_region_r2c(
      {
        x_cm_start: Number(item.startXx),
        x_cm_stop: Number(item.stopXx),
        y_cm_start: Number(item.startYy),
        y_cm_stop: Number(item.stopYy),
      },
      {
        x_radar: 250,
        y_radar: 250,
      }
    )

    const routeRegion = rotateRect(itemRegion, { x: 250, y: 250 }, props.angle)

    console.log(item, itemRegion, routeRegion, '🚀🚀🚀🚀🚀🚀🚀')

    return {
      ...item,
      nanoid: item.nanoid || nanoid(),
      isDraging: false,
      isResizing: false,
      isActive: false,
      isTracking: Boolean(item.trackPresence),
      isFalling: Boolean(item.excludeFalling),
      isBed: index === 0 && props.hasBed,
      pixelX: routeRegion.left,
      pixelY: routeRegion.top,
      pixelWidth: routeRegion.width,
      pixelHeight: routeRegion.height,
    }
  })
}
echoSubRegions()

const renderSubRegions = () => {
  roomStore.localSubRegions = roomStore.localSubRegions.map((item, index) => {
    const centerX = (Number(item.startXx) + Number(item.stopXx)) / 2
    const centerY = (Number(item.startYy) + Number(item.stopYy)) / 2
    const w = Math.abs(Number(item.stopXx) - Number(item.startXx))
    const h = Math.abs(Number(item.stopYy) - Number(item.startYy))
    const pos = geoToPixel(centerX, centerY)

    return {
      ...item,
      nanoid: item.nanoid || nanoid(),
      isDraging: false,
      isResizing: false,
      isActive: false,
      isTracking: Boolean(item.trackPresence),
      isFalling: Boolean(item.excludeFalling),
      isBed: index === 0 && props.hasBed,
      pixelX: pos.x - w / 2,
      pixelY: pos.y - h / 2,
      pixelWidth: w,
      pixelHeight: h,
    }
  })
}

// ✅ 监听手动调整，重新回显像素位置
const geoCoordinatesSignature = computed(() => {
  return roomStore.localSubRegions
    .map((region) => `${region.startXx}_${region.stopXx}_${region.startYy}_${region.stopYy}`)
    .join('|')
})

watch(geoCoordinatesSignature, () => {
  nextTick(() => {
    renderSubRegions()
  })
})

onMounted(() => log('component mounted'))
</script>

<style scoped lang="less">
.editable-subregion {
  display: flex;
  gap: 20px;
}

.temp-block {
  position: absolute;
  background: rgba(24, 144, 255, 0.2);
  border: 2px dashed #1890ff;
  pointer-events: none;
  z-index: 2;
}

.block-item {
  background: rgba(24, 144, 255, 0.1);
  pointer-events: all;
  z-index: 1;

  &:hover {
    background: rgba(24, 144, 255, 0.2);
  }

  .resize-handle {
    position: absolute;
    right: -4px;
    bottom: -4px;
    width: 15px;
    height: 15px;
    background: #1890ff;
    cursor: nwse-resize;
    font-size: 10px;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 2px;
    z-index: 3;
  }
}
</style>
