<template>
  <div ref="mod">
    <a-modal
      :get-container="() => $refs.mod"
      :open="props.open"
      :title="props.title"
      :mask-closable="false"
      width="600px"
      @cancel="cancel"
      :footer="null"
    >
      <a-form
        ref="formRef"
        :model="formState"
        :label-col="{ style: { width: '80px' } }"
        hideRequiredMark
      >
        <a-form-item v-if="props.type === 'plan'" label="计划模板">
          <div style="display: flex; align-items: center; gap: 8px">
            <a-select
              v-model:value="planTemplateId"
              show-search
              placeholder="选择内置模板填充内容"
              :filter-option="false"
              :not-found-content="null"
              :options="planTemplateOptions"
              @search="handleSearch"
              @change="handleChange"
            ></a-select>

            <a-popconfirm
              title="应用模板会覆盖内容，确认吗？"
              ok-text="确认"
              cancel-text="取消"
              :disabled="!planTemplateId"
              @confirm="useTemplateAdd"
            >
              <a-button size="small" type="link" :disabled="!planTemplateId">应用</a-button>
            </a-popconfirm>
          </div>
        </a-form-item>

        <a-form-item
          label="计划名称"
          name="planName"
          :rules="[{ required: true, message: '请输入计划名称' }]"
        >
          <a-input
            v-model:value.trim="formState.planName"
            placeholder="请输入计划名称"
            :maxlength="20"
            show-count
            allow-clear
          />
        </a-form-item>

        <a-form-item
          label="计划备注"
          name="remark"
          :rules="[{ required: true, message: '请输入计划备注' }]"
        >
          <a-input
            v-model:value.trim="formState.remark"
            placeholder="请输入备注"
            :maxlength="200"
            show-count
            allow-clear
          />
        </a-form-item>

        <a-form-item
          label="触发阈值"
          name="thresholdTime"
          :rules="[{ required: true, message: '请输入触发阈值' }]"
        >
          <a-input-number
            v-model:value.trim="formState.thresholdTime"
            placeholder="请输入(默认300，需要大于0)"
            min="0"
            show-count
            allow-clear
            style="width: 100%"
          >
            <template #addonAfter>
              <a-select v-model:value="thresholdTimeFormat" style="width: 80px">
                <a-select-option value="s">秒</a-select-option>
                <a-select-option value="min">分钟</a-select-option>
                <a-select-option value="hour">小时</a-select-option>
                <a-select-option value="day">天</a-select-option>
              </a-select>
            </template>
          </a-input-number>
        </a-form-item>

        <a-form-item
          label="归并时间"
          name="mergeTime"
          :rules="[{ required: true, message: '请输入归并时间' }]"
        >
          <a-input-number
            v-model:value.trim="formState.mergeTime"
            placeholder="请输入(默认30，需要大于0)"
            min="0"
            show-count
            allow-clear
            style="width: 100%"
          />
        </a-form-item>

        <a-form-item
          label="事件类型"
          name="eventType"
          :rules="[{ required: true, message: '请选择事件类型' }]"
        >
          <a-select
            v-model:value="formState.eventType"
            :options="eventTypeList"
            placeholder="请选择事件类型"
            @change="eventTypeChange"
          />

          <a-form-item-rest v-if="formState.eventType && ![1, 2, 3].includes(formState.eventType)">
            <div class="eventTypeBox">
              <div v-if="[4, 5, 6, 7, 8].includes(formState.eventType)" class="eventTypeBox-item">
                <span class="eventTypeBox-item-label">统计时间:</span>
                <a-form-item
                  name="statisticsTime"
                  :rules="[{ required: true, message: '请选择统计时间' }]"
                >
                  <a-form-item-rest>
                    <a-space>
                      <a-time-picker
                        v-model:value="formState.statisticsTime[0]"
                        valueFormat="HH:mm"
                        format="HH:mm"
                        placeholder="开始时间"
                        style="width: 100px"
                      />
                      <div> - </div>
                      <a-time-picker
                        v-model:value="formState.statisticsTime[1]"
                        valueFormat="HH:mm"
                        format="HH:mm"
                        placeholder="结束时间"
                        style="width: 100px"
                      />
                    </a-space>
                  </a-form-item-rest>
                </a-form-item>
              </div>

              <div v-if="[6, 7].includes(formState.eventType)" class="eventTypeBox-item">
                <span class="eventTypeBox-item-label">异常阈值:</span>
                <a-form-item name="count" :rules="[{ required: true, message: '请输入异常阈值' }]">
                  <a-input-number
                    v-model:value.trim="formState.count"
                    placeholder="请输入(默认3，需要大于0)"
                    min="0"
                    show-count
                    allow-clear
                    style="width: 100%"
                  />
                </a-form-item>
              </div>

              <div v-if="formState.eventType === 9" class="eventTypeBox-item">
                <span class="eventTypeBox-item-labelend">异常消失时间阈值:</span>
                <a-form-item
                  name="timeThreshold"
                  :rules="[{ required: true, message: '请输入异常消失时间阈值' }]"
                >
                  <a-input-number
                    v-model:value.trim="formState.timeThreshold"
                    placeholder="请输入(默认300，需要大于0)"
                    min="0"
                    show-count
                    allow-clear
                    style="width: 100%"
                  >
                    <template #addonAfter>
                      <a-select v-model:value="timeThresholdFormat" style="width: 80px">
                        <a-select-option value="s">秒</a-select-option>
                        <a-select-option value="min">分钟</a-select-option>
                        <a-select-option value="hour">小时</a-select-option>
                        <a-select-option value="day">天</a-select-option>
                      </a-select>
                    </template>
                  </a-input-number>
                </a-form-item>
              </div>
            </div>
          </a-form-item-rest>
        </a-form-item>

        <a-form-item
          label="计划时间"
          name="planTime"
          :rules="[{ type: 'array' as const, required: true, message: '请选择计划时间' }]"
        >
          <a-range-picker
            v-model:value="formState.planTime"
            style="width: 100%"
            :show-time="false"
            valueFormat="YYYY-MM-DD"
          />
        </a-form-item>

        <a-form-item v-if="![4, 5, 6, 8].includes(formState.eventType!)" label="生效时段">
          <div style="display: flex; align-items: center; gap: 8px">
            <a-time-range-picker
              v-model:value="formState.effectTimeFrame"
              valueFormat="HH:mm"
              format="HH:mm"
              style="width: 100%"
              :disabled="[4, 6, 8].includes(formState.eventType!)"
            />
            <a-button
              size="small"
              type="link"
              :disabled="[4, 6, 8].includes(formState.eventType!)"
              @click="addEffectTime"
              >添加</a-button
            >
          </div>
          <div style="margin-top: 12px">
            <span
              v-if="formState.effectTimeFrames && !formState.effectTimeFrames.length"
              style="color: #aaa; font-size: 14px"
              >⚠️暂无生效时段</span
            >
            <a-space wrap v-else>
              <a-tag
                v-for="(item, index) in formState.effectTimeFrames"
                :key="index"
                closable
                style="font-size: 14px; padding: 4px 10px"
                @close="deleteEffectTimeItem($event, index)"
                >{{ item.startTime }} - {{ item.endTime }}</a-tag
              >
            </a-space>
          </div>
        </a-form-item>

        <a-form-item label="生效方式">
          <a-form-item-rest>
            <a-radio-group
              v-model:value="formState.effectType"
              name="radioGroup"
              @change="effectTypeChange"
            >
              <a-radio value="week">按周</a-radio>
              <a-radio value="month">按月</a-radio>
            </a-radio-group>
            <a-checkbox
              v-model:checked="checkState.checkAll"
              :indeterminate="checkState.indeterminate"
              @change="onCheckAllChange"
            >
              全选
            </a-checkbox>
            <a-checkbox-group v-model:value="formState.effectTimeRanges" :options="plainOptions" />
          </a-form-item-rest>
        </a-form-item>

        <a-form-item
          v-if="props.type === 'plan' && [1, 2, 3, 9].includes(formState?.eventType as number)"
          label="检测区域"
          name="region"
          style="user-select: none"
        >
          <a-alert
            v-if="areaAvailable"
            message="检测区域范围未配置或数值较小，请在设备配置调整参数！"
            banner
            style="margin-bottom: 10px"
          />
          <div> 雷达检测区域：{{ props.area!.ranges }} </div>
          <div style="user-select: none">
            <span>告警框选区域： {{ formState.region }}</span>
            <a-button type="link" style="margin-left: 16px" @click="resetBlocks"> 重置 </a-button>
          </div>
          <a-form-item-rest>
            <baseAreaViewer
              :width="areaWidth"
              :length="areaHeight"
              :furnitureItems="furnitureItems"
              :ranges="props?.area?.ranges ?? []"
              class="blockArea"
            >
              <div
                v-for="(block, blockIndex) in blocks"
                :key="blockIndex"
                class="block-item"
                :style="{
                  left: `${block.x}px`,
                  top: `${block.y}px`,
                  width: `${block.width}px`,
                  height: `${block.height}px`,
                  border: `2px solid #1890ff`,
                  position: 'absolute',
                  cursor: 'move',
                  backgroundColor: 'rgba(24, 144, 255, 0.1)',
                }"
                @mousedown="startDrag(block, $event)"
              >
                <div
                  class="resize-handle"
                  :style="{
                    backgroundColor: '#1890ff',
                  }"
                  @mousedown.stop="startResize(block, $event)"
                >
                </div>
              </div>
            </baseAreaViewer>
          </a-form-item-rest>
        </a-form-item>

        <a-form-item label="告警联动">
          <a-checkbox v-model:checked="formState.linkagePushWechatService">
            微信服务号推送
          </a-checkbox>
        </a-form-item>

        <a-form-item label="是否启用">
          <a-switch v-model:checked="formState.enable" />
        </a-form-item>
      </a-form>

      <div class="footer">
        <a-space>
          <a-button @click="cancel">取消</a-button>
          <a-button type="primary" :loading="submitLoading" @click="submit">保存</a-button>
        </a-space>
      </div>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, watch, computed, nextTick } from 'vue'
