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

    <div class="my-container">
      <!-- 大屏顶部信息栏 -->
      <div class="top-info-bar">
        <div class="system-title-section">
          <h1 class="system-title">智慧养老监护</h1>
          <p class="system-subtitle">智能守护 • 安心养老 • 实时监控</p>
        </div>
        <div class="time-display">
          <div class="current-date">{{ currentDate }}</div>
          <div class="current-time">{{ currentTime }}</div>
          <button class="fullscreen-btn" @click="toggleFullScreen">
            <Icon icon="ep:full-screen" />
          </button>
        </div>
      </div>

      <!-- 统计信息 - 大屏优化 -->
      <div class="stats-grid-large">
        <div
          v-for="stat in largeScreenStats"
          :key="stat.label"
          :class="['stat-card-large', { clickable: stat.clickable }]"
          @click="handleStatCardClick(stat)"
        >
          <div class="stat-icon-large">
            <Icon :icon="stat.icon" />
          </div>
          <div class="stat-content-large">
            <div class="stat-value-large">{{ stat.value }}</div>
            <div class="stat-label-large">{{ stat.label }}</div>
            <div class="stat-trend" :class="stat.trend">
              <span class="trend-icon">{{ stat.trend === 'up' ? '↗' : '→' }}</span>
              <span class="trend-value">{{ stat.change }}</span>
            </div>
          </div>
        </div>
      </div>

      <div class="main-content-large">
        <!-- 左侧：老人列表 -->
        <div class="elderly-list-section">
          <!-- 添加长者按钮 -->
          <el-button
            type="primary"
            size="large"
            @click="openAddElderDialog"
            style="width: 95%; margin: 5px auto 0"
          >
            <Icon icon="ep:plus" />
            <span>添加长者</span>
          </el-button>
          <div class="section-header-large">
            <h2>老人列表</h2>
            <div class="search-section-large">
              <el-input
                v-model="searchQuery"
                placeholder="搜索老人或设备..."
                clearable
                size="large"
              >
                <template #prefix>
                  <Icon icon="ep:search" />
                </template>
              </el-input>
            </div>
          </div>

          <div class="elderly-scroll-container">
            <div class="elderly-grid-large">
              <div
                class="elderly-card-large"
                v-for="elderly in filteredElderlyList"
                :key="elderly.id"
                :class="{
                  active: selectedElderly?.id === elderly.id,
                  flashing: elderly._flashEffect
                }"
                @click="selectElderly(elderly)"
              >
                <div class="elderly-avatar-large">
                  <el-image
                    v-if="elderly.avatar"
                    style="width: 32px; height: 32px"
                    :src="elderly.avatar"
                    fit="fill"
                  />
                  <Icon v-else icon="mdi:account-tie" />
                </div>
                <div class="elderly-info-large">
                  <h3>{{ elderly.name }}</h3>
                  <p> {{ elderly.age || 0 }}岁 • {{ genderMap[elderly.gender] || '未知' }} </p>
                  <div class="health-status-large">
                    <div class="status-dot" :class="getHealthStatusClass(elderly.healthText)"></div>
                    <span>{{ elderly.healthText || '未知' }}</span>
                  </div>
                </div>
                <div class="elderly-actions">
                  <div class="device-count">
                    <span>{{ elderly.deviceNumber || 0 }} 个设备</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 右侧：详细信息 -->
        <div class="detail-section" v-if="selectedElderly">
          <div class="detail-header">
            <h2>{{ selectedElderly.name }}的详细信息</h2>
          </div>

          <div class="health-metrics">
            <h3>健康指标</h3>
            <div
              class="metrics-grid"
              v-if="selectedElderly.healthList && selectedElderly.healthList?.length"
            >
              <div
                class="metric-card"
                v-for="(metric, index) in selectedElderly.healthList"
                :key="index"
              >
                <div class="metric-icon">
                  <Icon :icon="getHealthIcon(metric)" />
                </div>
                <div class="metric-info">
                  <div class="metric-value">{{ metric.value }}{{ metric.unit }}</div>
                  <div class="metric-name">{{ metric.name }}</div>
                </div>
                <div
                  class="metric-trend"
                  :class="metric.status.includes('警') ? 'warning' : 'normal'"
                >
                  {{ metric.status }}
                </div>
              </div>
            </div>
            <el-empty v-else description="暂无健康指标" image-size="40" />
          </div>

          <div class="devices-section-large">
            <div class="devices-header">
              <h3>设备监控</h3>
              <el-button type="primary" size="large" @click="openAddDeviceDialog(selectedElderly)">
                <Icon icon="ep:plus" />
                <span>添加设备</span>
              </el-button>
            </div>
            <div
              class="devices-grid-large"
              v-if="selectedElderly.deviceList && selectedElderly.deviceList?.length"
            >
              <div
                class="device-card-large"
                v-for="(device, index) in selectedElderly.deviceList"
                :key="index"
                :class="getDeviceStatusInfo(device).class"
              >
                <div class="device-header">
                  <div class="device-icon-large">
                    <Icon :icon="getDeviceInfo(device).icon" />
                  </div>
                  <div class="device-info-large">
                    <h4>
                      {{
                        deviceTypeOptions?.find(
                          (v: DeviceTypeVO) => v.deviceType == device.deviceType
                        )?.deviceTypeName || '-'
                      }}
                    </h4>
                    <p>{{ device.installPosition }}</p>
                  </div>
                  <el-tag :type="getDeviceStatusInfo(device).tagType">
                    {{ getDeviceStatusInfo(device).text }}
                  </el-tag>
                </div>
                <div class="device-data">
                  <p>{{ device.indicatorText || '-' }}</p>
                </div>
                <div class="device-actions-large">
                  <el-button type="primary" size="small" @click.stop="showDeviceDetail(device)">
                    查看详情
                  </el-button>
                  <el-button
                    type="danger"
                    size="small"
                    @click.stop="removeDevice(selectedElderly, device)"
                  >
                    移除
                  </el-button>
                </div>
              </div>
            </div>
            <el-empty v-else description="暂无设备" image-size="40" />
          </div>
        </div>

        <div class="detail-placeholder" v-else>
          <div class="placeholder-content">
            <div class="placeholder-icon">
              <Icon icon="mdi:gesture-tap" />
            </div>
            <h3>请选择一位老人查看详细信息</h3>
            <p>点击左侧老人卡片查看健康数据和设备状态</p>
          </div>
        </div>
      </div>

      <!-- 底部状态栏 -->
      <div class="status-bar">
        <div class="status-info">
          <span
            >系统状态:
            <span class="status-online">{{
              largeScreenStatsData.systemStatus || '未知状态'
            }}</span></span
          >
          <span>最后数据同步: {{ largeScreenStatsData.lastTime || '-' }}</span>
        </div>
        <div class="alert-indicator" :class="{ active: hasAlerts }">
          {{ hasAlerts ? '有警告设备需要关注' : '所有设备运行正常' }}
        </div>
      </div>
    </div>

    <!-- 添加设备对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="'为' + (currentElderly ? currentElderly.name : '') + '添加设备'"
      width="600px"
      append-to-body
      center
      :before-close="closeDialog"
      class="large-screen-dialog"
    >
      <el-form ref="deviceFormRef" :model="addDeviceForm" :rules="formRules" label-width="100px">
        <el-form-item label="设备类型" prop="deviceType">
          <el-select
            v-model="addDeviceForm.deviceType"
            placeholder="请选择设备类型"
            style="width: 100%"
            size="large"
          >
            <el-option
              v-for="item in deviceTypeOptions"
              :key="item.deviceType"
              :label="item.deviceTypeName"
              :value="item.deviceType"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="设备码" prop="deviceCode">
          <el-input v-model="addDeviceForm.deviceCode" placeholder="请输入设备码" size="large" />
        </el-form-item>
        <el-form-item label="设备位置" prop="installPosition">
          <el-input
            v-model="addDeviceForm.installPosition"
            placeholder="请输入设备安装位置"
            size="large"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="closeDialog" size="large">取消</el-button>
        <el-button type="primary" @click="addDevice" size="large">确认添加</el-button>
      </template>
    </el-dialog>

    <!-- 设备详情对话框 -->
    <el-dialog
      v-model="deviceDetailVisible"
      :title="
        (deviceTypeOptions?.find((v: DeviceTypeVO) => v.deviceType == deviceDetail?.deviceType)
          ?.deviceTypeName || '-') + ' - 详细信息'
      "
      width="700px"
      append-to-body
      class="large-screen-dialog"
    >
      <div class="device-detail-content" v-if="deviceDetail">
        <div class="device-detail-header">
          <div class="device-icon-xlarge">
            <Icon :icon="getDeviceInfo(deviceDetail).icon" />
          </div>
          <div class="device-detail-info">
            <h3>
              {{
                deviceTypeOptions?.find(
                  (v: DeviceTypeVO) => v.deviceType == deviceDetail?.deviceType
                )?.deviceTypeName || '-'
              }}
            </h3>
            <p>设备类型: {{ deviceDetail.deviceType }}</p>
            <p>安装位置: {{ deviceDetail.installPosition }}</p>
            <p>
              设备状态:
              <el-tag :type="textStatusMap[deviceDetail.status]">
                {{ deviceDetail.status }}
              </el-tag>
            </p>
          </div>
        </div>

        <div class="device-data-detail">
          <h4>设备数据</h4>
          <div
            class="data-grid"
            v-if="deviceDetail.indicatorInfo && deviceDetail.indicatorInfo?.length"
          >
            <div class="data-item" v-for="(item, value) in deviceDetail.indicatorInfo" :key="value">
              <span class="data-label">{{ item.name }}</span>
              <span class="data-value">{{ item.value }}</span>
            </div>
          </div>
          <el-empty v-else description="暂无设备" image-size="40" />
        </div>

        <div class="device-history">
          <h4>历史记录</h4>
          <div
            class="history-list"
            v-if="deviceDetail.historyInfo && deviceDetail.historyInfo?.length"
          >
            <div
              class="history-item"
              v-for="(record, index) in deviceDetail.historyInfo"
              :key="index"
            >
              <span class="history-time">{{
                record.happensAt ? formatToDateTime(record.happensAt) : ''
              }}</span>
              <span class="history-event">{{ record.content }}</span>
            </div>
          </div>
          <el-empty v-else description="暂无历史记录" image-size="40" />
        </div>
      </div>
      <template #footer>
        <el-button @click="deviceDetailVisible = false" size="large">关闭</el-button>
      </template>
    </el-dialog>

    <!-- 设备预警历史抽屉 -->
    <el-drawer
      v-model="warningDrawerVisible"
      direction="rtl"
      size="520px"
      class="warning-drawer"
      :title="`设备预警历史 (共${total}条)`"
      append-to-body
      @close="closeWarningDrawer"
    >
      <div class="warning-drawer-content">
        <div class="warning-history">
          <div class="history-list" v-if="warningData.length">
            <div class="history-item" v-for="(record, index) in warningData" :key="index">
              <div class="history-header">
                <span class="history-time">{{ record.happensAt }}</span>
              </div>
              <div class="history-event">{{ record.content }}</div>
            </div>
          </div>
          <el-empty v-else description="暂无报警记录" />

          <!-- 分页组件 -->
          <div class="pagination-container" v-if="total > 0">
            <el-pagination
              v-model:current-page="pageNum"
              v-model:page-size="pageSize"
              :page-sizes="[5, 10, 20, 50]"
              :small="false"
              :background="true"
              layout="total, sizes, prev, pager, next, jumper"
              :total="total"
              @size-change="handleSizeChange"
              @current-change="handlePageChange"
            />
          </div>
        </div>
      </div>
    </el-drawer>

    <!-- 在设备详情对话框后面添加添加长者对话框 -->
    <el-dialog
      v-model="addElderDialogVisible"
      title="添加长者"
      width="500px"
      append-to-body
      center
      class="large-screen-dialog"
    >
      <el-form ref="elderFormRef" :model="addElderForm" :rules="elderFormRules" label-width="80px">
        <el-form-item label="姓名" prop="name">
          <el-input
            v-model="addElderForm.name"
            placeholder="请输入长者姓名"
            size="large"
            maxlength="20"
          />
        </el-form-item>
        <el-form-item label="地址" prop="address">
          <el-input
            v-model="addElderForm.address"
            placeholder="请输入长者地址"
            size="large"
            type="textarea"
            :rows="3"
            maxlength="100"
            show-word-limit
          />
        </el-form-item>
        <el-form-item label="性别" prop="gender">
          <el-select v-model="addElderForm.gender" size="large" placeholder="请选择性别">
            <el-option label="男" :value="1" />
            <el-option label="女" :value="0" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="closeAddElderDialog" size="large">取消</el-button>
        <el-button type="primary" @click="submitAddElder" size="large">确认添加</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
