<template>
  <a-spin :spinning="spinning">
    <div class="viewer">
      <div class="viewer-header">
        <div>
          <div class="viewer-header-title">家具配置</div>
          <div class="viewer-header-subtitle">检测范围 {{ areaWidth }} x {{ areaHeight }} cm</div>
        </div>
        <div class="viewer-header-extra">
          <a-space>
            <a-switch
              :checked="isEditDraggable"
              checked-children="启用"
              un-checked-children="禁用"
              @change="isEditDraggable = !isEditDraggable"
            />
            <a-button
              type="primary"
              size="small"
              :disabled="!isEditDraggable"
              @click="saveFurnitureMapConfig"
              >保存家具</a-button
            >
          </a-space>
        </div>
      </div>
      <div class="viewer-content">
        <div
          ref="contentEl"
          class="mapBox"
          :style="{
            width: `${areaWidth}px`,
            height: `${areaHeight}px`,
          }"
          @mousedown="handleMouseDownMapCanvas"
        >
          <furniture-icon
            v-for="(item, index) in mapCanvasList"
            :key="index"
            :icon="item.type"
            :width="item.width"
            :height="item.height"
            :style="{
              left: `${item.left}px`,
              top: `${item.top}px`,
              position: 'absolute',
              transform: `rotate(${item.rotate}deg)`,
              cursor: item.type === 'radar' ? 'default' : isEditDraggable ? 'move' : 'default',
              pointerEvents: item.type === 'radar' ? 'none' : isEditDraggable ? 'auto' : 'none',
              border: `${item.isActice && item.type !== 'radar' ? '2px solid yellow' : 'none'}`,
            }"
            :class="{ 'dragging-item': item.isDragging }"
            tabindex="0"
            :draggable="item.type === 'radar' ? false : isEditDraggable"
            @dragstart="onDragstartListItem($event, item)"
            @dragend="onDragendEndListItem($event, item)"
            @click="onClickMapItem($event, item)"
          />
        </div>

        <div v-if="clickedDragItem" class="mapConfig">
          <div class="mapConfig-header">家具属性</div>
          <div class="mapConfig-item">
            <div class="mapConfig-item-label">家具名称：</div>
            <div class="mapConfig-item-content">
              <a-input
                v-if="clickedDragItem"
                v-model:value.trim="clickedDragItem.name"
                size="small"
                style="width: 128px"
              />
            </div>
          </div>

          <div class="mapConfig-item">
            <div class="mapConfig-item-label">家具大小：</div>
            <div class="mapConfig-item-content">
              <a-space v-if="clickedDragItem">
                <a-input-number
                  v-model:value.trim="clickedDragItem.width"
                  size="small"
                  style="width: 60px"
                />
                <a-input-number
                  v-model:value.trim="clickedDragItem.height"
                  size="small"
                  style="width: 60px"
                />
              </a-space>
            </div>
          </div>

          <div class="mapConfig-item">
            <div class="mapConfig-item-label">家具旋转：</div>
            <div class="mapConfig-item-content">
              <a-space>
                <UndoOutlined
                  :rotate="-270"
                  @click="rotateFurnitureIcon(1, clickedDragItem?.nanoid || '')"
                />
                <RedoOutlined
                  :rotate="-90"
                  @click="rotateFurnitureIcon(2, clickedDragItem?.nanoid || '')"
                />
              </a-space>
            </div>
          </div>

          <div class="mapConfig-item">
            <div class="mapConfig-item-label">微调位置：</div>
            <div class="mapConfig-item-content">
              <a-space>
                <ArrowLeftOutlined
                  @click="positonFurnitureIcon('left', clickedDragItem?.nanoid || '', distance)"
                />
                <ArrowUpOutlined
                  @click="positonFurnitureIcon('up', clickedDragItem?.nanoid || '', distance)"
                />
                <ArrowDownOutlined
                  @click="positonFurnitureIcon('down', clickedDragItem?.nanoid || '', distance)"
                />
                <ArrowRightOutlined
                  @click="positonFurnitureIcon('right', clickedDragItem?.nanoid || '', distance)"
                />
                <a-input-number v-model:value.trim="distance" size="small" style="width: 60px" />
              </a-space>
            </div>
          </div>

          <div class="mapConfig-item">
            <div class="mapConfig-item-label">删除家具：</div>
            <div class="mapConfig-item-content">
              <DeleteOutlined @click="deleteFurnitureIcon(clickedDragItem?.nanoid || '')" />
            </div>
          </div>
        </div>
      </div>

      <furnitureCard
        v-if="isEditDraggable"
        v-model:is-edit="isEditDraggable"
        :style="{ marginTop: '30px' }"
        @add="addHnadler"
      ></furnitureCard>
    </div>

    <div class="viewer">
      <div class="viewer-header">
        <div>
          <div class="viewer-header-title">屏蔽子区域配置</div>
          <div class="viewer-header-subtitle">检测范围 {{ areaWidth }} x {{ areaHeight }} cm</div>
        </div>
        <div class="viewer-header-extra">
          <a-space>
            <a-button size="small" @click="createNewBlock">{{
              isCreating ? '创建中...' : '新建区域'
            }}</a-button>
            <a-button type="primary" size="small" @click="saveBlockConfig">保存子区域</a-button>
          </a-space>
        </div>
      </div>

      <div class="viewer-content">
        <div
          class="mapBox blockArea"
          :style="{
            width: `${areaWidth}px`,
            height: `${areaHeight}px`,
            cursor: isCreating ? 'crosshair' : 'default',
          }"
          @mousedown="handleMouseDown"
        >
          <furniture-icon
            v-for="(item, index) in furnitureItems"
            :key="index"
            :icon="item.type"
            :width="item.width"
            :height="item.length"
            :style="{
              left: `${item.left}px`,
              top: `${item.top}px`,
              position: 'absolute',
              transform: `rotate(${item.rotate}deg)`,
              cursor: 'default',
            }"
            :draggable="false"
          />

          <!-- 绘制临时选区 -->
          <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 in blocks"
            :key="block.id"
            class="block-item"
            :style="{
              left: `${block.x}px`,
              top: `${block.y}px`,
              width: `${block.width}px`,
              height: `${block.height}px`,
              border: `2px solid ${block.isActice ? 'yellow' : '#1890ff'}`,
              position: 'absolute',
              cursor: 'move',
            }"
            @mousedown="startDrag(block, $event)"
            @click="selectBlock(block)"
          >
            <div class="resize-handle" @mousedown.stop="startResize(block, $event)"></div>
          </div>
        </div>

        <div v-if="selectedBlock" class="mapConfig">
          <div class="mapConfig-header">子区域属性</div>
          <div class="mapConfig-item">
            <div class="mapConfig-item-label">子区域X范围：</div>
            <div class="mapConfig-item-content">
              <a-space>
                <a-input
                  v-model:value.trim="selectedBlock.startXx"
                  :style="{ width: '50px' }"
                  size="small"
                  @pressEnter="blockInputPressEnter($event, selectedBlock, 'startXx')"
                  @blur="blockInputBlur($event, selectedBlock, 'startXx')"
                />

                <a-input
                  v-model:value.trim="selectedBlock.stopXx"
                  :style="{ width: '50px' }"
                  size="small"
                  @pressEnter="blockInputPressEnter($event, selectedBlock, 'stopXx')"
                  @blur="blockInputBlur($event, selectedBlock, 'stopXx')"
                />
              </a-space>
            </div>
          </div>

          <div class="mapConfig-item">
            <div class="mapConfig-item-label">子区域Y范围：</div>
            <div class="mapConfig-item-content">
              <a-space>
                <a-input
                  v-model:value.trim="selectedBlock.startYy"
                  :style="{ width: '50px' }"
                  size="small"
                  @pressEnter="blockInputPressEnter($event, selectedBlock, 'startYy')"
                  @blur="blockInputBlur($event, selectedBlock, 'startYy')"
                />

                <a-input
                  v-model:value.trim="selectedBlock.stopYy"
                  :style="{ width: '50px' }"
                  size="small"
                  @pressEnter="blockInputPressEnter($event, selectedBlock, 'stopYy')"
                  @blur="blockInputBlur($event, selectedBlock, 'stopYy')"
                />
              </a-space>
            </div>
          </div>

          <div class="mapConfig-item">
            <div class="mapConfig-item-label">子区域Z范围：</div>
            <div class="mapConfig-item-content">
              <a-space>
                <a-input
                  v-model:value.trim="selectedBlock.startZz"
                  :style="{ width: '50px' }"
                  size="small"
                />

                <a-input
                  v-model:value.trim="selectedBlock.stopZz"
                  :style="{ width: '50px' }"
                  size="small"
                />
              </a-space>
            </div>
          </div>

          <div class="mapConfig-item">
            <div class="mapConfig-item-label">子区域区域跟踪：</div>
            <div class="mapConfig-item-content">
              <a-switch v-model:checked="selectedBlock.isTracking" size="small" />
            </div>
          </div>

          <div class="mapConfig-item">
            <div class="mapConfig-item-label">子区域区域跌倒：</div>
            <div class="mapConfig-item-content">
              <a-switch v-model:checked="selectedBlock.isFalling" size="small" />
            </div>
          </div>

          <div class="mapConfig-item">
            <div class="mapConfig-item-label">删除子区域：</div>
            <div class="mapConfig-item-content">
              <DeleteOutlined @click="deleteBlockArea(selectedBlock.id || '')" />
            </div>
          </div>
        </div>
      </div>
    </div>
  </a-spin>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import * as roomApi from '@/api/room'