import { message, type FormInstance, type SelectProps } from 'ant-design-vue'
import * as alarmApi from '@/api/alarm'
import { getOriginPosition } from '@/utils/index'
import type { AlarmPlanParams } from '@/api/alarm/types'
import dayjs from 'dayjs'
import { debounce } from 'lodash-es'
import * as roomApi from '@/api/room'
import type { Furniture } from '@/api/room/types'

defineOptions({
  name: 'AlarmPlanModal',
})

const formRef = ref<FormInstance>()

type AlarmPlan = {
  id: number
  uuid: ID
  name: string
  clientId: string
  enable: SwitchType
  region: string
  eventVal: number
  alarmTimePlanId: ID
  thresholdTime: ID
  mergeTime: ID
  param: string
  createTime: string
  updateTime: string
  remark: string | null
  alarmTimePlan: {
    createId: ID
    updateId: ID
    createTime: ID
    updateTime: ID
    isDeleted: SwitchType | null
    remark: ID
    id: ID
    startDate: string
    stopDate: string
    timeRange: string
    monthDays: string
    weekdays: string
  }
}

type Props = {
  open: boolean
  type?: 'plan' | 'template'
  title?: string
  clientId?: string // 设备ID
  alarmPlanId?: number | null // 告警计划ID 编辑时传入
  data?: AlarmPlan // 编辑数据
  area?: {
    width: number
    length: number
    ranges: number[]
  }
  devId?: string // 设备ID
}
const emit = defineEmits<{
  (e: 'update:open', value: boolean): void
  (e: 'success', value: void): void
}>()