import fetchHttp from '@/config/axios/fetchHttp'
import { getAccessToken } from '@/utils/auth'
import { formatToDateTime } from '@/utils/dateUtil'

interface WarningHistory {
  happensAt: string
  content: 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
}

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[]
}

type DeviceStatusTag = 'success' | 'warning' | 'danger' | 'info' | 'primary'

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 healthIconMap: Record<string, string> = {
  血氧: 'mdi:oxygen-tank',
  心率: 'mdi:heart-pulse',
  血压: 'mdi:blood-bag',
  体温: 'mdi:thermometer',
  血糖: 'mdi:needle',
  血脂: 'mdi:blood-bag',
  呼吸频率: 'mdi:lungs',
  步数: 'mdi:walk',
  睡眠: 'mdi:sleep',
  体重: 'mdi:scale',
  身高: 'mdi:human-male-height',
  BMI: 'mdi:human-male-height-variant',
  运动量: 'mdi:run',
  卡路里: 'mdi:fire',
  水分摄入: 'mdi:cup-water',
  血氧饱和度: 'mdi:oxygen-tank',
  心电图: 'mdi:heart-flash',
  肺功能: 'mdi:lungs',
  骨密度: 'mdi:bone',
  视力: 'mdi:eye',
  听力: 'mdi:ear-hearing',
  胆固醇: 'mdi:blood-bag',
  尿酸: 'mdi:flask',
  肝功能: 'mdi:liver',
  肾功能: 'mdi:kidney',
  血糖波动: 'mdi:chart-line',
  血压波动: 'mdi:chart-areaspline',
  心率变异性: 'mdi:chart-bell-curve',
  睡眠时长: 'mdi:clock-sleep',
  深睡时长: 'mdi:sleep',
  浅睡时长: 'mdi:sleep',
  REM睡眠: 'mdi:sleep',
  入睡时间: 'mdi:clock-start',
  醒来时间: 'mdi:clock-end',
  夜间醒来次数: 'mdi:alert-circle',
  日间活动量: 'mdi:walk',
  静息心率: 'mdi:heart',
  最大心率: 'mdi:heart',
  最低心率: 'mdi:heart',
  收缩压: 'mdi:blood-bag',
  舒张压: 'mdi:blood-bag',
  平均血压: 'mdi:blood-bag',
  血糖餐前: 'mdi:food',
  血糖餐后: 'mdi:food',
  血糖空腹: 'mdi:food-off',
  血氧夜间: 'mdi:weather-night',
  血氧日间: 'mdi:weather-sunny',
  呼吸暂停: 'mdi:alert',
  打鼾指数: 'mdi:volume-high',
  体温晨起: 'mdi:weather-sunset-up',
  体温晚间: 'mdi:weather-sunset-down',
  体重变化: 'mdi:chart-line',
  BMI趋势: 'mdi:trending-up',
  水分平衡: 'mdi:water-percent',
  运动强度: 'mdi:run-fast',
  卡路里消耗: 'mdi:fire',
  睡眠效率: 'mdi:percent',
  睡眠评分: 'mdi:star',
  健康评分: 'mdi:star',
  压力指数: 'mdi:alert',
  情绪状态: ' mdi:emoticon-happy',
  认知功能: 'mdi:brain',
  平衡能力: 'mdi:scale-balance',
  握力: 'mdi:hand-back-right',
  步行速度: 'mdi:speedometer',
  日常活动: 'mdi:home',
  用药依从性: 'mdi:pill',
  复诊提醒: 'mdi:calendar',
  紧急呼叫: 'mdi:alert-circle'
}

