<template>
  <div class="elderly-management-system large-screen">
    <div class="cyber-bg"></div>
    <div class="cyber-grid"></div>

    <div class="my-container">
      <!-- 顶部信息栏 -->
      <TopInfoBar :tenant-name="getTenantName()" />

      <!-- 右上角实时事件抽屉开关 -->
      <el-tooltip class="box-item" effect="dark" content="设备实时事件" placement="top-start">
        <button class="realtime-fab" @click="realtimeDrawerVisible = true" title="实时事件">
          <Icon icon="mdi:radar" :size="30" />
        </button>
      </el-tooltip>

      <!-- 统计信息卡片 -->
      <StatsCard :stats="largeScreenStats" @stat-card-click="handleStatCardClick" />

      <!-- 主内容区域 -->
      <div v-if="!showAllDevices" class="main-content-large">
        <!-- 左侧老人列表 -->
        <ElderlyList
          :elderly-list="elderlyList"
          :selected-elderly-id="selectedElderly.id"
          :warning-flags="warningFlags"
          @select-elderly="selectElderly"
          @add-device="openAddDeviceFromList"
          @handle-warning="openHandleWarningDialog"
          @add-elder="openAddElderDialog"
        />

        <!-- 右侧详情区域 -->
        <DetailSection
          ref="detailSectionRef"
          :selected-elderly="selectedElderly.id > 0 ? selectedElderly : null"
          :device-type-options="deviceTypeOptions"
          @add-device="openAddDeviceDialog"
          @show-device-detail="showDeviceDetail"
          @remove-device="removeDevice"
          @view-profile="openElderProfileDialog"
          @view-warning-service="openElderWarningServiceDialog"
        />
      </div>

      <!-- 全部设备视图（组件） -->
      <AllDevicesView
        v-else
        :devices="allDevices as any"
        @refresh="handelDeviceRefresh"
        @back="backToOverview"
        @show-device-detail="showDeviceDetailByCode"
      />

      <!-- 底部状态栏 -->
      <StatusBar
        :system-status="largeScreenStatsData.systemStatus"
        :last-time="largeScreenStatsData.lastTime"
        :has-alerts="hasAlerts"
      />
    </div>

    <!-- 对话框和抽屉 -->
    <AddDeviceDialog
      ref="addDeviceDialogRef"
      v-model:visible="dialogVisible"
      :current-elderly="currentElderly"
      :device-type-options="deviceTypeOptions"
      :tenant-name="getTenantName()"
      :organization-id="organizationId"
      @submit="addDevice"
    />

    <DeviceDetailDialog
      v-model:visible="deviceDetailVisible"
      :device="deviceDetail"
      :device-type-options="deviceTypeOptions"
    />

    <WarningDrawer
      v-model:visible="warningDrawerVisible"
      v-model:page-num="pageNum"
      v-model:page-size="pageSize"
      :warning-data="warningData"
      :total="total"
      @page-change="handlePageChange"
      @size-change="handleSizeChange"
      @handle-warning="onHandleWarningFromDrawer"
    />

    <AddElderDialog v-model:visible="addElderDialogVisible" @submit="submitAddElder" />

    <HandleWarningDialog
      v-model:visible="handleWarningDialogVisible"
      :current-elderly="currentWarningElderly"
      :mode="handleWarningMode"
      @submit="submitHandleWarning"
    />

    <ElderProfileDialog v-model="elderProfileDialogVisible" :elder-id="currentProfileElderId" />

    <ElderWarningServiceDialog
      v-model="elderWarningServiceDialogVisible"
      :elder-id="currentWarningServiceElderId"
    />

    <!-- 实时事件抽屉 -->
    <RealtimeFeedDrawer ref="realtimeDrawerRef" v-model="realtimeDrawerVisible" />
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, onMounted, onUnmounted, nextTick, h, defineAsyncComponent } from 'vue'
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
import fetchHttp from '@/config/axios/fetchHttp'
import { getAccessToken, getLoginForm } from '@/utils/auth'
import { useWebSocket } from './composables/useWebSocket'
import { amapReverseGeocode } from '@/utils/amapService'