const props = withDefaults(defineProps<Props>(), {
  open: false,
  type: 'plan',
  title: '告警计划',
  clientId: '',
  alarmPlanId: null,
  data: undefined,
})

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

// 获取原点坐标
const { originOffsetX, originOffsetY } = getOriginPosition(props.area!.ranges, [0, 0])

interface BlockItem {
  // 本地用
  x: number // 区块基于父元素的X偏移量，区块的左上角x坐标
  y: number // 区块基于父元素的Y偏移量，区块的左上角y坐标
  ox: number // 区块基于原点的X偏移量，区块的左上角x坐标
  oy: number // 区块基于原点的Y偏移量，区块的左上角y坐标
  width: number // 区块宽度
  height: number // 区块高度
}

const blocks = ref<BlockItem[]>([])

// 区块拖动
const startDrag = (block: BlockItem, e: MouseEvent) => {
  const { originX, originY } = getOriginPosition(props.area!.ranges, [0, 0])

  e.stopPropagation()
  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 - originX
    block.oy = originY - block.y
    // block.ox = block.x - originOffsetX
    // block.oy = originOffsetY - block.y
    formState.region = [block.ox, block.oy, block.width, block.height]
  }

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

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

// const drag = (block: BlockItem) => {
//   formState.region = [block.ox, block.oy, block.width, block.height]
// }

// const endDrag = (block: BlockItem) => {
//   formState.region = [block.ox, block.oy, block.width, block.height]
// }

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

const startResize = (block: BlockItem, e: MouseEvent) => {
  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(0, Math.min(initialWidth + deltaX, rect.width - block.x))
    block.height = Math.max(0, Math.min(initialHeight + deltaY, rect.height - block.y))
    formState.region = [block.ox, block.oy, block.width, block.height]
  }

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

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

const weekOptions = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
const monthOptions = [
  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
  28, 29, 30, 31,
]