// 设备类型映射
const deviceTypeMap: Record<
  string,
  {
    name: string
    icon: string
    color: string
  }
> = {
  ['health_band']: { name: '健康监测手环', icon: 'mdi:watch-variant', color: '#ff6b6b' },
  ['smart_mattress']: { name: '智能床垫', icon: 'mdi:bed-queen', color: '#4ecdc4' },
  ['security_camera']: { name: '安防摄像头', icon: 'mdi:cctv', color: '#45aaf2' },
  ['blood_pressure_monitor']: {
    name: '血压监测仪',
    icon: 'mdi:heart-pulse',
    color: '#a55eea'
  },
  ['emergency_button']: {
    name: '紧急呼叫按钮',
    icon: 'mdi:alarm-light',
    color: '#fd9644'
  },
  ['smoke_sensor']: { name: '烟雾传感器', icon: 'mdi:smoke-detector', color: '#26de81' },
  ['water_sensor']: { name: '水浸传感器', icon: 'mdi:water-alert', color: '#26de81' },
  ['infrared_sensor']: {
    name: '人体红外传感器',
    icon: 'mdi:motion-sensor',
    color: '#26de81'
  },
  ['door_sensor']: { name: '门磁传感器', icon: 'mdi:door-closed', color: '#26de81' },
  ['gas_sensor']: { name: '燃气传感器', icon: 'mdi:gas-cylinder', color: '#26de81' },
  ['temperature_sensor']: {
    name: '温度传感器',
    icon: 'mdi:thermometer',
    color: '#ff6b6b'
  },
  ['humidity_sensor']: {
    name: '湿度传感器',
    icon: 'mdi:water-percent',
    color: '#48dbfb'
  },
  ['fall_detection_sensor']: {
    name: '跌倒检测传感器',
    icon: 'mdi:human-falling',
    color: '#ff9ff3'
  },
  ['pill_box']: {
    name: '智能药盒',
    icon: 'mdi:pill',
    color: '#1dd1a1'
  },
  ['oxygen_saturation_monitor']: {
    name: '血氧监测仪',
    icon: 'mdi:heart-pulse',
    color: '#a55eea'
  },
  ['glucose_meter']: {
    name: '血糖仪',
    icon: 'mdi:needle',
    color: '#fed330'
  }
}

const textStatusMap = {
  在线: 'success',
  离线: 'danger',
  警告: 'warning'
}

// 设备状态映射
const deviceStatusMap: Record<
  string,
  {
    text: string
    class: string
    tagType: DeviceStatusTag
  }
> = {
  ['在线']: { text: '在线', class: 'online', tagType: 'success' },
  ['离线']: { text: '离线', class: 'offline', tagType: 'danger' },
  ['警告']: { text: '警告', class: 'warning', tagType: 'warning' }
}

const organizationId = localStorage.getItem('organizationId')

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

// 设备类型选项
const deviceTypeOptions = ref<DeviceTypeVO[]>([])
const warningDrawerVisible = ref(false)
const warningData = ref<WarningHistory[]>([])
const deviceDetail = ref<Device | null>(null)
const deviceFormRef = ref()
const currentDate = ref('')
const currentTime = ref('')
const lastSyncTime = ref('')
const timeInterval = ref<ReturnType<typeof setInterval> | null>(null)
const largeScreenStatsData = ref<StatisticsVO>({
  systemStatus: '',
  lastTime: '',
  isWarning: false
})

const addDeviceForm = reactive({
  elderlyId: null as number | null,
  deviceType: '',
  deviceCode: '',
  installPosition: ''
})

const genderMap = {
  0: '女',
  1: '男'
}

// 在响应式数据部分添加
const addElderDialogVisible = ref(false)
const elderFormRef = ref()
const addElderForm = reactive({
  name: '',
  address: '',
  gender: 1 // 默认男性
})

// 添加长者表单验证规则
const elderFormRules = {
  name: [
    { required: true, message: '请输入长者姓名', trigger: 'blur' },
    { min: 2, max: 20, message: '姓名长度在 2 到 20 个字符', trigger: 'blur' }
  ],
  address: [
    { required: true, message: '请输入长者地址', trigger: 'blur' },
    { min: 5, max: 100, message: '地址长度在 5 到 100 个字符', trigger: 'blur' }
  ],
  gender: [{ required: true, message: '请选择性别', trigger: 'change' }]
}

// 表单规则
const formRules = {
  deviceType: [{ required: true, message: '请选择设备类型', trigger: 'change' }],
  deviceCode: [{ required: true, message: '请输入设备码', trigger: 'blur' }],
  installPosition: [{ required: true, message: '请输入设备位置', trigger: 'blur' }]
}

// 计算属性
const filteredElderlyList = computed(() => {
  if (!searchQuery.value) {
    return elderlyList.value
  }
  const query = searchQuery.value.toLowerCase()
  return elderlyList.value.filter((elderly) => elderly.name.toLowerCase().includes(query))
})