// 导入组件
const TopInfoBar = defineAsyncComponent(() => import('./components/TopInfoBar.vue'))
const StatsCard = defineAsyncComponent(() => import('./components/StatsCard.vue'))
const ElderlyList = defineAsyncComponent(() => import('./components/ElderlyList.vue'))
const DetailSection = defineAsyncComponent(() => import('./components/DetailSection.vue'))
const AddDeviceDialog = defineAsyncComponent(() => import('./components/AddDeviceDialog.vue'))
const DeviceDetailDialog = defineAsyncComponent(() => import('./components/DeviceDetailDialog.vue'))
const WarningDrawer = defineAsyncComponent(() => import('./components/WarningDrawer.vue'))
const AddElderDialog = defineAsyncComponent(() => import('./components/AddElderDialog.vue'))
const HandleWarningDialog = defineAsyncComponent(
  () => import('./components/HandleWarningDialog.vue')
)
const StatusBar = defineAsyncComponent(() => import('./components/StatusBar.vue'))
const AllDevicesView = defineAsyncComponent(() => import('./components/AllDevicesView.vue'))
const ElderProfileDialog = defineAsyncComponent(() => import('./components/ElderProfileDialog.vue'))
const ElderWarningServiceDialog = defineAsyncComponent(
  () => import('./components/ElderWarningServiceDialog.vue')
)
const RealtimeFeedDrawer = defineAsyncComponent(() => import('./components/RealtimeFeedDrawer.vue'))

const realtimeDrawerVisible = ref(false)
const realtimeDrawerRef = ref<any>(null)

// 类型定义
interface WarningHistory {
  happensAt: string
  content: string
  elderId?: number
  elderName?: string
}

interface StatisticsVO {
  systemStatus: string
  lastTime: string
  isWarning: boolean
}

interface CommonVo {
  name: string
  value: string
}

interface HistoryInfoVo {
  happensAt: string
  content: string
}

interface Elderly {
  id: number
  avatar: string
  name: string
  age: number
  gender: string
  healthStatus: string
  healthText: string
  deviceNumber: number
  elderPhone?: string
  relativePhone?: string
  _flashEffect?: boolean
}

interface HealthVO {
  name: string
  value: string
  status: string
  unit: string
}

interface DetailDevice {
  deviceType: string
  installPosition: string
  status: string
  indicatorText: string
  deviceCode: string
}

interface SelectElderly {
  id: number
  healthList: HealthVO[]
  name: string
  deviceList: DetailDevice[]
}

interface Device {
  deviceType: string
  installPosition: string
  status: string
  indicatorInfo: CommonVo[]
  historyInfo: HistoryInfoVo[]
}

interface LargeScreenStat {
  icon: string
  value: number | string
  label: string
  trend: 'up' | 'stable'
  change: string
  type?: 'warning'
  clickable?: boolean
  indicator: string
}

interface DeviceTypeVO {
  deviceType: string
  deviceTypeName: string
  displayOrder: number
}

// 常量定义
const WARNING_STORAGE_KEY = 'elder_warning_flags'
const organizationId = localStorage.getItem('organizationId') || ''

// 响应式数据
const total = ref(0)
const pageNum = ref(1)
const pageSize = ref(10)
const elderlyList = ref<Elderly[]>([])
const dialogVisible = ref(false)
const addDeviceDialogRef = ref<any>(null)
const detailSectionRef = ref<any>(null)
const deviceDetailVisible = ref(false)
const currentElderly = ref<SelectElderly | null>(null)
const selectedElderly = ref<SelectElderly>({
  id: 0,
  name: '',
  healthList: [],
  deviceList: []
})

// 全部设备视图
const showAllDevices = ref(false)
interface AllDevice {
  deviceType: string
  deviceCode: string
  installPosition: string
  elderName: string
  historyInfo: HistoryInfoVo[]
}
const allDevices = ref<AllDevice[]>([])

const deviceTypeOptions = ref<DeviceTypeVO[]>([])
const warningDrawerVisible = ref(false)
const warningData = ref<WarningHistory[]>([])
const deviceDetail = ref<Device | null>(null)
const largeScreenStatsData = ref<StatisticsVO>({
  systemStatus: '正常',
  lastTime: new Date().toLocaleString(),
  isWarning: false
})

const addElderDialogVisible = ref(false)
const handleWarningDialogVisible = ref(false)
const currentWarningElderly = ref<Elderly | null>(null)
const handleWarningMode = ref<'default' | 'reportOnly'>('default')
const warningFlags = ref<number[]>([])
const elderProfileDialogVisible = ref(false)
const currentProfileElderId = ref(0)
const elderWarningServiceDialogVisible = ref(false)
const currentWarningServiceElderId = ref(0)

// 告警标记管理
const loadWarningFlags = () => {
  try {
    const raw = localStorage.getItem(WARNING_STORAGE_KEY)
    warningFlags.value = raw ? JSON.parse(raw) : []
  } catch (e) {
    warningFlags.value = []
  }
}

const saveWarningFlags = () => {
  localStorage.setItem(WARNING_STORAGE_KEY, JSON.stringify(warningFlags.value))
}