import type { FurnitureType, Furniture } from '@/api/room/types'
import { message } from 'ant-design-vue'
import { nanoid } from 'nanoid'
import { useDropZone } from '@vueuse/core'
import { furnitureIconNameMap, furnitureIconSizeMap } from '@/const/furniture'
import type { FurnitureIconType } from '@/types/furniture'
import furnitureCard from '../furnitureCard/index.vue'
import {
  RedoOutlined,
  UndoOutlined,
  ArrowUpOutlined,
  ArrowDownOutlined,
  ArrowLeftOutlined,
  ArrowRightOutlined,
  DeleteOutlined,
} from '@ant-design/icons-vue'

defineOptions({
  name: 'deviceAreaConfig',
})

type Props = {
  devId: string // 设备id，用于获取房间布局
  // x,y的范围，用于初始化画布的大小
  length: number
  width: number
}
const emit = defineEmits<{
  (e: 'success', value: void): void
}>()
const props = withDefaults(defineProps<Props>(), {
  devId: '',
  length: 0, // 区域宽度
  width: 0, // 区域高度
})

const deviceRoomId = ref('')
const furnitureItems = ref<Furniture[]>([])

// 检测区域宽度 length
const areaWidth = computed(() => {
  return Math.abs(props.length)
})
// 检测区域高度 width
const areaHeight = computed(() => {
  return Math.abs(props.width)
})