// 大屏专用统计信息
const largeScreenStats = ref<LargeScreenStat[]>([
  {
    icon: 'mdi:account-group',
    value: 0,
    label: '老人数量',
    trend: 'up',
    change: '',
    indicator: 'elderCount'
  },
  {
    icon: 'mdi:devices',
    value: 0,
    label: '设备总数',
    trend: 'up',
    change: '',
    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 isFullscreen = ref(false)
// 监听全屏状态变化
const handleFullscreenChange = () => {
  isFullscreen.value = !!document.fullscreenElement
}

document.addEventListener('fullscreenchange', handleFullscreenChange)
const toggleFullScreen = () => {
  if (!document.fullscreenElement) {
    document.documentElement.requestFullscreen().catch((err) => {
      ElMessage.error(`全屏请求失败: ${err.message}`)
    })
  } else {
    if (document.exitFullscreen) {
      document.exitFullscreen()
    }
  }
}

// 添加相关方法
const openAddElderDialog = () => {
  addElderForm.name = ''
  addElderForm.address = ''
  addElderForm.gender = 1
  addElderDialogVisible.value = true
  // 清除表单验证
  nextTick(() => {
    if (elderFormRef.value) {
      elderFormRef.value.clearValidate()
    }
  })
}

const closeAddElderDialog = () => {
  addElderDialogVisible.value = false
}

const submitAddElder = async () => {
  if (!elderFormRef.value) return
  try {
    const valid = await elderFormRef.value.validate()
    if (!valid) return
    // 构建请求数据
    const elderData = {
      name: addElderForm.name,
      address: addElderForm.address,
      gender: addElderForm.gender
    }
    // 调用添加长者接口
    const res = await fetchHttp.post('/api/pc/admin/addElder', elderData, {
      headers: {
        Authorization: `Bearer ${getAccessToken()}`
      }
    })
    if (res) {
      ElMessage.success('长者添加成功！')
      closeAddElderDialog()
      // 刷新长者列表
      await getElderList()
    } else {
      ElMessage.error('长者添加失败！')
    }
  } catch (error) {
    console.error('添加长者失败:', error)
    ElMessage.error('添加长者时出现错误')
  }
}

// 方法
const openAddDeviceDialog = (elderly: SelectElderly) => {
  currentElderly.value = elderly
  addDeviceForm.elderlyId = elderly.id
  addDeviceForm.deviceType = ''
  addDeviceForm.deviceCode = ''
  addDeviceForm.installPosition = ''
  dialogVisible.value = true

  if (deviceFormRef.value) {
    deviceFormRef.value.clearValidate()
  }
}

// 取消添加设备
const closeDialog = () => {
  dialogVisible.value = false
  currentElderly.value = null
}

// 新增设备
const addDevice = async () => {
  if (!deviceFormRef.value) return
  try {
    const valid = await deviceFormRef.value.validate()
    if (!valid) return
    const newDevice = {
      deviceType: addDeviceForm.deviceType,
      deviceCode: addDeviceForm.deviceCode,
      elderId: Number(addDeviceForm.elderlyId),
      organizationId: Number(organizationId),
      installPosition: addDeviceForm.installPosition
    }
    const res = await fetchHttp.post('/api/pc/admin/bindDevice', newDevice, {
      headers: {
        Authorization: `Bearer ${getAccessToken()}`
      }
    })
    if (res) {
      ElMessage.success('设备添加成功！')
      closeDialog()
      getElderDeviceMessage(selectedElderly.value.id)
    } else {
      ElMessage.error('设备添加失败！')
    }
  } catch (error) {}
}

// 删除设备
const removeDevice = (elderly: any, device: DetailDevice) => {
  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 getHealthIcon = (metric: HealthVO) => {
  return healthIconMap[metric.name] || 'mdi:help-circle-outline'
  // return metric.icon || 'mdi:help-circle-outline'
}

const getDeviceInfo = (device: Device | DetailDevice) => {
  return (
    deviceTypeMap[device.deviceType] || {
      name: '未知设备',
      icon: 'mdi:help-circle-outline',
      color: '#a5b1c2'
    }
  )
  // return (
  //   deviceTypeOptions.valur?.find((v: DeviceTypeVO) => v.deviceType == device.deviceType)?.icon ||
  //   'mdi:help-circle-outline'
  // )
}

const getDeviceStatusInfo = (
  device: any
): { text: string; class: string; tagType: DeviceStatusTag } => {
  return deviceStatusMap[device.status] || { text: '未知', class: 'offline', tagType: 'info' }
}

const getHealthStatusClass = (healthText: string) => {
  if (!healthText) return ''
  if (healthText.includes('良好') || healthText.includes('稳定')) return 'good'
  if (healthText.includes('偏高') || healthText.includes('需关注')) return 'warning'
  return 'normal'
}

// 大屏专用方法
const selectElderly = (elderly: Elderly) => {
  selectedElderly.value.id = elderly.id
  selectedElderly.value.name = elderly.name
  getElderDeviceMessage(selectedElderly.value.id)
}

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

const closeWarningDrawer = () => {
  warningDrawerVisible.value = false
}

const handleStatCardClick = (stat: LargeScreenStat) => {
  if (stat.type !== 'warning' || stat.value === 0) return
  getAllWarning()
  warningDrawerVisible.value = true
}

const updateDateTime = () => {
  const now = new Date()
  currentDate.value = now.toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    weekday: 'long'
  })
  currentTime.value = now.toLocaleTimeString('zh-CN', {
    hour12: false,
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}

// 获取统计数据
const getStatistics = async () => {
  const res = await fetchHttp.get(
    '/api/pc/admin/getStatistics?organizationId=' + organizationId,
    {},
    {
      headers: {
        Authorization: `Bearer ${getAccessToken()}`
      }
    }
  )
  if (res.list && res.list.length) {
    let resData = JSON.parse(JSON.stringify(res.list))
    resData.forEach((v: any) => {
      let index = largeScreenStats.value.findIndex(
        (z: LargeScreenStat) => 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
      getElderDeviceMessage(selectedElderly.value.id)
    }
  }
}

// 查询设备详情
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()}`
      }
    }
  )
  res
  if (res) {
    selectedElderly.value.healthList = res.healthList
    selectedElderly.value.deviceList = res.deviceList
  }
  console.log(selectedElderly.value)
}

// 查询设备详情
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 handlePageChange = (newPageNum: number) => {
  pageNum.value = newPageNum
  getAllWarning()
}

const handleSizeChange = (newPageSize: number) => {
  pageSize.value = newPageSize
  pageNum.value = 1 // 重置到第一页
  getAllWarning()
}

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

// 生命周期
onMounted(() => {
  // 初始化时间
  updateDateTime()
  lastSyncTime.value = new Date().toLocaleTimeString('zh-CN', { hour12: false })
  // 设置定时器更新时间和同步状态
  timeInterval.value = setInterval(() => {
    updateDateTime()
    // 每5分钟更新一次同步时间
    if (new Date().getMinutes() % 5 === 0) {
      lastSyncTime.value = new Date().toLocaleTimeString('zh-CN', { hour12: false })
    }
  }, 1000)
  getAllDevices()
  // 获取数据
  getStatistics()
  getElderList()

  // 页面加载后自动连接
  setTimeout(() => {
    connect()
  }, 1000)

  // 页面可见性变化处理
  // 页面可见性变化处理
  document.addEventListener('visibilitychange', () => {
    if (document.hidden) {
      console.log('页面切换到后台')
    } else {
      console.log('页面回到前台')
      // 检查连接和心跳状态
      checkConnectionHealth()
    }
  })
  // 添加定期健康检查
  setInterval(() => {
    checkConnectionHealth()
  }, 30000) // 每30秒检查一次连接健康状态

  // 网络状态监测
  window.addEventListener('online', () => {
    if (!socket.value) {
      connect()
    }
  })

  window.addEventListener('offline', () => {
    console.log('网络连接断开')
  })
})

onUnmounted(() => {
  document.removeEventListener('fullscreenchange', handleFullscreenChange)
  if (timeInterval.value) {
    clearInterval(timeInterval.value)
  }

  // 清理所有定时器
  stopHeartbeat()
  if (reconnectTimeout) {
    clearTimeout(reconnectTimeout)
    reconnectTimeout = null
  }

  // 正常关闭连接
  if (socket.value) {
    socket.value.close(1000, '页面关闭')
    socket.value = null
  }
})

// websocket设备连接
// 响应式数据
const socket = ref(null)
const isConnecting = ref(false)
const connectionId = ref(null)
const reconnectAttempts = ref(0)
const maxReconnectAttempts = ref(10)
const lastActivityTime = ref('-')
const initTime = ref(new Date().toLocaleTimeString())
const events = ref([])
// 定时器引用
let heartbeatInterval = null
let heartbeatTimeout = null
let reconnectTimeout = null
let lastActivity = Date.now()
const heartbeatIntervalTime = 25000 // 25秒发送一次心跳
const heartbeatTimeoutTime = 10000 // 10秒心跳响应超时

// 添加心跳状态响应式变量
const heartbeatStatus = ref('normal') // normal: 正常, waiting: 等待响应, timeout: 超时, expired: 过期
const lastHeartbeatTime = ref(null) // 最后一次发送心跳的时间
const lastHeartbeatAckTime = ref(null) // 最后一次收到心跳响应的时间

// 连接websocket方法
const connect = () => {
  // 连接已存在或连接中，跳过重复连接
  if (isConnecting.value || socket.value) {
    return
  }
  isConnecting.value = true
  // 连接中...
  // 清除之前的重连定时器
  if (reconnectTimeout) {
    clearTimeout(reconnectTimeout)
    reconnectTimeout = null
  }
  try {
    const clientId = generateClientId()
    // 连接地址: ${wsUrl}
    const wsUrl = import.meta.env.VITE_API_WSS_URL + clientId
    socket.value = new WebSocket(wsUrl)
    socket.value.onopen = handleOpen
    socket.value.onmessage = handleMessage
    socket.value.onclose = handleClose
    socket.value.onerror = handleError
  } catch (error) {
    // 连接创建错误: ${error.message}
    handleConnectionFailure()
  }
}

const sendMessage = (message) => {
  if (socket.value && socket.value.readyState === WebSocket.OPEN) {
    try {
      socket.value.send(JSON.stringify(message))
      lastActivity = Date.now()
      updateLastActivity()
      return true
    } catch (error) {
      // 发送消息失败: ${error.message}
      return false
    }
  } else {
    // 无法发送消息: WebSocket未连接
    return false
  }
}

// 连接成功
const handleOpen = (event) => {
  isConnecting.value = false
  reconnectAttempts.value = 0
  lastActivity = Date.now()
  // WebSocket连接成功
  // 启动心跳机制
  startHeartbeat()
  // 发送身份验证消息
  let postData = {
    type: 'AUTH',
    clientType: 'homecare-web',
    clientId: generateClientId(),
    timestamp: Date.now(),
    accessToken: `Bearer ${getAccessToken()}`
  }
  sendMessage(postData)
}

// 获取到服务器发送的消息
const handleMessage = (event) => {
  try {
    lastActivity = Date.now()
    updateLastActivity()

    const data = JSON.parse(event.data)
    processIncomingData(data)
  } catch (error) {
    console.error('消息解析错误:', error, '原始数据:', event.data)
  }
}

// 处理心跳响应
const handleHeartbeatAck = (data) => {
  console.log('心跳消息', data)
  // 清除超时检测
  if (heartbeatTimeout) {
    clearTimeout(heartbeatTimeout)
    heartbeatTimeout = null
  }

  heartbeatStatus.value = 'normal'
  lastHeartbeatAckTime.value = Date.now()
  lastActivity = Date.now()
  updateLastActivity()

  console.log('💓 心跳响应正常')
}

// 新增：连接健康检查
const checkConnectionHealth = () => {
  if (!socket.value || socket.value.readyState !== WebSocket.OPEN) {
    return
  }

  const now = Date.now()
  const timeSinceLastActivity = now - lastActivity
  const timeSinceLastHeartbeat = now - (lastHeartbeatTime.value || 0)
  const totalTimeout = heartbeatIntervalTime + heartbeatTimeoutTime

  console.log('🔍 连接健康检查:')
  console.log('最后活动:', Math.round(timeSinceLastActivity / 1000) + '秒前')
  console.log('最后心跳:', Math.round(timeSinceLastHeartbeat / 1000) + '秒前')
  console.log('心跳状态:', heartbeatStatus.value)

  // 如果超过总超时时间无活动，认为连接已死
  if (timeSinceLastActivity > totalTimeout + 10000) {
    // 额外给10秒缓冲
    console.error('🚨 连接长时间无活动，可能已断开')
    heartbeatStatus.value = 'expired'
    handleHeartbeatExpired()
    return
  }

  // 如果心跳等待时间过长，发送测试消息
  if (heartbeatStatus.value === 'waiting' && timeSinceLastHeartbeat > heartbeatTimeoutTime + 5000) {
    console.warn('⚠️ 心跳响应延迟，发送测试消息')
    sendMessage({ type: 'PING', timestamp: now })
  }
}

const handleClose = (event) => {
  console.log(`WebSocket连接关闭: 代码 ${event.code}, 原因: ${event.reason || '未知'}`)

  isConnecting.value = false
  socket.value = null
  connectionId.value = null
  heartbeatStatus.value = 'expired' // 连接关闭时标记为过期

  // 停止心跳检测
  stopHeartbeat()

  // 清除可能存在的重连定时器
  if (reconnectTimeout) {
    clearTimeout(reconnectTimeout)
    reconnectTimeout = null
  }

  // 判断是否需要重连（非正常关闭且未超过最大重连次数）
  if (event.code !== 1000 && reconnectAttempts.value < maxReconnectAttempts.value) {
    reconnectAttempts.value++
    const delay = Math.min(3000 * Math.pow(1.5, reconnectAttempts.value - 1), 30000)

    console.log(
      `${Math.round(delay / 1000)}秒后尝试重连 (${reconnectAttempts.value}/${
        maxReconnectAttempts.value
      })`
    )

    reconnectTimeout = setTimeout(() => {
      // 检查是否已经重新连接
      if (!socket.value && !isConnecting.value) {
        connect()
      }
    }, delay)
  } else if (reconnectAttempts.value >= maxReconnectAttempts.value) {
    console.error('已达到最大重连次数，停止自动重连')
    heartbeatStatus.value = 'expired'
  }
}

const handleError = (event) => {
  console.error('WebSocket错误详情:', event)
}

// 修改心跳检测逻辑
const startHeartbeat = () => {
  // 先停止可能存在的旧心跳
  stopHeartbeat()

  // 初始化心跳状态
  heartbeatStatus.value = 'normal'
  lastHeartbeatTime.value = Date.now()

  // 定时发送心跳
  heartbeatInterval = setInterval(() => {
    // 检查连接状态
    if (!socket.value || socket.value.readyState !== WebSocket.OPEN) {
      console.log('连接已断开，停止心跳')
      heartbeatStatus.value = 'expired'
      stopHeartbeat()
      return
    }

    // 检查上次心跳是否过期（超过间隔+超时时间未收到响应）
    const now = Date.now()
    const timeSinceLastHeartbeat = now - lastHeartbeatTime.value
    const totalTimeout = heartbeatIntervalTime + heartbeatTimeoutTime

    if (lastHeartbeatTime.value && timeSinceLastHeartbeat > totalTimeout) {
      console.warn(
        `💔 心跳已过期，距离上次心跳${Math.round(timeSinceLastHeartbeat / 1000)}秒，触发重连`
      )
      heartbeatStatus.value = 'expired'
      handleHeartbeatExpired()
      return
    }

    // 发送心跳
    heartbeatStatus.value = 'waiting'
    lastHeartbeatTime.value = now
    let params = {
      type: 'HEARTBEAT',
      timestamp: now,
      clientTime: now
    }
    console.log('params', params)
    const success = sendMessage(params)

    if (success) {
      // 设置心跳超时检测
      if (heartbeatTimeout) {
        clearTimeout(heartbeatTimeout)
      }

      heartbeatTimeout = setTimeout(() => {
        console.warn('💔 心跳响应超时，连接可能已断开')
        heartbeatStatus.value = 'timeout'
        handleHeartbeatTimeout()
      }, heartbeatTimeoutTime)
    } else {
      console.warn('心跳发送失败，连接可能有问题')
      heartbeatStatus.value = 'timeout'
      handleHeartbeatTimeout()
    }
  }, heartbeatIntervalTime)
}

// 新增：处理心跳过期
const handleHeartbeatExpired = () => {
  console.error('🚨 心跳已过期，关闭连接并重新连接')

  // 停止所有定时器
  stopHeartbeat()

  // 关闭当前连接
  if (socket.value) {
    socket.value.close(1000, '心跳过期')
    socket.value = null
  }

  // 立即重新连接
  reconnectAttempts.value = 0 // 重置重连计数
  setTimeout(() => {
    if (!socket.value && !isConnecting.value) {
      console.log('开始心跳过期重连...')
      connect()
    }
  }, 1000)
}

// 新增：处理心跳超时
const handleHeartbeatTimeout = () => {
  console.warn('⏰ 心跳响应超时，关闭连接触发重连')

  // 停止心跳检测
  stopHeartbeat()

  // 主动关闭连接触发重连机制
  if (socket.value) {
    socket.value.close(1000, '心跳响应超时')
  }
}

const stopHeartbeat = () => {
  if (heartbeatInterval) {
    clearInterval(heartbeatInterval)
    heartbeatInterval = null
  }
  if (heartbeatTimeout) {
    clearTimeout(heartbeatTimeout)
    heartbeatTimeout = null
  }
}

const processIncomingData = (data) => {
  if (!data || !data.type) {
    // 收到无效消息格式
    return
  }

  switch (data.type) {
    case 'CONNECT_SUCCESS':
      handleConnectSuccess(data)
      break
    case 'AUTH_SUCCESS':
      handleAuthSuccess(data)
      break
    case 'SOS_ALERT':
      // 需要展示的数据
      handleSOSAlert(data)
      break
    case 'HEALTH_ALERT':
      handleHealthAlert(data)
      break
    case 'DEVICE_DATA_UPDATE':
      handleDeviceData(data)
      break
    case 'SYSTEM_STATS_UPDATE':
      handleStatsUpdate(data)
      break
    case 'HEARTBEAT_ACK':
      handleHeartbeatAck(data)
      break
    default:
      handleGenericMessage(data)
  }
}

const handleConnectSuccess = (data) => {
  console.log('WebSocket连接成功')
  // 连接成功，连接ID: ${connectionId.value}
  connectionId.value = data.connectionId
}

const handleAuthSuccess = (data) => {
  console.log('身份验证成功')
}

const handleSOSAlert = (alertData) => {
  console.log('alertData', alertData)
  try {
    const alert = alertData.data || alertData
    // 发送确认消息
    sendMessage({
      type: 'SOS_ACK',
      alertId: alertData.timestamp,
      timestamp: Date.now()
    })
    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>时间: ${new Date(alertData.timestamp).toLocaleString()}</div>
         `
      }),
      type: 'warning',
      duration: 10000
    })

    // 找出elderlyList.value里面id和healthAlertData.elderId一致的老人，将这个老人排序到elderlyList.value第一个，并且边框红色闪烁
    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)
      }
    }
  } catch (error) {
    console.error('处理SOS告警错误:', error)
  }
}