const addWarningFlag = (elderId: number) => {
  if (!elderId) return
  if (!warningFlags.value.includes(elderId)) {
    warningFlags.value.push(elderId)
    saveWarningFlags()
  }
}

const clearWarningFlag = (elderId: number) => {
  const idx = warningFlags.value.indexOf(elderId)
  if (idx !== -1) {
    warningFlags.value.splice(idx, 1)
    saveWarningFlags()
  }
}

// 大屏统计信息
const largeScreenStats = ref<LargeScreenStat[]>([
  {
    icon: 'mdi:account-group',
    value: 0,
    label: '老人数量',
    trend: 'up',
    change: '',
    clickable: true,
    indicator: 'elderCount'
  },
  {
    icon: 'mdi:devices',
    value: 0,
    label: '设备总数',
    trend: 'up',
    change: '',
    clickable: true,
    indicator: 'deviceCount'
  },
  // {
  //   icon: 'mdi:shield-check',
  //   value: 0,
  //   label: '在线设备',
  //   trend: 'up',
  //   change: '100%',
  //   indicator: 'onlineCount'
  // },
  {
    icon: 'mdi:alert-decagram',
    value: 0,
    label: '警告设备',
    trend: 'up',
    change: '需关注',
    type: 'warning',
    clickable: true,
    indicator: 'warningCount'
  }
])

const hasAlerts = computed(() => largeScreenStatsData.value.isWarning)

// 方法
const getTenantName = () => {
  return getLoginForm()?.tenantName || ''
}

const openAddDeviceDialog = (elderly: SelectElderly) => {
  currentElderly.value = elderly
  dialogVisible.value = true
  nextTick(() => {
    // 确保子组件已挂载并接收到 props 后再初始化表单
    addDeviceDialogRef.value?.initForm?.()
  })
}

const openAddDeviceFromList = (elderly: Elderly) => {
  const temp: SelectElderly = {
    id: elderly.id,
    name: elderly.name,
    healthList: [],
    deviceList: []
  }
  openAddDeviceDialog(temp)
}

const addDevice = async (data: any) => {
  try {
    const res = await fetchHttp.post('/api/pc/admin/bindDevice', data, {
      headers: {
        Authorization: `Bearer ${getAccessToken()}`
      }
    })
    if (res) {
      ElMessage.success('设备添加成功！')
      getElderDeviceMessage(selectedElderly.value.id)
    } else {
      ElMessage.error('设备添加失败！')
    }
  } catch (error) {
    console.error('添加设备失败:', error)
    ElMessage.error('添加设备时出现错误')
  }
}