type FormState = {
  planName: string // 计划名称
  region: number[] // 检测区域 [left, top, width, height]
  eventType: number | null // 事件类型
  thresholdTime: number | null // 触发阈值
  mergeTime: number | null // 归并时间
  planTime: string[] // 计划时间
  effectType: 'week' | 'month' // 生效方式 周week、月month
  effectTimeRanges: (number | string)[] // 生效范围 周 1-7、月 1-31
  effectTimeFrame: string[] // 生效时段 单条 00:00:00 - 23:59:59
  effectTimeFrames: { startTime: string; endTime: string }[] // 生效时段 多条
  enable: boolean // 是否启用
  linkagePushWechatService: boolean // 是否开启服务号消息推送
  statisticsTime: string[] // 统计时间
  count?: number | null // 异常阈值
  timeThreshold?: number | null // 异常消失时间阈值(单位：秒)
  remark?: string // 备注
}

const formState = reactive<FormState>({
  planName: '',
  region: [originOffsetX, originOffsetY, 50, 50],
  eventType: null,
  thresholdTime: 300,
  mergeTime: 30,
  planTime: [],
  effectType: 'week',
  effectTimeRanges: weekOptions,
  effectTimeFrame: [],
  effectTimeFrames: [],
  enable: true,
  linkagePushWechatService: true,
  statisticsTime: [],
  count: 3,
  timeThreshold: 300,
})

const planTemplateId = ref<number | null>()
const planTemplate = ref<AlarmPlan>()

const planTemplateOptions = ref<SelectProps['options']>([])

// 获取列表
const fetchTemplateList = debounce(async (val: string = '') => {
  try {
    await alarmApi
      .getAlarmPlanTemplateList({
        pageNo: 1,
        pageSize: 30,
        name: val,
      })
      .then((res) => {
        console.log('获取告警计划模板成功✅', res)
        const { rows } = res.data
        try {
          planTemplateOptions.value =
            (Array.isArray(rows) &&
              rows.map((item) => ({
                label: item.name,
                value: item.id,
                data: {
                  ...item,
                  alarmTimePlan: item.alarmTimePlanTpl,
                },
              }))) ||
            []
        } catch (err) {
          console.log('获取告警计划模板失败❌', err)
        }
      })
      .catch((err) => {
        console.log('获取告警计划模板失败❌', err)
      })
  } catch (err) {
    console.log('获取告警计划列表失败❌', err)
  }
}, 1000)

const useTemplateAdd = () => {
  console.log('useTemplateAdd', planTemplate.value)
  const val = planTemplate.value as SourceData
  formState.planName = echoFormState(val).planName
  formState.remark = echoFormState(val).remark
  formState.thresholdTime = echoFormState(val).thresholdTime
  formState.mergeTime = echoFormState(val).mergeTime
  formState.eventType = echoFormState(val).eventType
  formState.statisticsTime = echoFormState(val).statisticsTime
  formState.count = echoFormState(val).count
  formState.timeThreshold = echoFormState(val).timeThreshold
  formState.planTime = echoFormState(val).planTime
  formState.effectType = echoFormState(val).effectType
  formState.effectTimeRanges = echoFormState(val).effectTimeRanges
  formState.effectTimeFrames = echoFormState(val).effectTimeFrames
  formState.region = echoFormState(val).region
  formState.enable = echoFormState(val).enable
  formState.linkagePushWechatService = echoFormState(val).linkagePushWechatService
}

const handleChange = (value: string, options: { value: number; label: string; data: unknown }) => {
  console.log(`selected ${value}`, options?.data)
  planTemplate.value = options?.data as AlarmPlan
}

const handleSearch = (val: string) => {
  fetchTemplateList(val)
}

const initBlocks = async () => {
  const { originX, originY, originOffsetX, originOffsetY } = getOriginPosition(
    props.area!.ranges,
    [0, 0]
  )
  console.log('🚀🚀🚀🚀initBlocks', originX, originY, originOffsetX, originOffsetY)
  await nextTick()
  formState.region = [0, 0, 50, 50]
  blocks.value = [
    {
      x: originX,
      y: originY,
      ox: formState.region[0],
      oy: formState.region[1],
      width: formState.region[2],
      height: formState.region[3],
    },
  ]
}

const resetBlocks = () => {
  initBlocks()
}

const thresholdTimeFormat = ref<'s' | 'min' | 'hour' | 'day'>('s') // 触发阈值 额外选择器
const timeThresholdFormat = ref<'s' | 'min' | 'hour' | 'day'>('s') // 异常消失时间阈值 额外选择器