const spinning = ref(false)
// 获取房间布局
const fetchRoomLayout = async () => {
  console.log('fetchRoomLayout', props, props.devId)
  if (!props.devId) {
    message.error('设备ID不能为空')
    return
  }
  try {
    spinning.value = true
    const res = await roomApi.queryRoomInfo({
      devId: props.devId,
    })
    console.log('✅获取到房间布局信息', res)
    if (!res) {
      spinning.value = false
      return
    }
    const { furnitures, roomId, subRegions } = res.data
    deviceRoomId.value = roomId || ''
    if (furnitures) {
      furnitureItems.value = furnitures!.map((item) => {
        // 将接口的家具，添加在家具画布上
        mapCanvasList.value.push({
          name: item.name,
          type: item.type,
          width: item.width,
          height: item.length,
          top: item.top,
          left: item.left,
          x: item.x,
          y: item.y,
          rotate: item.rotate,
          nanoid: nanoid(),
        })
        // 将接口的家具，添加在屏蔽子区域画布上
        return {
          ...item,
          width: item.width || 45,
          length: item.length || 45,
          top: item.top || 0,
          left: item.left || 0,
          rotate: item.rotate || 0,
          x: item.x || 0,
          y: item.y || 0,
        }
      })
    }

    if (subRegions) {
      // 将接口的子区域，添加在子区域画布上
      subRegions.forEach((item) => {
        blocks.value.push({
          // 本地需要使用的数据
          id: nanoid(),
          x: item.startXx + getOriginPosition().originX,
          y: getOriginPosition().originY - item.startYy,
          ox: item.startXx + getOriginPosition().originX - getOriginPosition().originX,
          oy: getOriginPosition().originY - item.startYy - getOriginPosition().originY,
          width: Math.abs(item.stopXx - item.startXx),
          height: Math.abs(item.stopYy - item.startYy),
          isDragging: false,
          isResizing: false,
          isActice: false,
          isTracking: Boolean(item.trackPresence),
          isFalling: Boolean(item.excludeFalling),
          // 来自接口回显的数据
          startXx: item.startXx,
          stopXx: item.stopXx,
          startYy: item.startYy,
          stopYy: item.stopYy,
          startZz: 0,
          stopZz: 0,
          isLowSnr: 0,
          isDoor: 0,
          presenceEnterDuration: 3,
          presenceExitDuration: 3,
          trackPresence: item.trackPresence,
          excludeFalling: item.excludeFalling,
        })
      })
    }
    spinning.value = false
  } catch (error) {
    console.error('❌获取房间布局信息失败', error)
    spinning.value = false
  }
}
fetchRoomLayout().finally(() => {
  // 获取房间信息后，初始化雷达图标
  initRadarIcon()
})