const removeDevice = (elderly: any, device: DetailDevice) => {
  console.log('elderly', elderly)
  console.log('device', device)
  ElMessageBox.confirm(`确定要删除设备吗？`, '删除确认', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(async () => {
      const res = await fetchHttp.post(
        '/api/pc/admin/unbindDevice',
        {
          deviceCode: device.deviceCode,
          elderId: Number(elderly.id)
        },
        {
          headers: {
            Authorization: `Bearer ${getAccessToken()}`
          }
        }
      )
      if (res) {
        ElMessage.success('设备删除成功！')
        getElderDeviceMessage(selectedElderly.value.id)
      } else {
        ElMessage.error('设备删除失败！')
      }
    })
    .catch(() => {})
}

const openAddElderDialog = () => {
  addElderDialogVisible.value = true
}

const openElderProfileDialog = (elderly: any) => {
  currentProfileElderId.value = elderly.id
  elderProfileDialogVisible.value = true
}

const openElderWarningServiceDialog = (elderly: any) => {
  currentWarningServiceElderId.value = elderly.id
  elderWarningServiceDialogVisible.value = true
}

const submitAddElder = async (data: any) => {
  try {
    const res = await fetchHttp.post('/api/pc/admin/addElder', data, {
      headers: {
        Authorization: `Bearer ${getAccessToken()}`
      }
    })
    if (res) {
      ElMessage.success('长者添加成功！')
      await getElderList()
    } else {
      ElMessage.error('长者添加失败！')
    }
  } catch (error) {
    console.error('添加长者失败:', error)
    ElMessage.error('添加长者时出现错误')
  }
}

const openHandleWarningDialog = (elderly: Elderly) => {
  currentWarningElderly.value = elderly
  handleWarningMode.value = 'default' // 老人卡片进入：默认电话回访
  handleWarningDialogVisible.value = true
}

const submitHandleWarning = async (data: any) => {
  // 电话回访与上报告警均可确认处理，并上送 elderId 与上报信息（remarks）
  const params = {
    elderId: data.elderId,
    remarks: data.message || ''
  }
  try {
    const res = await fetchHttp.post('/api/pc/admin/processAlert', params, {
      headers: {
        Authorization: `Bearer ${getAccessToken()}`
      }
    })
    if (res) {
      ElMessage.success(data.handleType === 'report' ? '告警情况已上报！' : '电话回访已确认！')
      clearWarningFlag(data.elderId)
      handleWarningDialogVisible.value = false
      if (selectedElderly.value.id === data.elderId) {
        await getElderDeviceMessage(selectedElderly.value.id)
      }
    } else {
      ElMessage.error('处理失败，请重试')
    }
  } catch (error) {
    console.error('处理告警失败:', error)
    ElMessage.error('处理告警时出现错误')
  }
}

const selectElderly = (elderly: Elderly) => {
  selectedElderly.value.id = elderly.id
  selectedElderly.value.name = elderly.name
  // clearWarningFlag(elderly.id)
  getElderDeviceMessage(selectedElderly.value.id)
  detailSectionRef.value?.reBackToDetail()
}

const showDeviceDetail = async (device: DetailDevice) => {
  await getDeviceDetail(device.deviceCode)
  deviceDetailVisible.value = true
}

const handleStatCardClick = (stat: LargeScreenStat) => {
  // 点击老人数量：回到总览视图
  if (stat.indicator === 'elderCount') {
    backToOverview()
    return
  }
  // 点击设备总数：切换到全部设备视图
  if (stat.indicator === 'deviceCount') {
    openAllDevicesView()
    return
  }
  // 点击警告设备：打开预警抽屉
  if (stat.indicator === 'warningCount' && Number(stat.value) > 0) {
    getAllWarning()
    warningDrawerVisible.value = true
  }
}

const handlePageChange = (newPageNum: number) => {
  pageNum.value = newPageNum
  getAllWarning()
}

const handleSizeChange = (newPageSize: number) => {
  pageSize.value = newPageSize
  pageNum.value = 1
  getAllWarning()
}

const onHandleWarningFromDrawer = (record: WarningHistory) => {
  let target: Elderly | null = null
  if ((record as any).elderId) {
    target = elderlyList.value.find((e) => e.id === (record as any).elderId) || null
  }
  if (!target && (record as any).elderName) {
    target = elderlyList.value.find((e) => e.name === (record as any).elderName) || null
  }
  if (!target && record.content) {
    // 尝试从内容中提取姓名（简单匹配）
    const match = record.content.match(/(长者|老人|用户)[:：]\s*([\u4e00-\u9fa5A-Za-z0-9_]+)/)
    if (match && match[2]) {
      target = elderlyList.value.find((e) => e.name === match[2]) || null
    }
  }
  if (target) {
    handleWarningMode.value = 'reportOnly'
    currentWarningElderly.value = target
    handleWarningDialogVisible.value = true
  } else {
    handleWarningMode.value = 'reportOnly'
    currentWarningElderly.value = null
    handleWarningDialogVisible.value = true
    // ElMessage.warning('未找到对应长者，将以上报方式处理')
  }
}

// API 调用
const getStatistics = async () => {
  const res = await fetchHttp.get(
    '/api/pc/admin/getStatistics?organizationId=' + organizationId,
    {},
    {
      headers: {
        Authorization: `Bearer ${getAccessToken()}`
      }
    }
  )
  if (res.list && res.list.length) {
    res.list.forEach((v: any) => {
      const index = largeScreenStats.value.findIndex((z) => z.indicator == v.indicator)
      if (~index) {
        largeScreenStats.value[index].value = v.total
        largeScreenStats.value[index].change = v.change
        largeScreenStats.value[index].trend = v.trend
      }
    })
  }
}

const getElderList = async () => {
  const res = await fetchHttp.get(
    '/api/pc/admin/getElderList?organizationId=' + organizationId,
    {},
    {
      headers: {
        Authorization: `Bearer ${getAccessToken()}`
      }
    }
  )
  if (res?.length) {
    elderlyList.value = res
    if (elderlyList.value.length) {
      selectedElderly.value.id = elderlyList.value[0].id
      selectedElderly.value.name = elderlyList.value[0].name
      getElderDeviceMessage(selectedElderly.value.id)
      warningFlags.value = []
    }
  }
}

const getDeviceDetail = async (deviceCode: string) => {
  const res = await fetchHttp.get(
    '/api/pc/admin/getDeviceDetail?deviceCode=' + deviceCode,
    {},
    {
      headers: {
        Authorization: `Bearer ${getAccessToken()}`
      }
    }
  )
  if (res) {
    deviceDetail.value = res
  }
}

const getElderDeviceMessage = async (elderId: number) => {
  const res = await fetchHttp.get(
    '/api/pc/admin/getElderHealthAndDeviceInfo?elderId=' + elderId,
    {},
    {
      headers: {
        Authorization: `Bearer ${getAccessToken()}`
      }
    }
  )
  if (res) {
    selectedElderly.value.healthList = res.healthList
    selectedElderly.value.deviceList = res.deviceList
  }
}

const getAllWarning = async () => {
  const params = {
    pageNum: pageNum.value,
    pageSize: pageSize.value
  }
  const res = await fetchHttp.get('/api/pc/admin/getAllWarning', params, {
    headers: {
      Authorization: `Bearer ${getAccessToken()}`
    }
  })
  if (res) {
    total.value = res.total
    warningData.value = res.list || []
  }
}

const getAllDevices = async () => {
  const res = await fetchHttp.get(
    '/api/pc/admin/getAllDeviceTypes',
    {},
    {
      headers: {
        Authorization: `Bearer ${getAccessToken()}`
      }
    }
  )
  if (res && res?.length) {
    deviceTypeOptions.value = res
  }
}

// WebSocket 处理
const addFlashingEffect = (elder: Elderly) => {
  elder._flashEffect = true
  setTimeout(() => {
    elder._flashEffect = false
    elderlyList.value = [...elderlyList.value]
  }, 10000)
}

const handelDeviceRefresh = async () => {
  await refreshAllDevices()
  ElMessage.success('设备刷新成功！')
}

// 全部设备视图相关方法
const refreshAllDevices = async () => {
  try {
    const res = await fetchHttp.get(
      '/api/pc/admin/getOrganizationDevices',
      {},
      {
        headers: {
          Authorization: `Bearer ${getAccessToken()}`
        }
      }
    )
    console.log('res', res)
    if (res?.deviceList && Array.isArray(res.deviceList)) {
      allDevices.value = res.deviceList
    }
  } catch (e) {
    console.error('获取全部设备失败:', e)
    allDevices.value = []
  }
}

const openAllDevicesView = async () => {
  showAllDevices.value = true
  await refreshAllDevices()
}

const backToOverview = () => {
  showAllDevices.value = false
}

const showDeviceDetailByCode = async (deviceCode: string) => {
  await getDeviceDetail(deviceCode)
  deviceDetailVisible.value = true
}

const handleSOSAlert = async (alertData: any) => {
  const alert = alertData.data || alertData
  sendMessage({
    type: 'SOS_ACK',
    alertId: alertData.timestamp,
    timestamp: Date.now()
  })

  // 获取地址信息
  let addressInfo = '位置信息获取中...'
  if (alert.longitude && alert.latitude) {
    addressInfo = await amapReverseGeocode(alert.longitude, alert.latitude)
  }

  ElNotification({
    title: '🚨🚨 SOS紧急预警 🚨🚨',
    customClass: 'my-warning-notification',
    message: h('div', {
      style: { color: '#fff' },
      innerHTML: `
        <div>院区名称: ${alert.organizationName || '未知'}</div>
        <div>长者姓名: ${alert.elderName || '未知'}</div>
        <div>长者房间: ${alert.roomName || '未知'}</div>
        <div>设备类型: ${alert.deviceType || '未知'}</div>
        <div>设备电量: ${alert.batteryLevel || '0%'}</div>
        <div>位置信息: ${addressInfo}</div>
        <div>时间: ${new Date(alertData.timestamp).toLocaleString()}</div>
      `
    }),
    type: 'warning',
    duration: 10000
  })

  if (alert.elderId) addWarningFlag(alert.elderId)

  if (alert.elderId && elderlyList.value.length > 0) {
    const elderIndex = elderlyList.value.findIndex((elder) => elder.id === alert.elderId)
    if (elderIndex !== -1) {
      const reorderedList = [...elderlyList.value]
      const [selectedElder] = reorderedList.splice(elderIndex, 1)
      reorderedList.unshift(selectedElder)
      elderlyList.value = reorderedList
      addFlashingEffect(selectedElder)
      getElderDeviceMessage(alert.elderId)
    }
  }

  largeScreenStatsData.value = {
    systemStatus: '告警',
    lastTime: new Date(alertData.timestamp).toLocaleString(),
    isWarning: true
  }

  setTimeout(() => {
    largeScreenStatsData.value = {
      systemStatus: '正常',
      lastTime: new Date().toLocaleString(),
      isWarning: false
    }
  }, 10000)
}

const handleHealthAlert = async (healthAlert: any) => {
  const healthAlertData = healthAlert.data

  if (healthAlertData.elderId) addWarningFlag(healthAlertData.elderId)

  // 获取地址信息
  let addressInfo = ''
  if (healthAlertData.longitude && healthAlertData.latitude) {
    addressInfo = await amapReverseGeocode(healthAlertData.longitude, healthAlertData.latitude)
  }

  ElNotification({
    title: `🚨🚨 ${healthAlertData.eventType} 🚨🚨`,
    customClass: 'my-warning-notification',
    message: h('div', {
      style: { color: '#fff' },
      innerHTML: `
        <div>长者姓名: ${healthAlertData.elderName || '未知'}</div>
        <div>预警指标: ${healthAlertData.indicatorName || '未知'}</div>
        <div>预警信息: ${healthAlertData.message || '未知'}</div>
        <div>处理建议: ${healthAlertData.suggestion || '未知'}</div>
        <div>预警程度: ${healthAlertData.alertLevel || ''}</div>
        <div>位置信息: ${addressInfo}</div>
        <div>时间: ${new Date(healthAlertData.timestamp).toLocaleString()}</div>
      `
    }),
    type: 'warning',
    duration: 10000
  })

  if (healthAlertData.elderId && elderlyList.value.length > 0) {
    const elderIndex = elderlyList.value.findIndex((elder) => elder.id === healthAlertData.elderId)
    if (elderIndex !== -1) {
      elderlyList.value[elderIndex].healthText =
        healthAlertData.message + healthAlertData.suggestion
      const reorderedList = [...elderlyList.value]
      const [selectedElder] = reorderedList.splice(elderIndex, 1)
      reorderedList.unshift(selectedElder)
      elderlyList.value = reorderedList
      addFlashingEffect(selectedElder)
      getElderDeviceMessage(healthAlertData.elderId)
    }
  }

  largeScreenStatsData.value = {
    systemStatus: '健康告警',
    lastTime: new Date(healthAlertData.timestamp).toLocaleString(),
    isWarning: true
  }

  setTimeout(() => {
    largeScreenStatsData.value = {
      systemStatus: '设备正常',
      lastTime: new Date().toLocaleString(),
      isWarning: false
    }
  }, 10000)
}

const handleLocationAlert = async (locationAlert: any) => {
  try {
    const payload = locationAlert?.data || {}
    const elderId = Number(payload.elderId || 0)
    const lng = Number(payload.longitude)
    const lat = Number(payload.latitude)
    const ts = locationAlert.timestamp

    // 推入右上角实时抽屉
    realtimeDrawerRef.value?.pushLocation?.({
      longitude: lng,
      latitude: lat,
      locationTime: ts,
      elderName: payload.elderName
    })

    // 地图联动：只对当前选中长者联动地图
    if (!elderId || elderId !== selectedElderly.value.id) return
    if (!Number.isFinite(lng) || !Number.isFinite(lat)) return

    const isMapShown = detailSectionRef.value?.isMapShown?.()
    if (!isMapShown) return

    detailSectionRef.value?.addMapPoint?.({
      longitude: lng,
      latitude: lat,
      locationTime: new Date(ts).toLocaleString()
    })
  } catch (e) {
    console.warn('处理 LOCATION_UPDATE 失败（忽略）:', e)
  }
}

const handleHealthUpdateAlert = async (healthUpdateAlert: any) => {
  realtimeDrawerRef.value?.pushHealth?.({
    time: healthUpdateAlert.timestamp,
    elderName: healthUpdateAlert.data.elderName,
    indicatorResults: healthUpdateAlert.data.realtimeHealthAnalysisResult.indicatorResults
  })
}

const handleDeviceDataUpdate = async (deviceDataUpdate: any) => {
  ElNotification({
    title: `设备状态更新`,
    customClass: 'my-warning-notification',
    message: h('div', {
      style: { color: '#fff' },
      innerHTML: `
        <div>设备名称: ${deviceDataUpdate.data.deviceType || '未知'}</div>
        <div>设备状态: ${deviceDataUpdate.data.eventType || '未知'}</div>
        <div>绑定长者: ${deviceDataUpdate.data.elderName || '未知'}</div>
        <div>时间: ${new Date(deviceDataUpdate.timestamp).toLocaleString()}</div>
      `
    }),
    type: 'warning',
    duration: 10000
  })
  realtimeDrawerRef.value?.pushDeviceUpdate?.({
    time: deviceDataUpdate.timestamp,
    elderName: deviceDataUpdate.data.elderName,
    eventType: deviceDataUpdate.data.eventType,
    deviceType: deviceDataUpdate.data.deviceType
  })
  // 判断deviceDataUpdate.data.elderId是否跟当前点击的老人id一致，如果一致，则更新当前点击的老人设备列表
  if (deviceDataUpdate.data.elderId === selectedElderly.value.id) {
    getElderDeviceMessage(selectedElderly.value.id)
  }
}

// WebSocket 连接
const wsUrl = import.meta.env.VITE_API_WSS_URL_MONITOR
const { connect, disconnect, sendMessage } = useWebSocket({
  wsUrl,
  onSOSAlert: handleSOSAlert,
  onHealthAlert: handleHealthAlert,
  onLocationAlert: handleLocationAlert,
  onHealthUpdateAlert: handleHealthUpdateAlert,
  onDeviceDataUpdate: handleDeviceDataUpdate
})

// 生命周期
onMounted(() => {
  loadWarningFlags()
  getAllDevices()
  getStatistics()
  getElderList()

  setTimeout(() => {
    connect()
  }, 1000)

  document.addEventListener('visibilitychange', () => {
    if (!document.hidden) {
      // 页面回到前台
    }
  })

  setInterval(() => {
    // 定期健康检查
  }, 30000)

  window.addEventListener('online', () => {
    // 网络恢复
  })
})

onUnmounted(() => {
  disconnect()
})
</script>

<style lang="scss" scoped>
$primary-color: #1a73e8;
$secondary-color: #00c6ff;
$accent-color: #7b61ff;
$dark-bg: #0a0e14;
$card-bg: #1a1f2e;
$text-light: #fff;
$text-gray: #8a8f98;
$success-color: #26de81;
$warning-color: #fd9644;
$danger-color: #ff6b6b;
$bg-gradient-start: #04060f;
$bg-gradient-mid: #0c1631;
$bg-gradient-end: #101b3f;
$bg-accent-1: rgb(32 156 255 / 35%);
$bg-accent-2: rgb(123 97 255 / 25%);

@keyframes auroraShift {
  0% {
    opacity: 0.6;
    transform: translate(-10%, -10%) scale(1);
  }

  50% {
    opacity: 0.9;
    transform: translate(5%, 10%) scale(1.1);
  }

  100% {
    opacity: 0.6;
    transform: translate(15%, -5%) scale(1.05);
  }
}

.large-screen {
  position: relative;
  padding: 20px;
  overflow: hidden;
  height: calc(
    100vh - var(--app-content-padding) - var(--app-content-padding) - var(--app-footer-height)
  );
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
    sans-serif;
  color: $text-light;
  background: radial-gradient(circle at 10% 20%, rgb(15 88 255 / 25%) 0%, transparent 35%),
    radial-gradient(circle at 90% 10%, rgb(20 201 201 / 18%) 0%, transparent 30%),
    linear-gradient(135deg, $bg-gradient-start 0%, $bg-gradient-mid 45%, $bg-gradient-end 100%);

  &::before,
  &::after {
    position: absolute;
    pointer-events: none;
    background: radial-gradient(circle, $bg-accent-1 0%, transparent 60%);
    content: '';
    opacity: 0.7;
    filter: blur(80px);
    animation: auroraShift 18s ease-in-out infinite alternate;
    inset: -30%;
  }

  &::after {
    background: radial-gradient(circle, $bg-accent-2 0%, transparent 60%);
    animation-delay: 4s;
    animation-duration: 22s;
  }

  .my-container {
    display: flex;
    height: 100%;
    flex-direction: column;
  }
}

.cyber-bg {
  position: fixed;
  top: 0;
  left: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  background: radial-gradient(circle at 20% 30%, rgb(34 123 255 / 18%) 0%, transparent 45%),
    radial-gradient(circle at 80% 70%, rgb(123 97 255 / 15%) 0%, transparent 50%),
    radial-gradient(circle at 50% 50%, rgb(0 255 240 / 8%) 0%, transparent 55%);
  opacity: 0.5;
  filter: blur(10px);
}

.cyber-grid {
  position: fixed;
  top: 0;
  left: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  background-image: linear-gradient(rgb(255 255 255 / 5%) 1px, transparent 1px),
    linear-gradient(90deg, rgb(255 255 255 / 5%) 1px, transparent 1px);
  background-position: center;
  background-size: 40px 40px;
  opacity: 0.35;
  mix-blend-mode: screen;
}

.main-content-large {
  display: grid;
  min-height: 0;
  margin-bottom: 15px;
  flex: 1;
  grid-template-columns: 1fr 2fr;
  gap: 20px;
}

:deep(.el-input__wrapper) {
  padding: 15px 20px !important;
  font-size: 16px !important;
  background: rgb(255 255 255 / 10%) !important;
  border-radius: 10px !important;
}

:deep(.el-input__inner) {
  font-size: 16px !important;
  color: $text-light !important;
}

:deep(.el-button) {
  display: flex !important;
  padding: 12px 24px !important;
  font-size: 16px !important;
  font-weight: 500 !important;
  border-radius: 10px !important;
  transition: all 0.3s !important;
  align-items: center !important;
  gap: 8px !important;
}

:deep(.el-button--primary) {
  background: linear-gradient(90deg, $primary-color, $accent-color) !important;
  border: none !important;
  box-shadow: 0 4px 15px rgb(26 115 232 / 30%) !important;
}

:deep(.el-button--primary:hover) {
  transform: translateY(-2px) !important;
  box-shadow: 0 8px 25px rgb(26 115 232 / 40%) !important;
}

/* 全部设备视图样式 */
.all-devices-view {
  padding: 10px 0 20px;

  .all-devices-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;

    h3 {
      margin: 0;
      font-size: 18px;
    }

    .actions {
      display: flex;
      gap: 10px;
    }
  }

  .device-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
  }

  .device-card {
    background: rgb(255 255 255 / 6%);
    border: 1px solid rgb(255 255 255 / 12%);
    border-radius: 12px;
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;

    .device-card-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      .device-type {
        font-weight: 600;
      }
      .device-code {
        color: $text-gray;
        font-size: 12px;
      }
    }

    .device-meta {
      display: grid;
      grid-template-columns: 1fr;
      gap: 4px;
      color: $text-gray;
      font-size: 14px;
    }

    .device-history {
      background: rgb(255 255 255 / 4%);
      border: 1px solid rgb(255 255 255 / 10%);
      border-radius: 8px;
      padding: 8px;

      .history-title {
        font-size: 13px;
        color: #cfd3dc;
        margin-bottom: 6px;
      }

      .history-list {
        list-style: none;
        padding: 0;
        margin: 0;
        display: flex;
        flex-direction: column;
        gap: 6px;

        li {
          display: grid;
          grid-template-columns: 150px 1fr;
          gap: 8px;
          font-size: 12px;

          .time {
            color: #a5b1c2;
          }
          .content {
            color: #ffffff;
          }
        }
      }
    }

    .device-actions {
      display: flex;
      justify-content: flex-end;
    }
  }
}
/* 右上角悬浮按钮 */
.realtime-fab {
  position: fixed;
  top: 230px;
  right: 16px;
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border: none;
  border-radius: 50%;
  color: #fff;
  background: var(--el-color-warning);
  box-shadow: 0 6px 18px rgb(0 0 0 / 35%);
  backdrop-filter: blur(6px);
  z-index: 999;
  transition: all 0.2s ease;
}