const plainOptions = ref<(number | string)[]>(weekOptions)
const checkState = reactive({
  indeterminate: true,
  checkAll: false,
})

const onCheckAllChange = (e: Event) => {
  const checked = (e.target as HTMLInputElement).checked
  checkState.checkAll = checked
  console.log('onCheckAllChange', e, checked)
  formState.effectTimeRanges = checked ? [...plainOptions.value] : []
}

// 星期映射数字
const weekToNumMap: Record<string, number> = {
  周一: 1,
  周二: 2,
  周三: 3,
  周四: 4,
  周五: 5,
  周六: 6,
  周日: 7,
}
// 数字映射星期
const numToWeekMap: Record<number, string> = {
  1: '周一',
  2: '周二',
  3: '周三',
  4: '周四',
  5: '周五',
  6: '周六',
  7: '周日',
}

watch(
  () => formState.effectTimeRanges,
  (val) => {
    checkState.indeterminate = !!val.length && val.length < plainOptions.value.length // 设置全选按钮的半选状态
    checkState.checkAll = val.length === plainOptions.value.length // 设置全选按钮的选中状态
  },
  {
    immediate: true,
  }
)

const safeParse = <T,>(str: string | undefined | null, fallback: T): T => {
  try {
    return JSON.parse(str ?? JSON.stringify(fallback)) as T
  } catch {
    return fallback
  }
}

interface ParamType {
  start_time?: string
  end_time?: string
  count?: number
  time_threshold?: number
}

interface TimeFrame {
  start_time?: string
  end_time?: string
}

interface AlarmTimePlan {
  startDate?: string
  stopDate?: string
  weekdays?: string
  monthDays?: string
  timeRange?: string
}

interface SourceData {
  name?: string
  remark?: string
  thresholdTime?: number
  mergeTime?: number
  eventVal?: number | null
  param?: string
  alarmTimePlan?: AlarmTimePlan
  alarmTimePlanTpl?: AlarmTimePlan
  region?: string
  enable?: number
  linkagePushWechatService?: number
}

// 是否为有效json字符串
const isValidJSON = (str: string) => {
  try {
    JSON.parse(str)
    return true
  } catch {
    return false
  }
}

const echoFormState = (val: SourceData) => {
  const paramObj = safeParse<ParamType>(val.param, {})
  let weekdays: string[] = []
  let monthDays: string[] = []
  let timeFrames: TimeFrame[] = []
  let planTimes: string[] = []
  if (props.type === 'plan') {
    weekdays = safeParse<string[]>(val.alarmTimePlan?.weekdays, [])
    monthDays = safeParse<string[]>(val.alarmTimePlan?.monthDays, [])
    timeFrames = safeParse<TimeFrame[]>(val.alarmTimePlan?.timeRange, [])
    planTimes = [
      dayjs(val.alarmTimePlan?.startDate).format('YYYY-MM-DD') ?? '',
      dayjs(val.alarmTimePlan?.stopDate).format('YYYY-MM-DD') ?? '',
    ]
  }
  if (props.type === 'template') {
    weekdays = safeParse<string[]>(val.alarmTimePlanTpl?.weekdays, [])
    monthDays = safeParse<string[]>(val.alarmTimePlanTpl?.monthDays, [])
    timeFrames = safeParse<TimeFrame[]>(val.alarmTimePlanTpl?.timeRange, [])
    planTimes = [
      dayjs(val.alarmTimePlanTpl?.startDate).format('YYYY-MM-DD') ?? '',
      dayjs(val.alarmTimePlanTpl?.stopDate).format('YYYY-MM-DD') ?? '',
    ]
  }

  plainOptions.value = weekdays.length === 0 ? monthOptions : weekOptions

  let effectTimeRanges: (number | string)[] = []
  try {
    effectTimeRanges =
      weekdays.length === 0 ? monthDays : weekdays.map((item: string) => numToWeekMap[Number(item)])
  } catch {
    effectTimeRanges = []
  }

  return {
    planName: val.name ?? '',
    remark: val.remark ?? '',
    thresholdTime: typeof val.thresholdTime === 'number' ? val.thresholdTime : null,
    mergeTime: typeof val.mergeTime === 'number' ? val.mergeTime : null,
    eventType: val.eventVal ?? null,
    statisticsTime:
      paramObj?.start_time && paramObj?.end_time
        ? ([paramObj.start_time, paramObj.end_time] as string[])
        : [],
    count: paramObj.count ?? null,
    timeThreshold: paramObj.time_threshold ?? null,
    planTime: planTimes,
    effectType: (weekdays.length === 0 ? 'month' : 'week') as 'week' | 'month',
    effectTimeRanges,
    effectTimeFrames: Array.isArray(timeFrames)
      ? timeFrames.map((item) => ({
          startTime: item?.start_time ?? '',
          endTime: item?.end_time ?? '',
        }))
      : [],
    region: isValidJSON(val?.region ?? '') && JSON.parse(val?.region ?? '[0, 0, 50, 50]'),
    enable: val?.enable === 1,
    linkagePushWechatService: val?.linkagePushWechatService === 1,
  }
}