interface CanvaseItem {
  name: string // 名称
  type: string // 类型，图标icon
  width: number // 家具宽度
  height: number // 家具长度
  top: number // 距离检测范围上方位置 cm
  left: number // 	距离检测范围左边位置 cm
  rotate: number // 旋转角度： 0°,90°,180°,270°
  x?: number // 距离雷达的X距离
  y?: number // 距离雷达的Y距离
  nanoid?: string // 本地使用
  isActice?: boolean // 是否选中 本地使用
  isDragging?: boolean // 是否拖拽 本地使用
}

// 画布上的家具列表
const mapCanvasList = ref<CanvaseItem[]>([])
const isEditDraggable = ref(false)
// 家具列表添加
const addHnadler = (icon: FurnitureIconType) => {
  console.log('addHnadler', icon)
  const { originOffsetX, originOffsetY } = getOriginPosition()
  // 家具原始宽高
  const originWidth = furnitureIconSizeMap[icon].width || 30
  const originHeight = furnitureIconSizeMap[icon].height || 30
  mapCanvasList.value.push({
    name: furnitureIconNameMap[icon],
    type: icon,
    width: originWidth,
    height: originHeight,
    top: 0,
    left: 0,
    rotate: 0,
    x: originOffsetX,
    y: originOffsetY,
    nanoid: nanoid(),
    isActice: false,
  })
  message.success('已添加')
}

const contentEl = ref<HTMLElement>()
const currentDragItem = ref<CanvaseItem | null>(null)
// 内容区域放置处理
useDropZone(contentEl, {
  onDrop(files: File[] | null, event: DragEvent) {
    if (contentEl.value && currentDragItem.value) {
      const rect = contentEl.value.getBoundingClientRect()
      // 计算基于画布容器的精确坐标
      const x = event.clientX - rect.left
      const y = event.clientY - rect.top
      // 中心点对齐计算
      currentDragItem.value.top = y - currentDragItem.value.height / 2
      currentDragItem.value.left = x - currentDragItem.value.width / 2
      // 添加边界检查
      // const maxX = contentEl.value.offsetWidth - currentDragItem.value.width
      // const maxY = contentEl.value.offsetHeight - currentDragItem.value.height
      // currentDragItem.value.left = Math.max(0, Math.min(x - currentDragItem.value.width / 2, maxX))
      // currentDragItem.value.top = Math.max(0, Math.min(y - currentDragItem.value.height / 2, maxY))
    }
  },
})

// 家具列表元素开始拖拽
const onDragstartListItem = (event: DragEvent, item: CanvaseItem) => {
  console.log('🔥onDragstartListItem', event, item)
  currentDragItem.value = item
  item.isDragging = true

  // 创建拖拽镜像
  const target = event.currentTarget as HTMLElement
  const clone = target.cloneNode(true) as HTMLElement
  const rect = target.getBoundingClientRect()
  // 获取实际渲染样式
  const computedStyle = window.getComputedStyle(target)
  // 复制所有关键样式
  clone.style.cssText = `
    position: fixed;
    left: -9999px;
    opacity: 0.5;
    pointer-events: none;
    width: ${rect.width}px;
    height: ${rect.height}px;
    transform: ${computedStyle.transform || `rotate(${item.rotate}deg)`};
    transform-origin: ${computedStyle.transformOrigin || 'center center'};
    border: ${computedStyle.border};
    box-shadow: ${computedStyle.boxShadow};
    background: ${computedStyle.background};
  `
  console.log('克隆元素尺寸:', clone.style.cssText)
  document.body.appendChild(clone)
  // 计算中心点偏移量
  const offsetX = rect.width / 2 // 水平中心偏移
  const offsetY = rect.height / 2 // 垂直中心偏移
  // 设置拖拽镜像和偏移量
  event.dataTransfer?.setDragImage(clone, offsetX, offsetY)
  // 隐藏原元素
  target.style.opacity = '0'
}