.realtime-fab:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 26px rgb(0 0 0 / 45%);
  background: #ffb74d;
}

.realtime-fab:active {
  transform: translateY(0);
}

// .realtime-fab :deep(svg),
// .realtime-fab :deep(span) {
//   width: 22px !important;
//   height: 22px !important;
// }
</style>

<style lang="scss">
/* 滚动条优化 */
.elderly-scroll-container::-webkit-scrollbar,
.detail-section::-webkit-scrollbar,
.history-list::-webkit-scrollbar {
  width: 8px;
}

.elderly-scroll-container::-webkit-scrollbar-track,
.detail-section::-webkit-scrollbar-track,
.history-list::-webkit-scrollbar-track {
  background: rgb(255 255 255 / 5%);
  border-radius: 4px;
}

.elderly-scroll-container::-webkit-scrollbar-thumb,
.detail-section::-webkit-scrollbar-thumb,
.history-list::-webkit-scrollbar-thumb {
  background: rgb(26 115 232 / 50%);
  border-radius: 4px;
}
.large-screen-dialog {
  margin-top: 8vh !important;
  background: #1a1f2e !important;
  border: 1px solid rgb(255 255 255 / 10%) !important;
  border-radius: 16px !important;
  box-shadow: 0 20px 60px rgb(0 0 0 / 40%) !important;

  .el-dialog__header {
    padding: 25px !important;
    margin-top: 20px;
    color: white !important;
    background: linear-gradient(90deg, var(--el-color-primary), #7b61ff) !important;
    border-radius: 16px 16px 0 0 !important;
  }

  .el-dialog__title {
    font-size: 20px !important;
    font-weight: 600 !important;
    color: white !important;
  }

  .el-dialog__body {
    padding: 30px !important;
    color: #fff !important;
  }
}
.my-warning-notification {
  color: #fff !important;
  background: linear-gradient(135deg, #1e4184 0%, #3469e3 100%) !important;
  border: 1px solid rgb(42 157 143 / 30%) !important;
  box-shadow: 0 4px 20px rgb(0 0 0 / 50%) !important;

  .el-notification__group {
    .el-notification__title {
      color: #fff !important;
    }
  }
}
</style>