watch(
  () => props.open,
  (value) => {
    const val = props.data as SourceData
    console.log('🌸🌸 监听data用于编辑回显数据 🌸🌸', value, val)
    if (value && val) {
      formState.planName = echoFormState(val).planName
      formState.remark = echoFormState(val).remark
      formState.thresholdTime = echoFormState(val).thresholdTime
      formState.mergeTime = echoFormState(val).mergeTime
      formState.eventType = echoFormState(val).eventType
      formState.statisticsTime = echoFormState(val).statisticsTime
      formState.count = echoFormState(val).count
      formState.timeThreshold = echoFormState(val).timeThreshold
      formState.planTime = echoFormState(val).planTime
      formState.effectType = echoFormState(val).effectType
      formState.effectTimeRanges = echoFormState(val).effectTimeRanges
      formState.effectTimeFrames = echoFormState(val).effectTimeFrames
      formState.region = echoFormState(val).region
      formState.enable = echoFormState(val).enable
      formState.linkagePushWechatService = echoFormState(val).linkagePushWechatService
      const { originOffsetX, originOffsetY } = getOriginPosition(props.area!.ranges, [0, 0])
      blocks.value = [
        {
          x: formState.region[0] - originOffsetX,
          y: originOffsetY - formState.region[1],
          ox: formState.region[0],
          oy: formState.region[1],
          width: formState.region[2],
          height: formState.region[3],
        },
      ]
      console.log('🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥')
    }
    if (value && props.type === 'plan') {
      fetchTemplateList()
    }
  },
  { immediate: true }
)

// 生效方式变化 周week、月month
const effectTypeChange = (e: Event) => {
  const value = (e.target as HTMLInputElement).value
  console.log('effectTypeChange', e, value)

  if (value === 'week') {
    plainOptions.value = weekOptions
    formState.effectTimeRanges = weekOptions
  } else if (value === 'month') {
    plainOptions.value = monthOptions
    formState.effectTimeRanges = monthOptions
  }
  /* 置全选按钮的状态 */
  checkState.indeterminate =
    !!formState.effectTimeRanges.length &&
    formState.effectTimeRanges.length < plainOptions.value.length // 设置全选按钮的半选状态
  checkState.checkAll = formState.effectTimeRanges.length === plainOptions.value.length // 设置全选按钮的选中状态
}

// 添加时间段
const addEffectTime = () => {
  console.log('addEffectTime', formState.effectTimeFrame)
  if (!formState.effectTimeFrame || !formState.effectTimeFrame.length) {
    message.warn('请选择时间段')
    return
  }
  // 仅允许添加一个时段校验
  if ([5, 7].includes(formState.eventType!) && formState.effectTimeFrames.length >= 1) {
    message.warn('当前事件类型，仅支持添加一个生效时段')
    return
  }
  formState.effectTimeFrames.push({
    startTime: formState.effectTimeFrame[0],
    endTime: formState.effectTimeFrame[1],
  })
  // formState.effectTimeFrame = [] // 清空选择的时间段
}
// 删除已添加的时间段
const deleteEffectTimeItem = (e: Event, index: number) => {
  console.log('deleteEffectTimeItem', e, index)
  formState.effectTimeFrames.splice(index, 1)
}

// 生效时段变化
const eventTypeChange = (value: number) => {
  if ([4, 6, 8].includes(value)) {
    formState.effectTimeFrames = [
      {
        startTime: '00:00',
        endTime: '23:59',
      },
    ]
  } else {
    formState.effectTimeFrames = []
  }
}

// 关闭弹窗
const cancel = () => {
  formRef?.value?.resetFields()
  emit('update:open', false)
  // 重置表单
  formState.planName = ''
  formState.region = [originOffsetX, originOffsetY, 50, 50]
  formState.eventType = null
  formState.thresholdTime = 300
  formState.mergeTime = 30
  formState.planTime = []
  formState.effectType = 'week'
  plainOptions.value = weekOptions
  formState.effectTimeRanges = weekOptions
  formState.effectTimeFrame = []
  formState.effectTimeFrames = []
  formState.enable = true
  formState.linkagePushWechatService = true
  formState.statisticsTime = []
  formState.count = 3
  formState.timeThreshold = 300
  formState.remark = ''
  planTemplateId.value = null
  initBlocks()
}