// 家具列表元素结束拖拽
const onDragendEndListItem = (event: DragEvent, item: CanvaseItem) => {
  item.isDragging = false
  const { originOffsetX, originOffsetY } = getOriginPosition()
  if (currentDragItem.value) {
    currentDragItem.value.x = originOffsetX
    currentDragItem.value.y = originOffsetY
    currentDragItem.value.isDragging = false
  }
  requestAnimationFrame(() => {
    item.isActice = true
    clickedDragItem.value = item
  })
  console.log('🔥onDragendEndListItem', event, item, {
    x: currentDragItem.value?.x,
    y: currentDragItem.value?.y,
  })
  if (event.currentTarget) {
    ;(event.currentTarget as HTMLElement).style.opacity = '1'
  }
}

const clickedDragItem = ref<CanvaseItem | null>()
const onClickMapItem = (event: MouseEvent, item: CanvaseItem) => {
  if (!isEditDraggable.value || item.type === 'radar' || item.isDragging) return
  console.log('onClickMapItem', event, item)
  item.isActice = true
  clickedDragItem.value = item
}

const handleMouseDownMapCanvas = () => {
  mapCanvasList.value.forEach((item) => {
    item.isActice = false
  })
  clickedDragItem.value = null
}

// 家具旋转
const rotateFurnitureIcon = (type: number, nanoid: string) => {
  console.log('rotateFurnitureIcon', type, nanoid, mapCanvasList.value)
  const rotateMap = [0, 90, 180, 270]

  if (nanoid) {
    mapCanvasList.value.forEach((item) => {
      if (item.nanoid === nanoid) {
        // 获取当前角度在rotateMap中的索引
        const currentIndex = rotateMap.indexOf(item.rotate)

        if (type === 1) {
          // 逆时针（索引递减）
          const newIndex = (currentIndex - 1 + rotateMap.length) % rotateMap.length
          item.rotate = rotateMap[newIndex]
        } else if (type === 2) {
          // 顺时针（索引递增）
          const newIndex = (currentIndex + 1) % rotateMap.length
          item.rotate = rotateMap[newIndex]
        }
      }
    })
  }
}

// 微调距离
const distance = ref(5)
// 家具位置微调
const positonFurnitureIcon = (type: string, nanoid: string, distance: number) => {
  console.log('positonFurnitureIcon', type, nanoid, mapCanvasList.value)
  if (nanoid) {
    mapCanvasList.value.forEach((item) => {
      if (item.nanoid === nanoid) {
        if (type === 'up') {
          item.top -= distance
        }
        if (type === 'down') {
          item.top += distance
        }
        if (type === 'left') {
          item.left -= distance
        }
        if (type === 'right') {
          item.left += distance
        }
      }
    })
  }
}

// 删除家具
const deleteFurnitureIcon = (nanoid: string) => {
  console.log('deleteFurnitureIcon', clickedDragItem.value)
  if (nanoid) {
    mapCanvasList.value = mapCanvasList.value.filter((item) => item.nanoid !== nanoid)
    clickedDragItem.value = null
  }
}

// 新增区块类型
interface BlockItem {
  // 本地用
  id: string // 唯一标识
  x: number // 区块基于父元素的X偏移量，区块的左上角x坐标
  y: number // 区块基于父元素的Y偏移量，区块的左上角y坐标
  ox: number // 区块基于原点的X偏移量，区块的左上角x坐标
  oy: number // 区块基于原点的Y偏移量，区块的左上角y坐标
  width: number // 区块宽度
  height: number // 区块高度
  isDragging: boolean // 是否正在拖动
  isResizing: boolean // 是否正在调整大小
  isActice: boolean // 是否选中
  isTracking: boolean // 是否开启区域跟踪  0-否,1-是
  isFalling: boolean // 是否屏蔽区域跌倒检测  0-否,1-是
  // 接口用
  startXx: number // 屏蔽子区域X开始
  stopXx: number // 屏蔽子区域X结束
  startYy: number // 屏蔽子区域Y开始
  stopYy: number // 屏蔽子区域Y结束
  startZz: number // 屏蔽子区域Z开始
  stopZz: number // 屏蔽子区域Z结束
  isLowSnr: number // 默认0
  isDoor: number // 是否是门 0-否,1-是 默认0
  presenceEnterDuration: number // 	人员进入时间 默认3
  presenceExitDuration: number // 人员离开时间 默认3
  trackPresence: number // 是否开启区域跟踪存在 0-否,1-是
  excludeFalling: number // 是否屏蔽区域跌倒检测 0-否,1-是
}

const blocks = ref<BlockItem[]>([])
const isCreating = ref(false)
const currentBlock = ref<{
  startX: number
  startY: number
  currentX: number
  currentY: number
} | null>(null)
const selectedBlock = ref<BlockItem | null>(null)