// 健康数据推送处理逻辑
const handleHealthAlert = (healthAlert) => {
  console.log('healthAlert', healthAlert)
  const healthAlertData = healthAlert.data

  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 || '0%'}</div>
        <div>时间: ${new Date(healthAlertData.timestamp).toLocaleString()}</div>
        `
    }),
    type: 'warning',
    duration: 10000
  })
  // 找出elderlyList.value里面id和healthAlertData.elderId一致的老人，将这个老人排序到elderlyList.value第一个，并且边框红色闪烁
  if (healthAlertData.elderId && elderlyList.value.length > 0) {
    const elderIndex = elderlyList.value.findIndex((elder) => elder.id === healthAlertData.elderId)
    if (elderIndex !== -1) {
      // 创建一个新数组，将指定的老人移到第一位
      const reorderedList = [...elderlyList.value]
      const [selectedElder] = reorderedList.splice(elderIndex, 1)
      reorderedList.unshift(selectedElder)
      // 更新列表
      elderlyList.value = reorderedList
      // 为对应的老人卡片添加闪烁效果
      addFlashingEffect(selectedElder)
      getElderDeviceMessage(healthAlertData.elderId)
    }
  }
}

// 添加一个方法来处理闪烁效果
const addFlashingEffect = (elder) => {
  // 添加一个临时的闪烁类名
  elder._flashEffect = true
  // 5秒后移除闪烁效果
  setTimeout(() => {
    elder._flashEffect = false
    // 强制重新渲染列表
    elderlyList.value = [...elderlyList.value]
  }, 10000)
}

const handleDeviceData = (deviceData) => {
  console.log('deviceData', deviceData)
}

const handleStatsUpdate = (statsData) => {
  console.log('statsData', statsData)
}

// 修改普通消息处理，不干扰心跳检测
const handleGenericMessage = (data) => {
  console.log('收到普通消息:', data)
  // 这里只更新最后活动时间，但不影响心跳超时检测
  lastActivity = Date.now()
  updateLastActivity()
}

const updateLastActivity = () => {
  lastActivityTime.value = new Date().toLocaleTimeString()
}

const generateClientId = () => {
  const timestamp = Date.now()
  const random = Math.random().toString(36).substr(2, 9)
  return `monitor_${timestamp}_${random}`
}

const handleConnectionFailure = () => {
  isConnecting.value = false
  socket.value = null

  // 连接创建失败也尝试重连
  if (reconnectAttempts.value < maxReconnectAttempts.value) {
    reconnectAttempts.value++
    const delay = Math.min(3000 * Math.pow(1.5, reconnectAttempts.value - 1), 30000)

    reconnectTimeout = setTimeout(() => {
      if (!socket.value && !isConnecting.value) {
        connect()
      }
    }, delay)
  }
}
</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%);
$border-radius: 12px;
$transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);

@keyframes pulse {
  0% {
    opacity: 1;
  }

  50% {
    opacity: 0.7;
  }

  100% {
    opacity: 1;
  }
}

@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);
  }
}

// 添加闪烁动画
@keyframes borderFlash {
  0%,
  100% {
    border-color: rgb(255 255 255 / 8%);
    box-shadow: 0 0 0 0 rgb(255 107 107 / 0%);
  }

  50% {
    border-color: $danger-color;
    box-shadow: 0 0 20px 5px rgb(255 107 107 / 50%);
  }
}

/* 大屏专用样式 */
.large-screen {
  position: relative;
  padding: 20px;
  overflow: hidden;
  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;
}

/* 顶部信息栏 */
.top-info-bar {
  display: flex;
  padding: 15px 25px;
  margin-bottom: 20px;
  background: rgb(26 31 46 / 90%);
  border: 1px solid rgb(255 255 255 / 15%);
  border-radius: 16px;
  justify-content: space-between;
  align-items: center;
}

.system-title-section {
  .system-title {
    margin-bottom: 5px;
    font-size: 36px;
    font-weight: 700;
    background: linear-gradient(90deg, $primary-color, $secondary-color, $accent-color);
    /* stylelint-disable-next-line property-no-vendor-prefix */
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
  }

  .system-subtitle {
    font-size: 18px;
    color: $text-gray;
  }
}

.time-display {
  text-align: right;

  .current-date {
    margin-bottom: 5px;
    font-size: 20px;
  }

  .current-time {
    font-size: 28px;
    font-weight: 600;
    color: $secondary-color;
  }
}

/* 大屏统计卡片 */
.stats-grid-large {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 15px;
  margin-bottom: 20px;
}

.stat-card-large {
  display: flex;
  padding: 25px;
  background: rgb(26 31 46 / 85%);
  border: 1px solid rgb(255 255 255 / 12%);
  border-radius: 16px;
  transition: $transition;
  align-items: center;
  gap: 20px;

  &:hover {
    transform: translateY(-5px);
    box-shadow: 0 10px 30px rgb(0 0 0 / 30%);
  }

  &.clickable {
    cursor: pointer;
    border-color: rgb(253 150 68 / 60%);

    &:hover {
      box-shadow: 0 10px 35px rgb(253 150 68 / 30%);
    }
  }
}

.stat-icon-large {
  display: flex;
  width: 80px;
  height: 80px;
  background: rgb(255 255 255 / 10%);
  border-radius: 16px;
  align-items: center;
  justify-content: center;

  :deep(svg),
  :deep(span) {
    width: 48px !important;
    height: 48px !important;
  }
}

.stat-content-large {
  flex: 1;
}

.stat-value-large {
  margin-bottom: 5px;
  font-size: 42px;
  font-weight: 700;
  background: linear-gradient(90deg, $primary-color, $secondary-color);
  /* stylelint-disable-next-line property-no-vendor-prefix */
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.stat-label-large {
  margin-bottom: 8px;
  font-size: 16px;
  color: $text-gray;
}

.stat-trend {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 14px;

  &.up {
    color: $success-color;
  }

  &.stable {
    color: #a5b1c2;
  }
}

/* 主内容区域 */
.main-content-large {
  display: grid;
  min-height: 0;
  margin-bottom: 15px;
  flex: 1;
  grid-template-columns: 1fr 2fr;
  gap: 20px;
}

/* 左侧老人列表 */
.elderly-list-section {
  display: flex;
  overflow: hidden;
  background: rgb(26 31 46 / 85%);
  border: 1px solid rgb(255 255 255 / 12%);
  border-radius: 16px;
  flex-direction: column;
}

.section-header-large {
  display: flex;
  padding: 20px;
  border-bottom: 1px solid rgb(255 255 255 / 10%);
  justify-content: space-between;
  align-items: center;

  h2 {
    font-size: 24px;
    font-weight: 600;
  }
}

.elderly-scroll-container {
  padding: 15px;
  overflow-y: auto;
  flex: 1;
}

.elderly-grid-large {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.elderly-card-large {
  display: flex;
  padding: 20px;
  cursor: pointer;
  background: rgb(255 255 255 / 5%);
  border: 1px solid rgb(255 255 255 / 8%);
  border-radius: 12px;
  transition: $transition;
  align-items: center;
  gap: 15px;

  &:hover,
  &.active {
    background: rgb(26 115 232 / 20%);
    border-color: rgb(26 115 232 / 50%);
    transform: translateX(5px);
  }
}

.elderly-card-large {
  display: flex;
  padding: 20px;
  cursor: pointer;
  background: rgb(255 255 255 / 5%);
  border: 1px solid rgb(255 255 255 / 8%);
  border-radius: 12px;
  transition: $transition;
  align-items: center;
  gap: 15px;

  &:hover,
  &.active {
    background: rgb(26 115 232 / 20%);
    border-color: rgb(26 115 232 / 50%);
    transform: translateX(5px);
  }

  // 添加闪烁样式
  &.flashing {
    position: relative;
    z-index: 1;
    animation: borderFlash 1s ease-in-out infinite;
  }
}

.elderly-avatar-large {
  display: flex;
  width: 60px;
  height: 60px;
  background: rgb(255 255 255 / 10%);
  border-radius: 50%;
  align-items: center;
  justify-content: center;

  :deep(svg),
  :deep(span) {
    width: 32px !important;
    height: 32px !important;
  }
}

.elderly-info-large {
  flex: 1;

  h3 {
    margin-bottom: 5px;
    font-size: 20px;
  }

  p {
    margin-bottom: 8px;
    color: $text-gray;
  }
}

.health-status-large {
  display: flex;
  align-items: center;
  gap: 8px;
}

.status-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  box-shadow: 0 0 10px currentcolor;
}

.status-dot.good {
  color: $success-color;
  background: $success-color;
}

.status-dot.warning {
  color: $warning-color;
  background: $warning-color;
}

.status-dot.normal {
  color: $primary-color;
  background: $primary-color;
}

.elderly-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}

.device-count {
  padding: 5px 10px;
  font-size: 14px;
  background: rgb(255 255 255 / 10%);
  border-radius: 20px;
}

.add-device-btn {
  white-space: nowrap;
}

/* 右侧详情区域 */
.detail-section {
  display: flex;
  padding: 25px;
  overflow-y: auto;
  background: rgb(26 31 46 / 85%);
  border: 1px solid rgb(255 255 255 / 12%);
  border-radius: 16px;
  flex-direction: column;
  gap: 25px;
}

.detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 15px;
  border-bottom: 1px solid rgb(255 255 255 / 10%);

  h2 {
    font-size: 28px;
  }

  .last-update {
    color: $text-gray;
  }
}

.health-metrics h3,
.devices-section-large h3 {
  margin-bottom: 15px;
  font-size: 22px;
}

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

.metrics-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 15px;
  margin-bottom: 20px;
}

.metric-card {
  display: flex;
  align-items: center;
  padding: 20px;
  background: rgb(255 255 255 / 5%);
  border-radius: 12px;
  gap: 15px;
}

.metric-icon {
  :deep(svg),
  :deep(span) {
    width: 32px !important;
    height: 32px !important;
  }
}

.metric-info {
  flex: 1;

  .metric-value {
    margin-bottom: 5px;
    font-size: 24px;
    font-weight: 600;
  }

  .metric-name {
    color: $text-gray;
  }
}

.metric-trend {
  padding: 5px 10px;
  font-size: 14px;
  border-radius: 20px;

  &.normal {
    color: $success-color;
    background: rgb(38 222 129 / 20%);
  }

  &.warning {
    color: $warning-color;
    background: rgb(253 150 68 / 20%);
  }
}

.devices-grid-large {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}

.device-card-large {
  display: flex;
  padding: 20px;
  cursor: default;
  background: rgb(255 255 255 / 5%);
  border: 1px solid rgb(255 255 255 / 8%);
  border-radius: 12px;
  flex-direction: column;
  gap: 15px;

  &.online {
    border-left: 4px solid $success-color;
  }

  &.offline {
    border-left: 4px solid $danger-color;
  }

  &.warning {
    cursor: pointer;
    border-left: 4px solid $warning-color;
    box-shadow: 0 0 20px rgb(253 150 68 / 25%);
  }
}

.device-header {
  display: flex;
  align-items: center;
  gap: 15px;
}

.device-icon-large {
  display: flex;
  width: 50px;
  height: 50px;
  background: rgb(26 115 232 / 20%);
  border-radius: 10px;
  align-items: center;
  justify-content: center;

  :deep(svg),
  :deep(span) {
    width: 32px !important;
    height: 32px !important;
  }
}

.device-info-large {
  flex: 1;

  h4 {
    margin-bottom: 5px;
    font-size: 18px;
  }

  p {
    color: $text-gray;
  }
}

.device-data {
  padding: 10px;
  font-size: 14px;
  background: rgb(255 255 255 / 3%);
  border-radius: 8px;
}

.device-actions-large {
  display: flex;
  gap: 10px;
}

.detail-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgb(26 31 46 / 85%);
  border: 1px solid rgb(255 255 255 / 12%);
  border-radius: 16px;

  .placeholder-content {
    text-align: center;

    .placeholder-icon {
      margin-bottom: 20px;

      :deep(svg),
      :deep(span) {
        width: 32px !important;
        height: 32px !important;
      }
    }

    h3 {
      margin-bottom: 10px;
      font-size: 24px;
    }

    p {
      color: $text-gray;
    }
  }
}

/* 底部状态栏 */
.fullscreen-btn {
  width: 40px;
  height: 40px;
  margin-left: 16px;
  color: white;
  cursor: pointer;
  background: rgb(255 255 255 / 20%);
  border: none;
  border-radius: 8px;
  transition: all 0.3s ease;
}

.fullscreen-btn:hover {
  background: rgb(255 255 255 / 30%);
}

.status-bar {
  display: flex;
  padding: 12px 25px;
  font-size: 14px;
  background: rgb(26 31 46 / 90%);
  border: 1px solid rgb(255 255 255 / 15%);
  border-radius: 12px;
  justify-content: space-between;
  align-items: center;
}

.status-info {
  display: flex;
  gap: 20px;

  .status-online {
    font-weight: 600;
    color: $success-color;
  }
}

.alert-indicator {
  padding: 5px 15px;
  background: rgb(166 177 194 / 20%);
  border-radius: 20px;

  &.active {
    color: $warning-color;
    background: rgb(253 150 68 / 30%);
    animation: pulse 2s infinite;
  }
}

/* 设备详情样式 */
.device-detail-content {
  .device-detail-header {
    display: flex;
    padding-bottom: 20px;
    margin-bottom: 25px;
    border-bottom: 1px solid rgb(255 255 255 / 10%);
    align-items: center;
    gap: 20px;
  }

  .device-icon-xlarge {
    display: flex;
    width: 80px;
    height: 80px;
    background: rgb(26 115 232 / 20%);
    border-radius: 16px;
    align-items: center;
    justify-content: center;

    :deep(svg),
    :deep(span) {
      width: 32px !important;
      height: 32px !important;
    }
  }

  .device-detail-info {
    flex: 1;

    h3 {
      margin-bottom: 10px;
      font-size: 24px;
    }

    p {
      margin-bottom: 5px;
      color: $text-gray;
    }
  }

  .device-data-detail {
    margin-bottom: 25px;

    h4 {
      margin-bottom: 15px;
      font-size: 18px;
    }

    .data-grid {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 15px;
    }

    .data-item {
      display: flex;
      justify-content: space-between;
      padding: 12px 15px;
      background: rgb(255 255 255 / 5%);
      border-radius: 8px;

      .data-label {
        color: $text-gray;
      }

      .data-value {
        font-weight: 600;
      }
    }
  }

  .device-history {
    h4 {
      margin-bottom: 15px;
      font-size: 18px;
    }

    .history-list {
      max-height: 200px;
      overflow-y: auto;
    }

    .history-item {
      display: flex;
      justify-content: space-between;
      padding: 10px 15px;
      border-bottom: 1px solid rgb(255 255 255 / 5%);

      .history-time {
        font-size: 14px;
        color: $text-gray;
      }
    }
  }
}

.warning-drawer {
  color: $text-light;
  background: linear-gradient(135deg, #111a3a, #0a1124);

  .el-drawer__header {
    padding-bottom: 10px;
    margin-bottom: 0;
    border-bottom: 1px solid rgb(255 255 255 / 10%);
  }

  .el-drawer__title {
    font-size: 20px;
    color: $text-light;
  }

  .el-drawer__body {
    padding: 20px;
  }
}

.warning-drawer-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.warning-device-header {
  display: flex;
  gap: 15px;
  align-items: center;
  padding: 15px;
  background: rgb(255 255 255 / 5%);
  border-radius: 12px;
}

.warning-device-info {
  flex: 1;

  h3 {
    margin-bottom: 6px;
    font-size: 20px;
  }

  p {
    margin-bottom: 8px;
    color: $text-gray;
  }
}

.warning-history {
  h4 {
    margin-bottom: 12px;
    font-size: 18px;
  }

  .history-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }

  .history-item {
    display: grid;
    padding: 15px;
    background: rgb(255 255 255 / 4%);
    border-radius: 12px;
    gap: 8px;
    grid-template-columns: 1fr auto;
    align-items: center;

    .history-time {
      font-size: 14px;
      color: $text-gray;
    }

    .history-event {
      grid-column: 1 / span 2;
      font-size: 16px;
    }
  }
}

.warning-summary {
  padding: 20px;
  background: rgb(255 255 255 / 4%);
  border-radius: 12px;

  h3 {
    margin-bottom: 8px;
    font-size: 20px;
  }

  p {
    color: $text-gray;
  }
}

/* 滚动条优化 */
.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;
}

/* Element Plus 组件大屏适配 */
:deep(.el-input__wrapper) {
  padding: 15px 20px !important;
  font-size: 16px !important;
  background: rgb(255 255 255 / 10%) !important;
  border-radius: 10px !important;
  box-shadow: 0 0 0 1px rgb(255 255 255 / 20%) !important;
}

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

:deep(.el-input__prefix),
:deep(.el-input__suffix) {
  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: $transition !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;
}

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

:deep(.el-select .el-input__wrapper),
:deep(.el-input .el-input__wrapper) {
  background: rgb(255 255 255 / 10%) !important;
}

:deep(.el-select-dropdown) {
  background: $card-bg !important;
  border: 1px solid rgb(255 255 255 / 20%) !important;
  border-radius: 10px !important;
}

:deep(.el-select-dropdown__item) {
  padding: 12px 20px !important;
  font-size: 16px !important;
  color: $text-light !important;
}

:deep(.el-select-dropdown__item.hover) {
  background: rgb(255 255 255 / 10%) !important;
}

:deep(.el-select-dropdown__item.selected) {
  background: $primary-color !important;
}

:deep(.el-empty__description) {
  color: $text-gray !important;
}

:deep(.el-empty) {
  padding: 10px !important;
}
</style>
<style lang="scss">
.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>