const eventTypeList = ref<{ label: string; value: string }[]>([])
// 获取事件类型下拉列表
const fetchEventTypeList = async () => {
  try {
    const res = await alarmApi.getAlarmEventTypeList()
    console.log('获取事件类型下拉列表成功✅', res)
    const data = res.data
    eventTypeList.value =
      (Array.isArray(data) &&
        data.map((item) => ({
          label: item.eventDesc,
          value: item.eventVal,
        }))) ||
      []
  } catch (err) {
    console.log('获取事件类型下拉列表失败❌', err)
  }
}
fetchEventTypeList()

function thresholdTimeFormatValue() {
  if (thresholdTimeFormat.value === 's') {
    return Number(formState.thresholdTime) // 触发阈值
  } else if (thresholdTimeFormat.value === 'min') {
    return Number(formState.thresholdTime) * 60 // 触发阈值
  } else if (thresholdTimeFormat.value === 'hour') {
    return Number(formState.thresholdTime) * 60 * 60 // 触发阈值
  } else if (thresholdTimeFormat.value === 'day') {
    return Number(formState.thresholdTime) * 24 * 60 * 60 // 触发阈值
  }
}

function timeThresholdFormatValue() {
  if (timeThresholdFormat.value === 's') {
    return Number(formState.timeThreshold) // 触发阈值
  } else if (timeThresholdFormat.value === 'min') {
    return Number(formState.timeThreshold) * 60 // 触发阈值
  } else if (timeThresholdFormat.value === 'hour') {
    return Number(formState.timeThreshold) * 60 * 60 // 触发阈值
  } else if (timeThresholdFormat.value === 'day') {
    return Number(formState.timeThreshold) * 24 * 60 * 60 // 触发阈值
  }
}

const submitLoading = ref(false)
// 确定
const submit = () => {
  formRef?.value
    ?.validate()
    .then(() => {
      console.log('校验通过', formState)
      let paramData = {}
      if ([1, 2, 3].includes(formState.eventType as number)) {
        paramData = {}
        console.log('🔥paramData🔥', paramData)
      } else if ([4, 5, 8].includes(formState.eventType as number)) {
        paramData = {
          start_time: formState.statisticsTime[0],
          end_time: formState.statisticsTime[1],
        }
        console.log('🔥paramData🔥', paramData)
      } else if ([6, 7].includes(formState.eventType as number)) {
        paramData = {
          start_time: formState.statisticsTime[0],
          end_time: formState.statisticsTime[1],
          count: isNaN(Number(formState.count)) ? 0 : Number(formState.count),
        }
        console.log('🔥paramData🔥', paramData)
      } else if ([9].includes(formState.eventType as number)) {
        paramData = {
          time_threshold: isNaN(Number(formState.timeThreshold)) ? 0 : timeThresholdFormatValue(),
        }
        console.log('🔥paramData🔥', paramData)
      }

      if ([5, 7].includes(formState.eventType!) && formState.effectTimeFrames.length >= 1) {
        message.warn('当前事件类型，仅支持添加一个生效时段')
        return
      }

      const params = {
        alarmPlanId: props.alarmPlanId || undefined, // 告警计划ID 编辑时传入
        clientId: props.clientId, // 设备ID
        name: formState.planName, // 计划名称
        remark: formState.remark || '', // 备注
        thresholdTime: thresholdTimeFormatValue(), // 触发阈值
        mergeTime: Number(formState.mergeTime) || 30, // 归并时间
        eventVal: formState.eventType as number, // 事件类型 与 param 有联动关系
        param: JSON.stringify(paramData), // 事件参数 与 eventVal 有联动关系
        region: [1, 2, 3, 9].includes(formState.eventType as number)
          ? JSON.stringify(formState.region)
          : '[]', // 检测区域
        linkagePushWechatService: Number(formState.linkagePushWechatService) as 0 | 1, // 是否开启服务号消息推送 1:开启 0:关闭
        enable: Number(formState.enable) as 0 | 1, // 是否启用 0否 1是
        // 生效方式
        alarmTimePlan: {
          startDate: formState.planTime[0], // 计划开始时间
          stopDate: formState.planTime[1], // 计划结束时间
          // 生效时段
          timeRange: JSON.stringify(
            formState.effectTimeFrames.map((item) => ({
              start_time: item.startTime,
              end_time: item.endTime,
            }))
          ),
          monthDays: JSON.stringify(
            formState.effectType === 'month' ? formState.effectTimeRanges : []
          ),
          weekdays: JSON.stringify(
            formState.effectType === 'week'
              ? formState.effectTimeRanges.map((item) => weekToNumMap[item])
              : []
          ),
        },
      }
      console.log('🚀🚀🚀提交参数', params)
      if ([4, 5, 6, 7, 8].includes(formState.eventType as number)) {
        if (!formState.statisticsTime[0] || !formState.statisticsTime[1]) {
          message.warn('统计时间不完整')
          return
        }
      }
      if (formState.effectTimeFrames.length === 0) {
        message.warn('请添加生效时段')
        return
      }
      if (![4, 5, 6, 8].includes(formState.eventType!)) {
        if (formState.effectTimeRanges.length === 0) {
          message.warn('请选择生效方式')
          return
        }
      }
      if ([1, 2, 3, 9].includes(formState.eventType as number) && formState.region.length !== 4) {
        message.warn('请选择检测区域')
        return
      }
      submitLoading.value = true
      if (props.type === 'plan') savePlan(params)
      if (props.type === 'template') saveTemplate(params)
    })
    .catch((err) => {
      console.log('校验失败', err)
    })
}