// 新建区块处理
const createNewBlock = () => {
  if (blocks.value && blocks.value.length > 5) {
    message.warn('最多只能创建6个区块')
    return
  }
  isCreating.value = true
}

// 获取容器边界
const getContainerRect = () => {
  const container = document.querySelector('.blockArea') as HTMLElement
  return container?.getBoundingClientRect() || { left: 0, top: 0 }
}

// 鼠标事件处理
const handleMouseDown = (e: MouseEvent) => {
  console.log('handleMouseDown', e)
  blocks.value.forEach((item) => {
    item.isActice = false
  })
  selectedBlock.value = null
  if (!isCreating.value) return

  const rect = getContainerRect()
  const startX = e.clientX - rect.left
  const startY = e.clientY - rect.top

  currentBlock.value = {
    startX,
    startY,
    currentX: startX,
    currentY: startY,
  }

  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', handleMouseUp)
}

// 鼠标移动处理
const handleMouseMove = (e: MouseEvent) => {
  if (!currentBlock.value) return

  const rect = getContainerRect()
  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 handleMouseUp = () => {
  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) {
    blocks.value.push({
      // 本地用
      id: nanoid(),
      x: Math.round(Math.min(startX, currentX)),
      y: Math.round(Math.min(startY, currentY)),
      ox: Math.round(Math.min(startX, currentX)) - getOriginPosition().originX,
      oy: Math.round(Math.min(startY, currentY)) - getOriginPosition().originY,
      width,
      height,
      isDragging: false,
      isResizing: false,
      isActice: false,
      isTracking: false,
      isFalling: false,
      // 接口用
      startXx: Math.round(Math.min(startX, currentX)) - getOriginPosition().originX,
      stopXx: Math.round(Math.min(startX, currentX)) - getOriginPosition().originX + width,
      startYy: Math.round(Math.min(startY, currentY)) - getOriginPosition().originY,
      stopYy: Math.round(Math.min(startY, currentY)) - getOriginPosition().originY + height,
      startZz: 0,
      stopZz: 0,
      isLowSnr: 0,
      isDoor: 0,
      presenceEnterDuration: 3,
      presenceExitDuration: 3,
      trackPresence: 0,
      excludeFalling: 0,
    })
  }

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

// 区块拖动
const startDrag = (block: BlockItem, e: MouseEvent) => {
  console.log('startDrag', block)
  e.stopPropagation()
  block.isDragging = true
  block.isActice = true
  const container = document.querySelector('.blockArea') as HTMLElement
  const rect = container.getBoundingClientRect()
  const offsetX = e.clientX - rect.left - block.x
  const offsetY = e.clientY - rect.top - block.y

  const moveHandler = (e: MouseEvent) => {
    const newX = e.clientX - rect.left - offsetX
    const newY = e.clientY - rect.top - offsetY
    const containerWidth = container.offsetWidth
    const containerHeight = container.offsetHeight

    block.x = Math.max(0, Math.min(newX, containerWidth - block.width))
    block.y = Math.max(0, Math.min(newY, containerHeight - block.height))
    block.ox = block.x - getOriginPosition().originX
    block.oy = getOriginPosition().originY - block.y
    block.startXx = block.ox
    block.stopXx = block.ox + block.width
    block.startYy = block.oy
    block.stopYy = block.oy - block.height
  }

  const upHandler = () => {
    block.isDragging = false
    block.isActice = false
    document.removeEventListener('mousemove', moveHandler)
    document.removeEventListener('mouseup', upHandler)
  }

  document.addEventListener('mousemove', moveHandler)
  document.addEventListener('mouseup', upHandler)
}

const selectBlock = (block: BlockItem) => {
  console.log('selectBlock', block)
  selectedBlock.value = block
  blocks.value.forEach((item) => {
    item.isActice = item === block
  })
}

// 保存子区域配置
const saveBlockConfig = () => {
  const blockData = blocks.value.map((item) => {
    return {
      startXx: item.startXx,
      stopXx: item.stopXx,
      startYy: item.startYy,
      stopYy: item.stopYy,
      startZz: Number(item.startZz) || 0,
      stopZz: Number(item.stopZz) || 0,
      isLowSnr: item.isLowSnr,
      isDoor: item.isDoor,
      presenceEnterDuration: item.presenceEnterDuration,
      presenceExitDuration: item.presenceExitDuration,
      trackPresence: Number(item.isTracking),
      excludeFalling: Number(item.isFalling),
    }
  })
  console.log('当前所有区块配置:', blockData)
  try {
    const res = roomApi.saveRoomInfo({
      roomId: deviceRoomId.value,
      devId: props.devId,
      subRegions: blockData,
    })
    console.log('saveBlockConfig 保存成功', res)
    message.success('保存成功')
    emit('success')
  } catch (error) {
    console.error('saveBlockConfig 保存失败', error)
  }
}

/**
 * 获取坐标位置
 * @returns
 * * width: 容器宽度
 * * heigt: 容器高度
 * * originX: 原点X坐标
 * * originY: 原点Y坐标
 * * offsetX: 元素基于父容器的偏移量 X坐标
 * * offsetY: 元素基于父容器的偏移量 Y坐标
 * * originOffsetX: 元素基于原点的偏移量 X坐标
 * * originOffsetY: 元素基于原点的偏移量 Y坐标
 * * radarX: 雷达X坐标
 * * radarY: 雷达Y坐标
 */
const getOriginPosition = () => {
  // 地图尺寸
  const containerWidth = areaWidth.value
  const containerHeight = areaHeight.value

  // 地图原点坐标
  const originX = containerWidth / 2
  const originY = containerHeight / 2

  // 元素基于父容器的偏移量
  const offsetX = (currentDragItem.value && currentDragItem.value?.left) || 0
  const offsetY = (currentDragItem.value && currentDragItem.value?.top) || 0

  // 元素基于原点的偏移量
  const originOffsetX = offsetX - originX
  const originOffsetY = originY - offsetY

  // 雷达尺寸
  const radarWidth = furnitureIconSizeMap['radar']?.width || 0
  const radarHeight = furnitureIconSizeMap['radar']?.height || 0

  // 雷达基于原点的偏移量
  const radarX = Math.round(originX - radarWidth / 2)
  const radarY = Math.round(originY - radarHeight / 2)

  const data = {
    width: containerWidth,
    height: containerHeight,
    originX: Math.round(originX),
    originY: Math.round(originY),
    offsetX: Math.round(offsetX),
    offsetY: Math.round(offsetY),
    originOffsetX: Math.round(originOffsetX),
    originOffsetY: Math.round(originOffsetY),
    radarX,
    radarY,
    radarWidth,
    radarHeight,
  }
  console.log('getOriginPosition', data)

  return data
}

// 初始化添加雷达图标
const initRadarIcon = () => {
  console.log('initRadarIcon', mapCanvasList.value, furnitureItems.value)
  const { radarX, radarY, originOffsetX, originOffsetY } = getOriginPosition()
  // 在家具地图添加雷达图标
  mapCanvasList.value.push({
    name: '雷达',
    type: 'radar',
    width: furnitureIconSizeMap['radar'].width,
    height: furnitureIconSizeMap['radar'].height,
    top: radarY,
    left: radarX,
    x: originOffsetX,
    y: originOffsetY,
    rotate: 0,
    nanoid: nanoid(),
  })
  // 在屏蔽子区域添加雷达图标
  furnitureItems.value.push({
    name: '雷达',
    type: 'radar',
    width: furnitureIconSizeMap['radar'].width,
    length: furnitureIconSizeMap['radar'].height,
    top: radarY,
    left: radarX,
    x: originOffsetX,
    y: originOffsetY,
    rotate: 0,
  })
}

// 保存家具配置
const saveFurnitureMapConfig = () => {
  console.log('saveFurnitureMapConfig', mapCanvasList.value)
  try {
    const res = roomApi.saveRoomInfo({
      roomId: deviceRoomId.value,
      devId: props.devId,
      furnitures: mapCanvasList.value
        .filter((item) => item.type !== 'radar')
        .map((item) => {
          return {
            name: item.name,
            type: item.type as FurnitureType,
            width: item.width,
            length: item.height,
            top: item.top,
            left: item.left,
            rotate: item.rotate as 0 | 90 | 180 | 270,
            x: item?.x || 0,
            y: item?.y || 0,
          }
        }),
    })
    console.log('保存家具配置 成功', res)
    message.success('保存成功')
    emit('success')
  } catch (error) {
    console.error('保存家具配置 失败', error)
  }
}

const startResize = (block: BlockItem, e: MouseEvent) => {
  block.isResizing = true
  selectedBlock.value = block
  const startX = e.clientX
  const startY = e.clientY
  const initialWidth = block.width
  const initialHeight = block.height

  const moveHandler = (e: MouseEvent) => {
    const rect = getContainerRect()
    const deltaX = e.clientX - startX
    const deltaY = e.clientY - startY
    // 限制最小尺寸和容器边界
    block.width = Math.max(50, Math.min(initialWidth + deltaX, rect.width - block.x))
    block.height = Math.max(50, Math.min(initialHeight + deltaY, rect.height - block.y))

    // 改变了区块的长款，元素的结束位置也相应变化
    block.stopXx = block.ox + block.width
    block.stopYy = block.oy + block.height
  }

  const upHandler = () => {
    block.isResizing = false
    selectedBlock.value = null
    document.removeEventListener('mousemove', moveHandler)
    document.removeEventListener('mouseup', upHandler)
  }

  document.addEventListener('mousemove', moveHandler)
  document.addEventListener('mouseup', upHandler)
}

const blockInputPressEnter = (e: Event, el: BlockItem, attr: string) => {
  if (attr === 'startXx') {
    el.startXx = Number(el[attr as keyof BlockItem])
    el.x = el.startXx + getOriginPosition().originX
  }
  if (attr === 'stopXx') {
    el.stopXx = Number(el[attr as keyof BlockItem])
    el.width = el.stopXx + getOriginPosition().originX - el.width
  }

  if (attr === 'startYy') {
    el.startYy = Number(el[attr as keyof BlockItem])
    el.x = el.startYy + getOriginPosition().originY
  }
  if (attr === 'stopYy') {
    el.stopYy = Number(el[attr as keyof BlockItem])
    el.height = el.stopYy + getOriginPosition().originY - el.height
  }
}

const blockInputBlur = (e: Event, el: BlockItem, attr: string) => {
  console.log('blockInputBlur', e, el, attr)
  if (attr === 'startXx') {
    el.startXx = Number(el[attr as keyof BlockItem])
    el.x = el.startXx + getOriginPosition().originX
  }
  if (attr === 'stopXx') {
    el.stopXx = Number(el[attr as keyof BlockItem])
    el.width = el.stopXx + getOriginPosition().originX - el.width
  }

  if (attr === 'startYy') {
    el.startYy = Number(el[attr as keyof BlockItem])
    el.x = el.startYy + getOriginPosition().originY
  }
  if (attr === 'stopYy') {
    el.stopYy = Number(el[attr as keyof BlockItem])
    el.height = el.stopYy + getOriginPosition().originY - el.height
  }
}

const deleteBlockArea = (id: string) => {
  if (id) {
    blocks.value = blocks.value.filter((item) => item.id !== id)
    selectedBlock.value = null
  }
}
</script>

<style scoped lang="less">
.viewer {
  padding: 10px;
  min-width: 500px;
  flex-shrink: 0;
  margin-top: 10px;

  &-header {
    display: flex;
    justify-content: space-between;
    padding-bottom: 20px;

    &-title {
      font-size: 16px;
      font-weight: 600;
      line-height: 24px;
    }
    &-subtitle {
      font-size: 14px;
      color: #666;
    }
  }

  &-content {
    display: flex;
    gap: 20px;
  }
}

.mapBox {
  background-color: #e0e0e0;
  background-image:
    linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),
    linear-gradient(to right, rgba(0, 0, 0, 0.1) 1px, transparent 1px);
  background-size: 20px 20px;
  position: relative;
  flex-shrink: 0;

  // 添加黑边框
  &::before {
    content: '';
    position: absolute;
    top: -5px;
    left: -5px;
    width: calc(100% + 10px);
    height: calc(100% + 10px);
    border: 5px solid rgba(0, 0, 0, 0.8);
    box-sizing: border-box;
    pointer-events: none;
  }
}

.mapConfig {
  background-color: #f5f5f5;
  border-radius: 10px;
  padding: 12px;
  &-header {
    font-size: 14px;
    margin-bottom: 10px;
    font-weight: 600;
  }

  &-item {
    display: flex;
    line-height: 30px;
    &-label {
      color: #888;
      min-width: 80px;
    }
    &-content {
      color: #555;
      min-width: 100px;
    }
  }
}

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

.block-item {
  background: rgba(24, 144, 255, 0.1);

  .resize-handle {
    position: absolute;
    right: -4px;
    bottom: -4px;
    width: 8px;
    height: 8px;
    background: #1890ff;
    cursor: nwse-resize;
  }
}

.dragging-item {
  opacity: 0.5;
  transition: opacity 0.2s ease;
}
</style>