// 保存计划
const savePlan = async (params: AlarmPlanParams) => {
  console.log('保存计划')
  try {
    await alarmApi
      .saveAlarmPlan(params)
      .then((res) => {
        console.log('添加成功', res)
        submitLoading.value = false
        message.success('添加成功')
        emit('success')
        cancel()
      })
      .catch(() => {
        submitLoading.value = false
      })
  } catch (error) {
    console.log('添加失败', error)
    message.error('添加失败')
  }
}

// 保存模板
const saveTemplate = async (params: AlarmPlanParams) => {
  console.log('saveTemplate', formState)
  try {
    await alarmApi
      .saveAlarmPlanTemplate({
        ...params,
        id: props.alarmPlanId as number,
        name: params.name,
        eventVal: params.eventVal,
        param: params.param,
        region: params.region,
        linkagePushWechatService: params.linkagePushWechatService,
        enable: params.enable,
        alarmTimePlanTpl: params.alarmTimePlan,
      })
      .then((res) => {
        console.log('添加成功', res)
        submitLoading.value = false
        message.success('添加成功')
        emit('success')
        cancel()
      })
      .catch(() => {
        submitLoading.value = false
      })
  } catch (error) {
    console.log('添加失败', error)
    message.error('添加失败')
  }
}

const furnitureItems = ref<Furniture[]>([])
const devId = ref<string | undefined>(props.devId)
/**
 * 获取房间布局
 */
const fetchRoomLayout = async () => {
  console.log('fetchRoomLayout', devId.value)
  if (!devId.value) {
    furnitureItems.value = []
    return
  }
  try {
    const res = await roomApi.queryRoomInfo({
      devId: devId.value,
    })
    console.log('✅获取到房间布局信息', res)
    if (!res) return
    const { furnitures } = res.data
    if (furnitures) {
      // 添加接口返回的家具数据
      furnitures!.forEach((item) => {
        furnitureItems.value.push({
          ...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,
        })
      })
    }
  } catch (error) {
    console.error('❌获取房间布局信息失败', error)
  }
}
fetchRoomLayout()

const areaAvailable = computed(() => {
  const length = Math.abs(props.area!.ranges[0]) + Math.abs(props.area!.ranges[1])
  const width = Math.abs(props.area!.ranges[2]) + Math.abs(props.area!.ranges[3])
  return Number(length) < 50 || Number(width) < 50
})
</script>

<style scoped lang="less">
:deep(.ant-modal) {
  .footer {
    text-align: right;
  }
  .ant-modal-body {
    padding: 12px 0;
  }
}

:deep(.ant-checkbox-group) {
  .ant-checkbox + span {
    min-width: 32px;
  }
}

:deep(.ant-tag) {
  margin-inline-end: 0 !important;
}

.eventTypeBox {
  margin-top: 12px;
  color: #555;
  font-size: 14px;
  padding: 20px 12px;
  background: #fafafa;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  &-item {
    margin-bottom: 12px;
    display: flex;
    align-items: center;
    gap: 8px;

    &-label {
      width: 100px;
    }
    &-labelend {
      width: 140px;
    }
    &:last-child {
      margin-bottom: 0;
    }
    :deep(.ant-form-item) {
      flex: 1;
      margin-bottom: 0;
    }
  }
}

.viewer {
  padding: 10px;
  min-width: 500px;
  flex-shrink: 0;

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

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

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