<template>
  <div class="device-monitor-container">

<iframe src="http://121.4.16.100:28080/#/play/wasm/ws%3A%2F%2F121.4.16.100%3A6080%2Frtp%2F34020000001110000001_34020000001320000012.live.flv"></iframe>

    <!-- 控制面板 -->
    <div class="control-panel">
      <div class="control-left">
        <div class="form-group">
          <label>农场选择</label>
          <select v-model="selectedFarm">
            <option value="all">全部农场</option>
            <option value="farm1">东湖智慧农场</option>
            <option value="farm2">西湖有机农场</option>
          </select>
        </div>
        <div class="form-group">
          <label>地块选择</label>
          <select v-model="selectedArea">
            <option value="all">全部地块</option>
            <option value="area1">1号地块</option>
            <option value="area2">2号地块</option>
          </select>
        </div>
        <div class="form-group">
          <label>时间范围</label>
          <select v-model="timeRange">
            <option value="realtime">实时数据</option>
            <option value="1h">近1小时</option>
            <option value="24h">近24小时</option>
          </select>
        </div>
      </div>
      <div class="control-right">
        <button class="refresh-btn" @click="refreshData">
          <i class="icon-refresh"></i>
          刷新数据
        </button>
        <div class="auto-refresh">
          <span>自动刷新：</span>
          <select v-model="autoRefresh" class="auto-refresh-select">
            <option value="15">15秒</option>
            <option value="30">30秒</option>
            <option value="60">60秒</option>
          </select>
        </div>
        <div class="last-update">
          最后更新：<span>{{ lastUpdateTime }}</span>
        </div>
      </div>
    </div>

    <!-- 设备统计 -->
    <div class="stats-container">
      <!-- 综合统计卡片 -->
      <div class="overview-stat-card">
        <div class="overview-stats">
          <div class="overview-item">
            <div class="stat-number online">42</div>
            <div class="stat-label">在线设备</div>
          </div>
          <div class="overview-item">
            <div class="stat-number offline">3</div>
            <div class="stat-label">离线设备</div>
          </div>
          <div class="overview-item">
            <div class="stat-number alert">5</div>
            <div class="stat-label">告警设备</div>
          </div>
        </div>
      </div>

      <!-- 分类统计卡片 -->
      <div class="category-stats">
        <div class="stat-card">
          <div class="stat-number camera">12</div>
          <div class="stat-label">摄像头</div>
          <div class="stat-detail">11在线 / 1离线</div>
        </div>
        <div class="stat-card">
          <div class="stat-number sensor">15</div>
          <div class="stat-label">传感器</div>
          <div class="stat-detail">14在线 / 1告警</div>
        </div>
        <div class="stat-card">
          <div class="stat-number weather">8</div>
          <div class="stat-label">气象设备</div>
          <div class="stat-detail">7在线 / 1离线</div>
        </div>
        <div class="stat-card">
          <div class="stat-number control">10</div>
          <div class="stat-label">控制设备</div>
          <div class="stat-detail">10在线</div>
        </div>
        <div class="stat-card">
          <div class="stat-number alert">7</div>
          <div class="stat-label">今日告警</div>
          <div class="stat-detail"><span class="processed">5已处理</span></div>
        </div>
      </div>
    </div>

    <!-- 主要内容区域 -->
    <div class="main-content">
      <!-- 视频监控 -->
      <div class="content-section">
        <div class="video-header">
          <div class="video-header-left">
            <h2 class="section-title">视频监控</h2>
            <div class="video-count">
              共 {{ videoList.length }} 个摄像头
            </div>
          </div>
          <div class="video-header-right">
            <div class="video-nav-controls">
              <button class="video-nav-btn" @click="prevPage" :disabled="currentPage === 1" title="上一页">
                <svg class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor">
                  <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
                </svg>
              </button>
              <div class="page-indicator">
                <span>{{ getPageRange() }} / {{ videoList.length }}</span>
              </div>
              <button class="video-nav-btn" @click="nextPage" :disabled="currentPage === totalPages" title="下一页">
                <svg class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor">
                  <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
                </svg>
              </button>
            </div>
            <button class="video-nav-btn" @click="toggleFullscreen" title="全屏显示">
              <svg class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor">
                <path fill-rule="evenodd" d="M3 4a1 1 0 011-1h4a1 1 0 010 2H6.414l2.293 2.293a1 1 0 11-1.414 1.414L5 6.414V8a1 1 0 01-2 0V4zm9 1a1 1 0 010-2h4a1 1 0 011 1v4a1 1 0 01-2 0V6.414l-2.293 2.293a1 1 0 11-1.414-1.414L13.586 5H12zm-9 7a1 1 0 012 0v1.586l2.293-2.293a1 1 0 111.414 1.414L6.414 15H8a1 1 0 010 2H4a1 1 0 01-1-1v-4zm13-1a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 010-2h1.586l-2.293-2.293a1 1 0 111.414-1.414L15 13.586V12a1 1 0 011-1z" clip-rule="evenodd" />
              </svg>
            </button>
          </div>
        </div>

        <div class="video-container">
          <div class="video-grid">
            <div v-for="video in paginatedVideos" :key="video.id" class="video-card">
              <button class="camera-fullscreen-btn" @click="openVideoFullscreen(video)" title="全屏查看">
                <svg class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor">
                  <path fill-rule="evenodd" d="M3 4a1 1 0 011-1h4a1 1 0 010 2H6.414l2.293 2.293a1 1 0 11-1.414 1.414L5 6.414V8a1 1 0 01-2 0V4zm9 1a1 1 0 010-2h4a1 1 0 011 1v4a1 1 0 01-2 0V6.414l-2.293 2.293a1 1 0 11-1.414-1.414L13.586 5H12zm-9 7a1 1 0 012 0v1.586l2.293-2.293a1 1 0 111.414 1.414L6.414 15H8a1 1 0 010 2H4a1 1 0 01-1-1v-4zm13-1a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 010-2h1.586l-2.293-2.293a1 1 0 111.414-1.414L15 13.586V12a1 1 0 011-1z" clip-rule="evenodd" />
                </svg>
              </button>
              <div class="video-preview">
                <div class="camera-placeholder centered-container">
                  <svg class="camera-icon centered-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <path d="M23 7l-7 5 7 5V7z"/>
                    <rect x="1" y="5" width="15" height="14" rx="2" ry="2"/>
                  </svg>
                </div>
                <div class="video-info-overlay">
                  <div class="video-details">
                    <div class="video-name">{{ video.name }}</div>
                    <div class="video-location">{{ video.location }}</div>
                  </div>
                  <span class="video-status" :class="video.status">
                    {{ video.status === 'online' ? '在线' : '离线' }}
                  </span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 设备监控 -->
      <div class="content-section">
        <!-- 顶部控制栏 -->
        <div class="device-monitor-header">
          <div class="device-monitor-title-section">
            <h2 class="section-title">设备监控</h2>
            <div class="filter-buttons">
              <button class="filter-btn" :class="{ active: deviceFilter === 'all' }" @click="setFilter('all')">
                全部设备
                <span class="filter-count">({{ deviceList.length }})</span>
              </button>
              <button class="filter-btn" :class="{ active: deviceFilter === 'warning' }" @click="setFilter('warning')">
                <span class="status-dot warning"></span>
                告警设备
                <span class="filter-count">({{ getDeviceCountByStatus('warning') }})</span>
              </button>
              <button class="filter-btn" :class="{ active: deviceFilter === 'offline' }" @click="setFilter('offline')">
                <span class="status-dot offline"></span>
                离线设备
                <span class="filter-count">({{ getDeviceCountByStatus('offline') }})</span>
              </button>
            </div>
            <div class="filter-divider"></div>
            <div class="type-filters">
              <button class="filter-btn" :class="{ active: deviceTypeFilter === 'soil' }" @click="setTypeFilter('soil')">土壤监测</button>
              <button class="filter-btn" :class="{ active: deviceTypeFilter === 'water' }" @click="setTypeFilter('water')">水质监测</button>
              <button class="filter-btn" :class="{ active: deviceTypeFilter === 'weather' }" @click="setTypeFilter('weather')">气象监测</button>
            </div>
          </div>
          <div class="device-monitor-controls">
            <select class="sort-select" v-model="sortBy">
              <option value="alert">告警优先</option>
              <option value="time">更新时间</option>
              <option value="name">设备名称</option>
            </select>
            <div class="device-pagination">
              <button class="page-btn" @click="prevDevicePage" :disabled="deviceCurrentPage === 1">
                <svg class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor">
                  <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
                </svg>
              </button>
              <span class="page-indicator">{{ getDevicePageRange() }} / {{ filteredDevices.length }}</span>
              <button class="page-btn" @click="nextDevicePage" :disabled="deviceCurrentPage === deviceTotalPages">
                <svg class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor">
                  <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
                </svg>
              </button>
            </div>
          </div>
        </div>

        <!-- 设备卡片网格 -->
        <div class="device-grid">
          <div v-for="device in paginatedDevices" :key="device.id" class="device-card" :class="device.status">
            <!-- 右上角数据按钮 -->
            <button class="data-btn" @click="showDeviceHistory(device)" title="查看数据">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <path d="M12 20v-6M6 20V10M18 20V4"/>
              </svg>
            </button>

            <div class="device-header">
              <div class="device-title-row">
                <div class="device-name">{{ device.name }}</div>
                <div class="device-status" :class="device.status">{{ device.statusText }}</div>
              </div>
            </div>
            <div class="device-location">{{ device.location }}</div>
            <div class="device-metrics"
                 @mouseenter="pauseCarousel(device.id)"
                 @mouseleave="resumeCarousel(device.id)">
              <div class="metrics-container">
                <transition name="flip" mode="out-in">
                  <div class="metric-pair" :key="getCurrentMetricIndex(device.id)">
                    <div class="metric">
                      <div class="metric-label">{{ getCurrentMetrics(device)[0].name }}</div>
                      <div class="metric-value" :class="{
                        'metric-warning': device.status === 'warning' && getCurrentMetrics(device)[0].isAlert,
                        'metric-alert': getCurrentMetrics(device)[0].isAlert
                      }">
                        {{ getCurrentMetrics(device)[0].value }}{{ getCurrentMetrics(device)[0].unit }}
                      </div>
                    </div>
                    <div class="metric" v-if="getCurrentMetrics(device)[1]">
                      <div class="metric-label">{{ getCurrentMetrics(device)[1].name }}</div>
                      <div class="metric-value" :class="{
                        'metric-warning': device.status === 'warning' && getCurrentMetrics(device)[1].isAlert,
                        'metric-alert': getCurrentMetrics(device)[1].isAlert
                      }">
                        {{ getCurrentMetrics(device)[1].value }}{{ getCurrentMetrics(device)[1].unit }}
                      </div>
                    </div>
                  </div>
                </transition>
              </div>
            </div>
            <div class="device-footer">
              <div class="last-update" :class="{ 'text-warning': device.status === 'warning', 'text-offline': device.status === 'offline' }">
                {{ device.lastUpdate }}
              </div>
              <button class="detail-btn" :class="device.status">
                {{ device.status === 'warning' ? '处理告警' : '查看详情' }}
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 单个摄像头全屏模式 -->
    <div v-if="singleCameraFullscreen.show" class="single-camera-fullscreen">
      <div class="video-area">
        <div class="fullscreen-video-container">
          <!-- 左上角摄像头名称 -->
          <div class="camera-title-overlay" v-if="singleCameraFullscreen.camera">
            <h3 class="camera-title-text">{{ singleCameraFullscreen.camera.name }}</h3>
          </div>

          <!-- 右上角关闭按钮 -->
          <div class="close-button-overlay">
            <button class="video-nav-btn" @click="exitSingleFullscreen" title="退出全屏">
              <svg class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor">
                <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
              </svg>
            </button>
          </div>

          <!-- 视频画面区域 -->
          <div class="fullscreen-video-preview">
            <svg class="fullscreen-camera-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
              <path d="M23 7l-7 5 7 5V7z"/>
              <rect x="1" y="5" width="15" height="14" rx="2" ry="2"/>
            </svg>
          </div>
        </div>
      </div>

      <div class="control-panel">
        <div class="control-sections">
          <!-- 云台控制 -->
          <div class="control-section">
            <h4 class="control-title">云台控制</h4>
                                      <div class="ptz-controls">
                <button class="ptz-btn" title="左上">↖</button>
                <button class="ptz-btn" title="向上">↑</button>
                <button class="ptz-btn" title="右上">↗</button>
                <button class="ptz-btn" title="向左">←</button>
                <button class="ptz-btn" title="停止">●</button>
                <button class="ptz-btn" title="向右">→</button>
                <button class="ptz-btn" title="左下">↙</button>
                <button class="ptz-btn" title="向下">↓</button>
                <button class="ptz-btn" title="右下">↘</button>
             </div>
          </div>

          <!-- 变倍控制 -->
          <div class="control-section">
            <h4 class="control-title">变倍控制</h4>
            <div class="zoom-controls">
              <button class="ptz-btn zoom-btn" title="放大">
                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v6m3-3H7"/>
                </svg>
              </button>
              <button class="ptz-btn zoom-btn" title="缩小">
                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM7 10h6"/>
                </svg>
              </button>
            </div>
          </div>

          <!-- 预置位 -->
          <div class="control-section">
            <h4 class="control-title">预置位</h4>
            <div class="preset-grid">
              <button v-for="n in 6" :key="n" class="preset-btn">位置{{ n }}</button>
            </div>
          </div>

          <!-- 回放控制 -->
          <div class="control-section">
            <h4 class="control-title">回放控制</h4>
            <div class="playback-controls">
              <button class="ptz-btn playback-btn" title="开始回放">
                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"/>
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
                </svg>
              </button>
              <button class="ptz-btn playback-btn" title="暂停回放">
                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 9v6m4-6v6m7-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
                </svg>
              </button>
            </div>
          </div>

          <!-- 其他控制 -->
          <div class="control-section">
            <h4 class="control-title">其他控制</h4>
            <div class="other-controls">
              <button class="ptz-btn other-btn" title="截图">
                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"/>
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"/>
                </svg>
              </button>
              <button class="ptz-btn other-btn" title="录制">
                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <circle cx="12" cy="12" r="10" stroke-width="2"/>
                  <circle cx="12" cy="12" r="3" fill="currentColor"/>
                </svg>
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 网格全屏模式 -->
    <div v-if="gridFullscreen.show" class="grid-fullscreen-mode">
      <div class="fullscreen-header">
        <div class="fullscreen-title">
          <h2 class="fullscreen-title-text">视频监控</h2>
          <div class="fullscreen-subtitle">共 {{ videoList.length }} 个摄像头</div>
        </div>

        <!-- 分页控制 -->
        <div class="fullscreen-pagination" v-if="gridTotalPages > 1">
          <button class="fullscreen-nav-btn" @click="gridPrevPage" :disabled="gridFullscreen.currentPage === 1" title="上一页">
            <svg class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor">
              <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
            </svg>
          </button>
          <div class="fullscreen-page-indicator">
            <span>{{ gridPageRange }} / {{ videoList.length }}</span>
            <div class="fullscreen-page-dots">
              <span
                v-for="page in gridTotalPages"
                :key="page"
                class="page-dot"
                :class="{ active: page === gridFullscreen.currentPage }"
                @click="gridFullscreen.currentPage = page"
              ></span>
            </div>
          </div>
          <button class="fullscreen-nav-btn" @click="gridNextPage" :disabled="gridFullscreen.currentPage === gridTotalPages" title="下一页">
            <svg class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor">
              <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
            </svg>
          </button>
        </div>

        <div class="fullscreen-controls">
          <!-- 键盘快捷键提示 -->
          <div class="keyboard-hints" v-if="gridTotalPages > 1">
            <div class="hint-item">
              <kbd>←</kbd><kbd>→</kbd> 翻页
            </div>
            <div class="hint-item">
              <kbd>1-9</kbd> 跳转
            </div>
            <div class="hint-item">
              <kbd>ESC</kbd> 退出
            </div>
          </div>

          <button class="fullscreen-close-btn" @click="exitGridFullscreen" title="退出全屏 (ESC)">
            <svg class="w-6 h-6" viewBox="0 0 20 20" fill="currentColor">
              <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
            </svg>
          </button>
        </div>
      </div>

      <div class="fullscreen-video-grid">
        <div v-for="video in gridPaginatedVideos" :key="video.id" class="fullscreen-video-card">
          <button class="fullscreen-camera-btn" @click="openVideoFullscreen(video)" title="单独查看">
            <svg class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor">
              <path fill-rule="evenodd" d="M3 4a1 1 0 011-1h4a1 1 0 010 2H6.414l2.293 2.293a1 1 0 11-1.414 1.414L5 6.414V8a1 1 0 01-2 0V4zm9 1a1 1 0 010-2h4a1 1 0 011 1v4a1 1 0 01-2 0V6.414l-2.293 2.293a1 1 0 11-1.414-1.414L13.586 5H12zm-9 7a1 1 0 012 0v1.586l2.293-2.293a1 1 0 111.414 1.414L6.414 15H8a1 1 0 010 2H4a1 1 0 01-1-1v-4zm13-1a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 010-2h1.586l-2.293-2.293a1 1 0 111.414-1.414L15 13.586V12a1 1 0 011-1z" clip-rule="evenodd" />
            </svg>
          </button>
          <div class="fullscreen-video-preview">
            <div class="fullscreen-camera-placeholder">
              <svg class="fullscreen-camera-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <path d="M23 7l-7 5 7 5V7z"/>
                <rect x="1" y="5" width="15" height="14" rx="2" ry="2"/>
              </svg>
            </div>
            <div class="fullscreen-video-info">
              <div class="fullscreen-video-details">
                <div class="fullscreen-video-name">{{ video.name }}</div>
                <div class="fullscreen-video-location">{{ video.location }}</div>
              </div>
              <span class="fullscreen-video-status" :class="video.status">
                {{ video.status === 'online' ? '在线' : '离线' }}
              </span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 设备历史数据模态框 -->
    <div v-if="historyModal.show" class="history-modal-backdrop" @click="closeHistoryModal">
      <div class="history-modal-content" @click.stop>
        <!-- 模态框头部 -->
        <div class="history-modal-header">
          <div class="history-modal-title-section">
            <h3 class="history-modal-title">{{ historyModal.device.name }} - 历史数据</h3>
            <span class="device-status" :class="historyModal.device.status">{{ historyModal.device.statusText }}</span>
          </div>
          <button class="history-modal-close" @click="closeHistoryModal">
            <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
            </svg>
          </button>
        </div>

        <!-- 图表控制区域 -->
        <div class="history-modal-controls">
          <div class="time-range-buttons">
            <button
              v-for="range in timeRanges"
              :key="range.value"
              class="time-range-btn"
              :class="{ active: historyModal.timeRange === range.value }"
              @click="setTimeRange(range.value)"
            >
              {{ range.label }}
            </button>
          </div>
          <div class="indicator-buttons">
            <button
              v-for="indicator in getDeviceIndicators()"
              :key="indicator.value"
              class="indicator-btn"
              :class="{ active: historyModal.activeIndicator === indicator.value }"
              @click="setActiveIndicator(indicator.value)"
            >
              {{ indicator.label }}
            </button>
          </div>
        </div>

        <!-- 图表区域 -->
        <div class="history-modal-body">
          <div ref="chartContainer" class="chart-container"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'DeviceMonitor',
  data() {
    return {
      selectedFarm: 'all',
      selectedArea: 'all',
      timeRange: 'realtime',
      autoRefresh: '30',
      lastUpdateTime: '刚刚',
      currentPage: 1,
      videosPerPage: 3,

      // 设备监控相关
      deviceFilter: 'all',
      deviceTypeFilter: 'all',
      sortBy: 'alert',
      deviceCurrentPage: 1,
      devicePerPage: 8,

      // 单个摄像头全屏模式
      singleCameraFullscreen: {
        show: false,
        camera: null
      },

      // 网格全屏模式
      gridFullscreen: {
        show: false,
        currentPage: 1,
        videosPerPage: 6
      },

      // 历史数据模态框
      historyModal: {
        show: false,
        device: null,
        timeRange: '24h',
        activeIndicator: 'all'
      },

      // 时间范围选项
      timeRanges: [
        { label: '近24小时', value: '24h' },
        { label: '近7天', value: '7d' },
        { label: '近30天', value: '30d' }
      ],

      // 图表实例
      chartInstance: null,

      // 原始样式保存
      originalBodyBg: '',
      originalBodyColor: '',
      originalAppBg: '',

      videoList: [
        { id: 1, name: '东区1号摄像头', location: '东区1号地块', status: 'online' },
        { id: 2, name: '东区2号摄像头', location: '东区2号地块', status: 'online' },
        { id: 3, name: '东区3号摄像头', location: '东区3号地块', status: 'offline' },
        { id: 4, name: '西区1号摄像头', location: '西区1号地块', status: 'online' },
        { id: 5, name: '西区2号摄像头', location: '西区2号地块', status: 'online' },
        { id: 6, name: '西区3号摄像头', location: '西区3号地块', status: 'online' },
        { id: 7, name: '南区1号摄像头', location: '南区1号地块', status: 'online' },
        { id: 8, name: '南区2号摄像头', location: '南区2号地块', status: 'offline' },
        { id: 9, name: '南区3号摄像头', location: '南区3号地块', status: 'online' },
        { id: 10, name: '北区1号摄像头', location: '北区1号地块', status: 'online' },
        { id: 11, name: '北区2号摄像头', location: '北区2号地块', status: 'online' },
        { id: 12, name: '北区3号摄像头', location: '北区3号地块', status: 'online' }
      ],

      // 轮播控制状态
      carouselStates: {},
      carouselTimers: {},

      deviceList: [
        {
          id: 1,
          name: '土壤气象监测器 #1',
          location: '第一家葡萄园',
          status: 'online',
          statusText: '在线',
          lastUpdate: '2分钟前更新',
          type: 'soil',
          metrics: [
            { name: '气温', value: '30.5', unit: '℃', isAlert: false },
            { name: '湿度', value: '93.1', unit: '%', isAlert: false },
            { name: '降雨量', value: '0.6', unit: 'mm', isAlert: false },
            { name: '风向', value: '北', unit: '', isAlert: false },
            { name: '风速', value: '1.2', unit: 'm/s', isAlert: false },
            { name: '气压', value: '994.00', unit: 'hPa', isAlert: false },
            { name: '光照强度', value: '-230.8', unit: 'lux', isAlert: false },
            { name: '土壤湿度', value: '22.10', unit: '%', isAlert: false },
            { name: '土壤温度', value: '27.10', unit: '℃', isAlert: false },
            { name: '氮含量', value: '1', unit: 'mg/kg', isAlert: false },
            { name: '磷含量', value: '1', unit: 'mg/kg', isAlert: false },
            { name: '钾含量', value: '0', unit: 'mg/kg', isAlert: false }
          ]
        },
        /* {
          id: 2,
          name: '水质监测器 #2',
          location: '西区1号地块',
          status: 'warning',
          statusText: '告警',
          lastUpdate: 'pH值超标',
          type: 'water',
          metrics: [
            { name: 'pH值', value: '8.5', unit: '', isAlert: true },
            { name: '溶解氧', value: '6.2', unit: 'mg/L', isAlert: false },
            { name: '电导率', value: '1.2', unit: 'mS/cm', isAlert: false },
            { name: '浊度', value: '15', unit: 'NTU', isAlert: false },
            { name: '氨氮', value: '0.8', unit: 'mg/L', isAlert: false }
          ]
        }, */
        {
          id: 3,
          name: '气象土壤监测器 #2',
          location: '东区气象站',
          status: 'online',
          statusText: '在线',
          lastUpdate: '1分钟前更新',
          type: 'weather',
          metrics: [
            { name: '温度', value: '26.5', unit: '℃', isAlert: false },
            { name: '湿度', value: '68', unit: '%', isAlert: false },
            { name: '光照强度', value: '45000', unit: 'lux', isAlert: false },
            { name: '风速', value: '2.3', unit: 'm/s', isAlert: false },
            { name: '降雨量', value: '0', unit: 'mm', isAlert: false },
            { name: '气压', value: '1013', unit: 'hPa', isAlert: false }
          ]
        },
        /*{
          id: 4,
          name: '土壤监测器 #4',
          location: '西区2号地块',
          status: 'offline',
          statusText: '离线',
          lastUpdate: '设备离线 > 24h',
          type: 'soil',
          metrics: [
            { name: '土壤湿度', value: '--', unit: '%', isAlert: false },
            { name: '土壤温度', value: '--', unit: '℃', isAlert: false }
          ]
        },
        {
          id: 5,
          name: '水质监测器 #3',
          location: '东区2号地块',
          status: 'online',
          statusText: '在线',
          lastUpdate: '5分钟前更新',
          type: 'water',
          metrics: [
            { name: 'pH值', value: '7.2', unit: '', isAlert: false },
            { name: '溶解氧', value: '5.8', unit: 'mg/L', isAlert: false },
            { name: '电导率', value: '0.9', unit: 'mS/cm', isAlert: false },
            { name: '浊度', value: '8', unit: 'NTU', isAlert: false }
          ]
        },
        {
          id: 6,
          name: '气象监测器 #2',
          location: '西区气象站',
          status: 'warning',
          statusText: '告警',
          lastUpdate: '温度过高',
          type: 'weather',
          metrics: [
            { name: '温度', value: '35.8', unit: '℃', isAlert: true },
            { name: '湿度', value: '45', unit: '%', isAlert: false },
            { name: '光照强度', value: '52000', unit: 'lux', isAlert: false },
            { name: '风速', value: '4.2', unit: 'm/s', isAlert: false },
            { name: '降雨量', value: '2.5', unit: 'mm', isAlert: false }
          ]
        },
        {
          id: 7,
          name: '土壤监测器 #5',
          location: '南区1号地块',
          status: 'online',
          statusText: '在线',
          lastUpdate: '3分钟前更新',
          type: 'soil',
          metrics: [
            { name: '土壤湿度', value: '28.5', unit: '%', isAlert: false },
            { name: '土壤温度', value: '22.8', unit: '℃', isAlert: false },
            { name: 'EC值', value: '2.1', unit: 'mS/cm', isAlert: false },
            { name: 'P含量', value: '38', unit: 'mg/kg', isAlert: false },
            { name: 'K含量', value: '125', unit: 'mg/kg', isAlert: false }
          ]
        },
        {
          id: 8,
          name: '水质监测器 #4',
          location: '南区水质站',
          status: 'online',
          statusText: '在线',
          lastUpdate: '1分钟前更新',
          type: 'water',
          metrics: [
            { name: 'pH值', value: '7.1', unit: '', isAlert: false },
            { name: '溶解氧', value: '6.5', unit: 'mg/L', isAlert: false },
            { name: '电导率', value: '1.1', unit: 'mS/cm', isAlert: false },
            { name: '温度', value: '23.5', unit: '℃', isAlert: false },
            { name: '浊度', value: '5', unit: 'NTU', isAlert: false }
          ]
        },
         {
          id: 9,
          name: '土壤监测器 #6',
          location: '北区1号地块',
          status: 'offline',
          statusText: '离线',
          lastUpdate: '设备离线 > 12h',
          type: 'soil',
          metrics: [
            { name: '土壤湿度', value: '--', unit: '%', isAlert: false },
            { name: '土壤温度', value: '--', unit: '℃', isAlert: false }
          ]
        },
        {
          id: 10,
          name: '气象监测器 #3',
          location: '北区气象站',
          status: 'online',
          statusText: '在线',
          lastUpdate: '30秒前更新',
          type: 'weather',
          metrics: [
            { name: '温度', value: '28.2', unit: '℃', isAlert: false },
            { name: '湿度', value: '72', unit: '%', isAlert: false },
            { name: '光照强度', value: '38000', unit: 'lux', isAlert: false },
            { name: '风速', value: '1.8', unit: 'm/s', isAlert: false },
            { name: '气压', value: '1015', unit: 'hPa', isAlert: false },
            { name: 'UV指数', value: '8', unit: '', isAlert: false }
          ]
        } */
      ]
    }
  },

  computed: {
    totalPages() {
      return Math.ceil(this.videoList.length / this.videosPerPage)
    },
    paginatedVideos() {
      const start = (this.currentPage - 1) * this.videosPerPage
      const end = start + this.videosPerPage
      return this.videoList.slice(start, end)
    },

    // 网格全屏模式计算属性
    gridTotalPages() {
      return Math.ceil(this.videoList.length / this.gridFullscreen.videosPerPage)
    },
    gridPaginatedVideos() {
      const start = (this.gridFullscreen.currentPage - 1) * this.gridFullscreen.videosPerPage
      const end = start + this.gridFullscreen.videosPerPage
      return this.videoList.slice(start, end)
    },
    gridPageRange() {
      const start = (this.gridFullscreen.currentPage - 1) * this.gridFullscreen.videosPerPage + 1
      const end = Math.min(this.gridFullscreen.currentPage * this.gridFullscreen.videosPerPage, this.videoList.length)
      return `${start}-${end}`
    },

    // 设备监控计算属性
    filteredDevices() {
      let devices = this.deviceList

      // 按状态过滤
      if (this.deviceFilter !== 'all') {
        devices = devices.filter(device => device.status === this.deviceFilter)
      }

      // 按类型过滤
      if (this.deviceTypeFilter !== 'all') {
        devices = devices.filter(device => device.type === this.deviceTypeFilter)
      }

      // 排序
      if (this.sortBy === 'alert') {
        devices = devices.sort((a, b) => {
          const statusOrder = { warning: 0, offline: 1, online: 2 }
          return statusOrder[a.status] - statusOrder[b.status]
        })
      } else if (this.sortBy === 'name') {
        devices = devices.sort((a, b) => a.name.localeCompare(b.name))
      } else if (this.sortBy === 'time') {
        devices = devices.sort((a, b) => {
          // 简单的时间排序逻辑，实际应该根据真实时间戳
          const getUpdateTime = (update) => {
            if (update.includes('分钟前')) return parseInt(update.match(/\d+/)[0])
            if (update.includes('刚刚')) return 0
            return 999 // 其他情况放最后
          }
          return getUpdateTime(a.lastUpdate) - getUpdateTime(b.lastUpdate)
        })
      }

      return devices
    },

    deviceTotalPages() {
      return Math.ceil(this.filteredDevices.length / this.devicePerPage)
    },

    paginatedDevices() {
      const start = (this.deviceCurrentPage - 1) * this.devicePerPage
      const end = start + this.devicePerPage
      return this.filteredDevices.slice(start, end)
    }
  },

  methods: {
    refreshData() {
      console.log('刷新数据')
      this.lastUpdateTime = '刚刚'
      // 这里可以添加实际的数据刷新逻辑
    },

    prevPage() {
      if (this.currentPage > 1) {
        this.currentPage--
      }
    },

    nextPage() {
      if (this.currentPage < this.totalPages) {
        this.currentPage++
      }
    },

    getPageRange() {
      const start = (this.currentPage - 1) * this.videosPerPage + 1
      const end = Math.min(this.currentPage * this.videosPerPage, this.videoList.length)
      return `${start}-${end}`
    },

    toggleFullscreen() {
      console.log('切换网格全屏模式')
      this.gridFullscreen.show = true
    },

    exitGridFullscreen() {
      this.gridFullscreen.show = false
      this.gridFullscreen.currentPage = 1
    },

    // 网格全屏分页方法
    gridPrevPage() {
      if (this.gridFullscreen.currentPage > 1) {
        this.gridFullscreen.currentPage--
      }
    },

    gridNextPage() {
      if (this.gridFullscreen.currentPage < this.gridTotalPages) {
        this.gridFullscreen.currentPage++
      }
    },

    openVideoFullscreen(video) {
      console.log('打开单个视频全屏:', video.name)
      console.log('Video data:', video)
      // 如果是从网格全屏模式进入，先关闭网格全屏
      if (this.gridFullscreen.show) {
        this.gridFullscreen.show = false
      }
      this.singleCameraFullscreen.show = true
      this.singleCameraFullscreen.camera = video
      // 确保数据更新后再强制更新视图
      this.$nextTick(() => {
        console.log('Fullscreen camera:', this.singleCameraFullscreen.camera)
      })
    },

    exitSingleFullscreen() {
      this.singleCameraFullscreen.show = false
      this.singleCameraFullscreen.camera = null
    },

    // 设备监控方法
    setFilter(filter) {
      this.deviceFilter = filter
      this.deviceCurrentPage = 1 // 重置到第一页
    },

    setTypeFilter(type) {
      this.deviceTypeFilter = this.deviceTypeFilter === type ? 'all' : type
      this.deviceCurrentPage = 1 // 重置到第一页
    },

    getDeviceCountByStatus(status) {
      return this.deviceList.filter(device => device.status === status).length
    },

    prevDevicePage() {
      if (this.deviceCurrentPage > 1) {
        this.deviceCurrentPage--
      }
    },

    nextDevicePage() {
      if (this.deviceCurrentPage < this.deviceTotalPages) {
        this.deviceCurrentPage++
      }
    },

    getDevicePageRange() {
      if (this.filteredDevices.length === 0) return '0-0'
      const start = (this.deviceCurrentPage - 1) * this.devicePerPage + 1
      const end = Math.min(this.deviceCurrentPage * this.devicePerPage, this.filteredDevices.length)
      return `${start}-${end}`
    },

    showDeviceHistory(device) {
      console.log('显示设备数据:', device.name)
      this.historyModal.show = true
      this.historyModal.device = device
      this.historyModal.device.type = 'soil'
      this.historyModal.timeRange = '24h'
      this.historyModal.activeIndicator = 'all'

      // 等待模态框渲染完成后初始化图表
      this.$nextTick(() => {
        this.initChart()
      })
    },

    closeHistoryModal() {
      this.historyModal.show = false
      this.historyModal.device = null
      // 销毁图表实例
      if (this.chartInstance) {
        this.chartInstance.dispose()
        this.chartInstance = null
      }
    },

    setTimeRange(range) {
      this.historyModal.timeRange = range
      this.updateChart()
    },

    setActiveIndicator(indicator) {
      this.historyModal.activeIndicator = indicator
      this.updateChart()
    },

    getDeviceIndicators() {
      if (!this.historyModal.device) return []

      const indicators = {
        soil: [
          { label: '所有指标', value: 'all' },
          { label: '土壤湿度', value: 'soilHumidity' },
          { label: '土壤温度', value: 'soilTemperature' },
          { label: 'EC值', value: 'ec' }
        ],
        water: [
          { label: '所有指标', value: 'all' },
          { label: 'pH值', value: 'ph' },
          { label: '溶解氧', value: 'oxygen' },
          { label: '电导率', value: 'conductivity' },
          { label: '浊度', value: 'turbidity' }
        ],
        weather: [
          { label: '所有指标', value: 'all' },
          { label: '温度', value: 'temperature' },
          { label: '湿度', value: 'humidity' },
          { label: '光照', value: 'light' },
          { label: '风速', value: 'windSpeed' },
          { label: '降雨量', value: 'rainfall' }
        ]
      }

      return indicators[this.historyModal.device.type] || indicators.soil
    },

    initChart() {
      if (!this.$refs.chartContainer) return

      // 销毁已存在的图表实例
      if (this.chartInstance) {
        this.chartInstance.dispose()
        this.chartInstance = null
      }

      // 创建新的图表实例
      this.chartInstance = this.$echarts.init(this.$refs.chartContainer)
      this.updateChart()
    },

    updateChart() {
      if (!this.chartInstance) return

      // 生成模拟数据
      const data = this.generateMockData()
      console.log("data");
      console.log(data);
      const seriesNames = this.getSeriesNames()
      console.log("seriesNames");
      console.log(seriesNames);

      const option = {
        backgroundColor: 'transparent',
        tooltip: {
          trigger: 'axis',
          backgroundColor: 'rgba(255, 255, 255, 0.95)',
          borderColor: '#e5e7eb',
          textStyle: { color: '#1f2937' }
        },
        legend: {
          data: seriesNames,
          textStyle: { color: '#6b7280' },
          top: 0
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true,
          top: 40
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: data.times,
          axisLine: { lineStyle: { color: '#d1d5db' } },
          axisLabel: { color: '#6b7280' }
        },
        yAxis: {
          type: 'value',
          axisLine: { lineStyle: { color: '#d1d5db' } },
          axisLabel: { color: '#6b7280' },
          splitLine: { lineStyle: { color: '#f3f4f6' } }
        },
        series: this.generateSeries(data)
      }

      this.chartInstance.setOption(option)
    },

    generateMockData() {
      const times = []
      const values = {}
      const points = this.historyModal.timeRange === '24h' ? 24 : this.historyModal.timeRange === '7d' ? 7 : 30
      const now = new Date()

      // 根据设备类型生成不同的数据
      const ranges = this.getDataRanges()

      console.log("generateMockData");
      console.log(ranges);

      for (let i = points - 1; i >= 0; i--) {
        const time = new Date(now - i * (this.historyModal.timeRange === '24h' ? 3600000 : 86400000))
        times.push(this.historyModal.timeRange === '24h' ?
          time.getHours() + ':00' :
          (time.getMonth() + 1) + '/' + time.getDate())

        ranges.forEach((range, index) => {
          if (!values[`values${index + 1}`]) {
            values[`values${index + 1}`] = []
          }
          values[`values${index + 1}`].push(
            (Math.random() * (range[1] - range[0]) + range[0]).toFixed(1)
          )
        })
      }

      return { times, ...values }
    },

    getDataRanges() {
      const ranges = {
        soil: [[20, 40], [15, 30], [0.5, 2]], // 土壤湿度, 土壤温度, EC值
        water: [[6.5, 8.5], [4, 8], [0.5, 2], [0, 10]], // pH值, 溶解氧, 电导率, 浊度
        weather: [[15, 35], [40, 80], [0, 1000], [0, 10], [0, 50], [0, 10], [0, 10], [0, 10]] // 温度, 湿度, 光照, 风速, 降雨量,土壤氮,土壤磷,土壤钾
      }
      return ranges[this.historyModal.device.type] || ranges.soil
    },

    getSeriesNames() {
      const names = {
        soil: ['土壤湿度', '土壤温度', 'EC值'],
        water: ['pH值', '溶解氧', '电导率', '浊度'],
        weather: ['温度', '湿度', '光照', '风速', '降雨量','土壤氮','土壤磷','土壤钾']
      }
      const allNames = names[this.historyModal.device.type] || names.soil

      if (this.historyModal.activeIndicator === 'all') {
        return allNames
      } else {
        const indicatorMap = {
          soilHumidity: '土壤湿度',
          soilTemperature: '土壤温度',
          ec: 'EC值',
          ph: 'pH值',
          oxygen: '溶解氧',
          conductivity: '电导率',
          turbidity: '浊度',
          temperature: '温度',
          humidity: '湿度',
          light: '光照',
          windSpeed: '风速',
          rainfall: '降雨量'
        }
        return [indicatorMap[this.historyModal.activeIndicator] || allNames[0]]
      }
    },

    generateSeries(data) {
      console.log("generateSeries_data");
      console.log(data);
      console.log(this.historyModal.device.type);
      console.log(this.historyModal.activeIndicator);
      const deviceType = this.historyModal.device.type
      const activeIndicator = this.historyModal.activeIndicator

      const indicators = {
        soil: {
          names: ['土壤湿度', '土壤温度', 'EC值'],
          colors: ['#10b981', '#34d399', '#f59e0b']
        },
        water: {
          names: ['pH值', '溶解氧', '电导率', '浊度'],
          colors: ['#10b981', '#34d399', '#6ee7b7', '#f59e0b']
        },
        weather: {
          names: ['温度', '湿度', '光照', '风速', '降雨量', '土壤氮', '土壤磷', '土壤钾'],
          colors: ['#10b981', '#34d399', '#6ee7b7', '#a7f3d0', '#f59e0b', '#a7f3d2', '#a7f3d3', '#a7f3d4']
        }
      }[deviceType] || { names: [], colors: [] }

      console.log(indicators);

      if (activeIndicator === 'all') {
        return indicators.names.map((name, index) => ({
          name: name,
          type: 'line',
          data: data[`values${index + 1}`] || [],
          smooth: true,
          showSymbol: false,
          lineStyle: { width: 3 },
          areaStyle: {
            color: {
              type: 'linear',
              x: 0, y: 0, x2: 0, y2: 1,
              colorStops: [
                { offset: 0, color: indicators.colors[index] + '50' },
                { offset: 0.8, color: indicators.colors[index] + '20' },
                { offset: 1, color: indicators.colors[index] + '05' }
              ]
            }
          },
          itemStyle: { color: indicators.colors[index] }
        }))
      } else {
        const index = indicators.names.indexOf(this.getIndicatorLabel(activeIndicator))
        const color = indicators.colors[index]
        return [{
          name: this.getIndicatorLabel(activeIndicator),
          type: 'line',
          data: data[`values${index + 1}`] || [],
          smooth: true,
          showSymbol: false,
          lineStyle: { width: 3 },
          areaStyle: {
            color: {
              type: 'linear',
              x: 0, y: 0, x2: 0, y2: 1,
              colorStops: [
                { offset: 0, color: color + '60' },
                { offset: 0.7, color: color + '30' },
                { offset: 1, color: color + '08' }
              ]
            }
          },
          itemStyle: { color: color }
        }]
      }
    },

    getIndicatorLabel(value) {
      const indicatorMap = {
        soilHumidity: '土壤湿度',
        soilTemperature: '土壤温度',
        ec: 'EC值',
        ph: 'pH值',
        oxygen: '溶解氧',
        conductivity: '电导率',
        turbidity: '浊度',
        temperature: '温度',
        humidity: '湿度',
        light: '光照',
        windSpeed: '风速',
        rainfall: '降雨量'
      }
      return indicatorMap[value] || value
    },

    // 轮播控制方法
    initializeCarousels() {
      this.deviceList.forEach(device => {
        if (device.metrics.length > 2) {
          this.$set(this.carouselStates, device.id, 0)
          this.startCarouselTimer(device.id)
        }
      })
    },

    startCarouselTimer(deviceId) {
      if (this.carouselTimers[deviceId]) {
        clearInterval(this.carouselTimers[deviceId])
      }

      this.carouselTimers[deviceId] = setInterval(() => {
        this.nextMetric(deviceId)
      }, 3000) // 3秒切换一次
    },

    pauseCarousel(deviceId) {
      if (this.carouselTimers[deviceId]) {
        clearInterval(this.carouselTimers[deviceId])
        this.carouselTimers[deviceId] = null
      }
    },

    resumeCarousel(deviceId) {
      const device = this.deviceList.find(d => d.id === deviceId)
      if (device && device.metrics.length > 2) {
        this.startCarouselTimer(deviceId)
      }
    },

    nextMetric(deviceId) {
      const device = this.deviceList.find(d => d.id === deviceId)
      if (!device || device.metrics.length <= 2) return

      const totalGroups = Math.ceil(device.metrics.length / 2)
      const currentIndex = this.carouselStates[deviceId] || 0
      const nextIndex = (currentIndex + 1) % totalGroups

      this.$set(this.carouselStates, deviceId, nextIndex)
    },

    getCurrentMetricIndex(deviceId) {
      return this.carouselStates[deviceId] || 0
    },

    getCurrentMetrics(device) {
      if (device.metrics.length <= 2) {
        return device.metrics
      }

      const currentIndex = this.carouselStates[device.id] || 0
      const startIndex = currentIndex * 2
      return device.metrics.slice(startIndex, startIndex + 2)
    }
  },

  mounted() {
    // 保存原始背景色和设置浅色主题
    this.originalBodyBg = document.body.style.backgroundColor || ''
    this.originalBodyColor = document.body.style.color || ''
    this.originalAppBg = document.getElementById('app')?.style.backgroundColor || ''

    // 应用浅色主题
    document.body.style.backgroundColor = '#f8fafc'
    document.body.style.color = '#1f2937'
    const appEl = document.getElementById('app')
    if (appEl) {
      appEl.style.backgroundColor = '#f8fafc'
    }

    // 初始化轮播
    this.initializeCarousels()

    // 监听键盘事件
    document.addEventListener('keydown', (e) => {
      if (e.key === 'Escape') {
        if (this.historyModal.show) {
          this.closeHistoryModal()
        } else if (this.singleCameraFullscreen.show) {
          this.exitSingleFullscreen()
        } else if (this.gridFullscreen.show) {
          this.exitGridFullscreen()
        }
      } else if (this.gridFullscreen.show) {
        // 网格全屏模式下的键盘快捷键
        if (e.key === 'ArrowLeft') {
          e.preventDefault()
          this.gridPrevPage()
        } else if (e.key === 'ArrowRight') {
          e.preventDefault()
          this.gridNextPage()
        } else if (e.key >= '1' && e.key <= '9') {
          // 数字键快速跳转页面
          const pageNum = parseInt(e.key)
          if (pageNum <= this.gridTotalPages) {
            this.gridFullscreen.currentPage = pageNum
          }
        }
      }
    })
  },

  beforeDestroy() {
    // 清理所有轮播定时器
    Object.values(this.carouselTimers).forEach(timer => {
      if (timer) {
        clearInterval(timer)
      }
    })
    this.carouselTimers = {}

    // 恢复原始背景色
    document.body.style.backgroundColor = this.originalBodyBg
    document.body.style.color = this.originalBodyColor
    const appEl = document.getElementById('app')
    if (appEl) {
      appEl.style.backgroundColor = this.originalAppBg
    }

    // 销毁图表实例
    if (this.chartInstance) {
      this.chartInstance.dispose()
      this.chartInstance = null
    }
  }
}
</script>



<style scoped>
.device-monitor-container {
  padding: 24px;
  background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
  color: #1f2937;
  min-height: 100vh;
}



/* 控制面板 */
.device-monitor-container > .control-panel {
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 16px;
  padding: 1.5rem;
  margin-bottom: 2rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 2rem;
  transition: all 0.3s ease;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

.device-monitor-container > .control-panel:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
  border-color: #10b981;
}

.control-left {
  display: flex;
  gap: 1.5rem;
  flex: 1;
}

.form-group {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.form-group label {
  font-size: 0.875rem;
  color: #6b7280;
  white-space: nowrap;
}

.form-group select {
  background-color: white;
  border: 1px solid #d1d5db;
  color: #1f2937;
  padding: 8px 12px;
  border-radius: 8px;
  min-width: 150px;
}

.form-group select:focus {
  outline: none;
  border-color: #10b981;
  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
}

.control-right {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.refresh-btn {
  background-color: #10b981;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 8px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
  transition: all 0.2s ease;
}

.refresh-btn:hover {
  background-color: #059669;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
}

.auto-refresh {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: #6b7280;
}

.auto-refresh-select {
  background-color: white;
  border: 1px solid #d1d5db;
  color: #1f2937;
  padding: 4px 8px;
  border-radius: 6px;
  font-size: 0.875rem;
}

.auto-refresh-select:focus {
  outline: none;
  border-color: #10b981;
  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
}

.last-update {
  font-size: 0.875rem;
  color: #6b7280;
}

.last-update span {
  color: #1f2937;
  font-weight: 500;
}

/* 统计容器 */
.stats-container {
  display: grid;
  grid-template-columns: 2fr 5fr;
  gap: 1rem;
  margin-bottom: 2rem;
}

/* 综合统计卡片 */
.overview-stat-card {
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 16px;
  padding: 1.5rem;
  transition: all 0.3s ease;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

.overview-stat-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
  border-color: #10b981;
}

.overview-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

.overview-item {
  text-align: center;
}

/* 分类统计区域 */
.category-stats {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 1rem;
}

.stat-card {
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  padding: 1.5rem;
  text-align: center;
  transition: all 0.3s ease;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.stat-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
  border-color: #10b981;
}

.stat-card.alert {
  border-color: #ef4444;
  background: linear-gradient(to right, rgba(239, 68, 68, 0.05), transparent);
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }
  70% { box-shadow: 0 0 0 10px rgba(239, 68, 68, 0); }
  100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
}

.stat-number {
  font-size: 2rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.stat-number.online { color: #10b981; }
.stat-number.offline { color: #ef4444; }
.stat-number.alert { color: #ef4444; }
.stat-number.camera { color: #3b82f6; }
.stat-number.sensor { color: #10b981; }
.stat-number.weather { color: #8b5cf6; }
.stat-number.control { color: #f59e0b; }

.stat-label {
  font-size: 0.875rem;
  color: #6b7280;
  margin-bottom: 0.25rem;
  font-weight: 500;
}

.stat-detail {
  font-size: 0.75rem;
  color: #9ca3af;
}

.stat-detail .processed {
  color: #10b981;
}

/* 主要内容区域 */
.main-content {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.content-section {
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 16px;
  padding: 24px;
  transition: all 0.3s ease;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

.content-section:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
  border-color: #10b981;
}

.section-title {
  font-size: 1.25rem;
  font-weight: 600;
  margin-bottom: 0;
  color: #1f2937;
}

/* 视频头部样式 */
.video-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
}

.video-header-left {
  display: flex;
  align-items: baseline;
  gap: 1rem;
}

.video-count {
  font-size: 0.875rem;
  color: #6b7280;
}

.video-header-right {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.video-nav-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.video-nav-btn {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  color: #6b7280;
  transition: all 0.2s ease;
  cursor: pointer;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.video-nav-btn:hover:not(:disabled) {
  background: #10b981;
  color: white;
  border-color: #10b981;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
}

.video-nav-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.page-indicator {
  padding: 0 12px;
  height: 32px;
  display: flex;
  align-items: center;
  background: white;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  color: #6b7280;
  font-size: 14px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* 视频容器样式 */
.video-container {
  padding: 0;
}

/* 视频网格 */
.video-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

.video-card {
  position: relative;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  overflow: hidden;
  transition: all 0.3s ease;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.video-card:hover {
  border-color: #10b981;
  transform: translateY(-4px);
  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
}

/* 摄像头全屏按钮 */
.camera-fullscreen-btn {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.9);
  border: 1px solid rgba(229, 231, 235, 0.8);
  border-radius: 8px;
  color: #6b7280;
  transition: all 0.2s ease;
  z-index: 10;
  cursor: pointer;
  backdrop-filter: blur(8px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.camera-fullscreen-btn:hover {
  background: rgba(16, 185, 129, 0.8);
  color: white;
  border-color: #10b981;
}

.video-preview {
  position: relative;
  padding-top: 56.25%; /* 16:9 aspect ratio */
  background: linear-gradient(135deg, #f0fdf4 0%, #f8fafc 100%);
}

.camera-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.camera-icon {
  position: absolute;
  width: 48px;
  height: 48px;
  color: #10b981;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  opacity: 0.7;
}

/* 强制居中的新样式 */
.centered-container {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
}

.centered-icon {
  position: relative !important;
  top: auto !important;
  left: auto !important;
  transform: none !important;
  margin: auto !important;
}

.video-info-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: linear-gradient(to top, rgba(248, 250, 252, 0.95), rgba(248, 250, 252, 0.8), rgba(248, 250, 252, 0.4), transparent);
  padding: 0.75rem;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  z-index: 5;
  backdrop-filter: blur(8px);
  border-top: 1px solid rgba(229, 231, 235, 0.3);
}

.video-details {
  flex: 1;
}

.video-name {
  font-weight: 600;
  margin-bottom: 0.25rem;
  color: #1f2937;
  font-size: 0.875rem;
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
}

.video-location {
  font-size: 0.75rem;
  color: #6b7280;
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
}

.video-status {
  font-size: 0.75rem;
  padding: 4px 8px;
  border-radius: 12px;
  font-weight: 500;
  white-space: nowrap;
  backdrop-filter: blur(4px);
}

.video-status.online {
  background-color: rgba(16, 185, 129, 0.15);
  color: #059669;
  border: 1px solid rgba(16, 185, 129, 0.4);
  font-weight: 600;
}

.video-status.offline {
  background-color: rgba(239, 68, 68, 0.15);
  color: #dc2626;
  border: 1px solid rgba(239, 68, 68, 0.4);
  font-weight: 600;
}

/* 设备监控头部 */
.device-monitor-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
  gap: 2rem;
}

.device-monitor-title-section {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex: 1;
}

.section-title {
  margin: 0;
  line-height: 1.5;
}

.filter-buttons {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.filter-divider {
  height: 24px;
  width: 1px;
  background-color: #e5e7eb;
}

.type-filters {
  display: flex;
  gap: 0.5rem;
}

.filter-btn {
  padding: 0.5rem 1rem;
  border-radius: 8px;
  font-size: 0.875rem;
  color: #6b7280;
  background: transparent;
  border: 1px solid #d1d5db;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  height: 36px; /* 固定高度确保对齐 */
  line-height: 1.5;
}

.filter-btn:hover {
  background: rgba(16, 185, 129, 0.05);
  border-color: #10b981;
  color: #059669;
}

.filter-btn.active {
  background: #10b981;
  border-color: #10b981;
  color: white;
}

.filter-count {
  font-size: 0.75rem;
  color: #9ca3af;
}

.filter-btn.active .filter-count {
  color: rgba(255, 255, 255, 0.8);
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
}

.status-dot.warning {
  background-color: #f59e0b;
}

.status-dot.offline {
  background-color: #ef4444;
}

.device-monitor-controls {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.sort-select {
  background-color: white;
  border: 1px solid #d1d5db;
  color: #1f2937;
  padding: 0.5rem 2rem 0.5rem 1rem;
  border-radius: 8px;
  font-size: 0.875rem;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%236b7280'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 9l-7 7-7-7'%3E%3C/path%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 1rem;
  height: 36px; /* 与按钮高度保持一致 */
  line-height: 1.5;
}

.sort-select:focus {
  outline: none;
  border-color: #10b981;
  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
}

.device-pagination {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.page-btn {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  color: #6b7280;
  transition: all 0.2s ease;
  background: white;
  border: 1px solid #d1d5db;
  cursor: pointer;
}

.page-indicator {
  padding: 0 12px;
  height: 32px;
  display: flex;
  align-items: center;
  color: #6b7280;
  font-size: 14px;
  line-height: 1;
  font-weight: 500;
}

.page-btn:hover:not(:disabled) {
  background: #10b981;
  border-color: #10b981;
  color: white;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
}

.page-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* 设备网格 */
.device-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1rem;
  padding: 0.5rem;
  min-height: 400px;
}

@media (min-width: 1280px) {
  .device-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 1536px) {
  .device-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.device-card {
  position: relative;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  padding: 1.5rem;
  transition: all 0.3s ease;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  min-height: 250px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* 右上角数据按钮 */
.data-btn {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  color: #6b7280;
  transition: all 0.2s ease;
  z-index: 1;
  cursor: pointer;
}

.data-btn:hover {
  background: #10b981;
  border-color: #10b981;
  color: white;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
}

.data-btn svg {
  width: 16px;
  height: 16px;
}

.device-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
  border-color: #10b981;
}

.device-card.warning {
  border-color: #f59e0b;
  background: linear-gradient(to right, rgba(245, 158, 11, 0.05), rgba(245, 158, 11, 0.02));
}

.device-card.offline {
  opacity: 0.8;
}



.device-header {
  margin-bottom: 0.5rem;
  padding-right: 3rem; /* 为右上角数据按钮留出空间 */
}

.device-title-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.device-name {
  font-weight: 600;
  color: #1f2937;
  font-size: 1.125rem;
}

.device-status {
  font-size: 0.75rem;
  padding: 4px 12px;
  border-radius: 12px;
  font-weight: 500;
}

.device-status.online {
  background-color: rgba(16, 185, 129, 0.1);
  color: #10b981;
  border: 1px solid rgba(16, 185, 129, 0.2);
}

.device-status.warning {
  background-color: rgba(245, 158, 11, 0.1);
  color: #f59e0b;
  border: 1px solid rgba(245, 158, 11, 0.2);
}

.device-status.offline {
  background-color: rgba(239, 68, 68, 0.1);
  color: #ef4444;
  border: 1px solid rgba(239, 68, 68, 0.2);
}

.device-location {
  font-size: 0.875rem;
  color: #6b7280;
  margin-bottom: 1.5rem;
}

.device-metrics {
  margin-bottom: 1.5rem;
  flex: 1;
}

.metrics-container {
  position: relative;
  min-height: 80px;
  overflow: hidden;
}

.metric-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
  width: 100%;
}

.metric {
  text-align: left;
}

.metric-label {
  font-size: 0.875rem;
  color: #6b7280;
  margin-bottom: 0.25rem;
  font-weight: 500;
}

.metric-value {
  font-size: 1.875rem;
  font-weight: 600;
  color: #1f2937;
  display: flex;
  align-items: baseline;
}

.metric-value span {
  font-size: 1.25rem;
  margin-left: 0.25rem;
  color: #6b7280;
  font-weight: 400;
}

.metric-value.metric-warning {
  color: #ef4444;
}

.metric-value.metric-alert {
  color: #ef4444;
}

/* 机场翻牌动画效果 */
.flip-enter-active,
.flip-leave-active {
  transition: all 0.4s ease-in-out;
  transform-style: preserve-3d;
}

.flip-enter {
  transform: perspective(600px) rotateX(90deg);
  opacity: 0;
}

.flip-enter-to {
  transform: perspective(600px) rotateX(0deg);
  opacity: 1;
}

.flip-leave {
  transform: perspective(600px) rotateX(0deg);
  opacity: 1;
}

.flip-leave-to {
  transform: perspective(600px) rotateX(-90deg);
  opacity: 0;
}

.device-card.offline .metric-value {
  color: #9ca3af;
}

.device-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: auto;
}

.last-update {
  font-size: 0.875rem;
  color: #6b7280;
}

.last-update.text-warning {
  color: #ef4444;
}

.last-update.text-offline {
  color: #9ca3af;
}



.detail-btn {
  background: transparent;
  border: 1px solid #d1d5db;
  color: #1f2937;
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 0.875rem;
  cursor: pointer;
  transition: all 0.2s ease;
  font-weight: 500;
}

.detail-btn:hover {
  border-color: #10b981;
  background-color: rgba(16, 185, 129, 0.1);
  color: #059669;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.2);
}

.detail-btn.warning {
  border-color: #ef4444;
  color: #ef4444;
}

.detail-btn.warning:hover {
  background-color: #ef4444;
  color: white;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(239, 68, 68, 0.4);
}



/* 单个摄像头全屏模式 */
.single-camera-fullscreen {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  width: 100vw !important;
  height: 100vh !important;
  background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%) !important;
  z-index: 10000 !important;
  display: flex !important;
  margin: 0 !important;
  padding: 0 !important;
}

.video-area {
  flex: 1 !important;
  min-width: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  position: relative !important;
}

.fullscreen-video-container {
  flex: 1;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #f0fdf4 0%, #f8fafc 100%);
}

/* 左上角摄像头名称 */
.camera-title-overlay {
  position: absolute !important;
  top: 20px !important;
  left: 20px !important;
  z-index: 10001 !important;
  background: rgba(255, 255, 255, 0.95) !important;
  padding: 12px 20px !important;
  border-radius: 12px !important;
  backdrop-filter: blur(8px) !important;
  border: 1px solid rgba(229, 231, 235, 0.8) !important;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1) !important;
}

.camera-title-text {
  color: #1f2937;
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0;
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
  letter-spacing: 0.5px;
}

/* 右上角关闭按钮 */
.close-button-overlay {
  position: absolute !important;
  top: 20px !important;
  right: 20px !important;
  z-index: 10001 !important;
}

.fullscreen-video-preview {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #f0fdf4 0%, #f8fafc 100%);
}

.fullscreen-camera-icon {
  width: 120px;
  height: 120px;
  color: #10b981;
  opacity: 0.6;
}

.single-camera-fullscreen .control-panel {
  width: 280px;
  background: white;
  border-left: 1px solid #e5e7eb;
  padding: 1.5rem;
  overflow-y: auto;
  height: 100vh;
  display: flex;
  flex-direction: column;
  box-shadow: -4px 0 6px -1px rgba(0, 0, 0, 0.1);
}

.control-sections {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  flex: 1;
  justify-content: flex-start;
}

.control-section {
  background: transparent;
}

.control-title {
  font-size: 0.875rem;
  font-weight: 600;
  margin-bottom: 0.75rem;
  color: #1f2937;
  text-align: left;
}

/* 云台控制按钮网格 */
.ptz-controls {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem;
}

.ptz-btn {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
  border: 1px solid #d1d5db;
  color: #6b7280;
  border-radius: 8px;
  font-size: 1.25rem;
  transition: all 0.2s ease;
  cursor: pointer;
  min-height: 44px;
}

.ptz-btn:hover {
  background: #10b981;
  border-color: #10b981;
  color: white;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
}

.ptz-btn:active {
  transform: scale(0.95);
}

/* 统一所有控制按钮的样式 */
.zoom-btn, .playback-btn, .other-btn {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
}

.zoom-btn svg, .playback-btn svg, .other-btn svg {
  width: 16px !important;
  height: 16px !important;
}

/* 变倍控制 */
.zoom-controls {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
}

/* 预置位按钮网格 */
.preset-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
}

.preset-btn {
  padding: 0.75rem;
  background: white;
  border: 1px solid #d1d5db;
  color: #6b7280;
  border-radius: 8px;
  transition: all 0.2s ease;
  text-align: center;
  cursor: pointer;
  font-size: 0.875rem;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.preset-btn:hover {
  background: #10b981;
  border-color: #10b981;
  color: white;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
}

/* 回放控制 */
.playback-controls {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
}

/* 其他控制 */
.other-controls {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
}

/* 网格全屏模式 */
.grid-fullscreen-mode {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  width: 100vw !important;
  height: 100vh !important;
  background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%) !important;
  z-index: 10000 !important;
  display: flex !important;
  flex-direction: column !important;
  padding: 1rem !important;
}

.fullscreen-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 0;
  border-bottom: 1px solid #e5e7eb;
  margin-bottom: 1rem;
  gap: 2rem;
}

.fullscreen-title {
  display: flex;
  align-items: baseline;
  gap: 1rem;
}

.fullscreen-title-text {
  font-size: 1.5rem;
  font-weight: 600;
  color: #1f2937;
  margin: 0;
}

.fullscreen-subtitle {
  font-size: 0.875rem;
  color: #6b7280;
}

.fullscreen-close-btn {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  color: #6b7280;
  transition: all 0.2s ease;
  cursor: pointer;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.fullscreen-close-btn:hover {
  background: #10b981;
  color: white;
  border-color: #10b981;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
}

/* 全屏分页控制样式 */
.fullscreen-pagination {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex: 1;
  justify-content: center;
}

.fullscreen-nav-btn {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  color: #6b7280;
  transition: all 0.2s ease;
  cursor: pointer;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.fullscreen-nav-btn:hover:not(:disabled) {
  background: #10b981;
  color: white;
  border-color: #10b981;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
}

.fullscreen-nav-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.fullscreen-page-indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  color: #6b7280;
  font-size: 0.875rem;
}

.fullscreen-page-dots {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.page-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #d1d5db;
  cursor: pointer;
  transition: all 0.2s ease;
}

.page-dot.active {
  background-color: #10b981;
  transform: scale(1.2);
}

.page-dot:hover {
  background-color: #6b7280;
}

/* 全屏控制区域 */
.fullscreen-controls {
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* 键盘快捷键提示 */
.keyboard-hints {
  display: flex;
  gap: 1rem;
  align-items: center;
}

.hint-item {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.75rem;
  color: #6b7280;
}

.hint-item kbd {
  background: white;
  border: 1px solid #d1d5db;
  border-radius: 4px;
  color: #374151;
  font-size: 0.75rem;
  padding: 2px 6px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  font-family: monospace;
  min-width: 20px;
  text-align: center;
}

.fullscreen-video-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 1fr);
  gap: 1rem;
  flex: 1;
  height: calc(100vh - 120px);
}

.fullscreen-video-card {
  position: relative;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  overflow: hidden;
  transition: all 0.3s ease;
  display: flex;
  flex-direction: column;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.fullscreen-video-card:hover {
  border-color: #10b981;
  transform: translateY(-4px);
  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
}

.fullscreen-camera-btn {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.9);
  border: 1px solid rgba(229, 231, 235, 0.8);
  border-radius: 8px;
  color: #6b7280;
  transition: all 0.2s ease;
  z-index: 10;
  cursor: pointer;
  backdrop-filter: blur(8px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.fullscreen-camera-btn:hover {
  background: #10b981;
  color: white;
  border-color: #10b981;
}

.fullscreen-video-preview {
  flex: 1;
  position: relative;
  background: linear-gradient(135deg, #f0fdf4 0%, #f8fafc 100%);
  display: flex;
  flex-direction: column;
}

.fullscreen-camera-placeholder {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.fullscreen-camera-icon {
  width: 64px;
  height: 64px;
  color: #10b981;
  opacity: 0.6;
}

.fullscreen-video-info {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: linear-gradient(to top, rgba(248, 250, 252, 0.95), rgba(248, 250, 252, 0.8), rgba(248, 250, 252, 0.4), transparent);
  padding: 0.75rem;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  z-index: 5;
  backdrop-filter: blur(8px);
  border-top: 1px solid rgba(229, 231, 235, 0.3);
}

.fullscreen-video-details {
  flex: 1;
}

.fullscreen-video-name {
  font-weight: 600;
  margin-bottom: 0.25rem;
  color: #1f2937;
  font-size: 0.875rem;
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
}

.fullscreen-video-location {
  font-size: 0.75rem;
  color: #6b7280;
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
}

.fullscreen-video-status {
  font-size: 0.75rem;
  padding: 4px 8px;
  border-radius: 12px;
  font-weight: 500;
  white-space: nowrap;
  backdrop-filter: blur(4px);
}

.fullscreen-video-status.online {
  background-color: rgba(16, 185, 129, 0.15);
  color: #059669;
  border: 1px solid rgba(16, 185, 129, 0.4);
  font-weight: 600;
}

.fullscreen-video-status.offline {
  background-color: rgba(239, 68, 68, 0.15);
  color: #dc2626;
  border: 1px solid rgba(239, 68, 68, 0.4);
  font-weight: 600;
}

/* 从网格全屏进入单摄像头全屏时的处理 */
.grid-fullscreen-mode .single-camera-fullscreen {
  position: fixed !important;
  z-index: 10001 !important;
}

/* 网格全屏模式响应式设计 */
@media (max-width: 1024px) {
  .fullscreen-video-grid {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(3, 1fr);
  }

  .fullscreen-camera-icon {
    width: 48px;
    height: 48px;
  }
}

@media (max-width: 768px) {
  .grid-fullscreen-mode {
    padding: 0.5rem !important;
  }

  .fullscreen-header {
    padding: 0.5rem 0;
    flex-direction: column;
    gap: 1rem;
  }

  .fullscreen-title-text {
    font-size: 1.25rem;
  }

  .fullscreen-pagination {
    order: 2;
    gap: 0.5rem;
  }

  .fullscreen-controls {
    order: 3;
    gap: 0.5rem;
  }

  .keyboard-hints {
    display: none;
  }

  .fullscreen-video-grid {
    grid-template-columns: repeat(1, 1fr);
    grid-template-rows: repeat(6, 1fr);
    gap: 0.5rem;
    height: calc(100vh - 140px);
  }

  .fullscreen-camera-icon {
    width: 40px;
    height: 40px;
  }

  .fullscreen-page-indicator {
    font-size: 0.75rem;
  }

  .fullscreen-nav-btn {
    width: 32px;
    height: 32px;
  }
}

/* 响应式设计 */
@media (max-width: 1280px) {
  .stats-container {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }

  .category-stats {
    grid-template-columns: repeat(4, 1fr);
  }

  .device-monitor-header {
    flex-direction: column;
    align-items: stretch;
    gap: 1rem;
  }

  .device-monitor-title-section {
    flex-direction: column;
    align-items: stretch;
    gap: 1rem;
  }

  .filter-buttons {
    flex-wrap: wrap;
  }

  .type-filters {
    flex-wrap: wrap;
  }
}

@media (max-width: 768px) {
  .control-panel {
    flex-direction: column;
    align-items: stretch;
    gap: 1rem;
  }

  .control-left {
    flex-direction: column;
    gap: 1rem;
  }

  .control-right {
    flex-direction: column;
    align-items: stretch;
    gap: 1rem;
  }

  .form-group {
    justify-content: space-between;
  }

  .stats-container {
    grid-template-columns: 1fr;
  }

  .overview-stats {
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
  }

  .category-stats {
    grid-template-columns: repeat(2, 1fr);
  }

  .video-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .device-monitor-header {
    gap: 0.75rem;
  }

  .device-monitor-title-section {
    gap: 0.75rem;
  }

  .device-monitor-controls {
    flex-direction: column;
    align-items: stretch;
    gap: 0.75rem;
  }

  .filter-btn {
    padding: 0.375rem 0.75rem;
    font-size: 0.8rem;
  }

  .device-pagination {
    justify-content: center;
  }

  .device-grid {
    padding: 0;
  }

  .device-metrics {
    gap: 1rem;
  }

  .metric-value {
    font-size: 1.5rem;
  }

  .metric-value span {
    font-size: 1rem;
  }

  .detail-btn {
    width: 100%;
    justify-content: center;
    text-align: center;
  }
}

/* 历史数据模态框样式 */
.history-modal-backdrop {
  position: fixed !important;
  top: 0 !important; /* 从页面顶部开始覆盖 */
  left: 200px !important; /* 考虑左侧菜单栏宽度 */
  right: 0 !important;
  bottom: 0 !important;
  background-color: rgba(248, 250, 252, 0.85) !important;
  backdrop-filter: blur(8px) !important;
  z-index: 1000 !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 1rem !important;
  padding-top: 84px !important; /* 给顶部留出导航栏空间，但仍然覆盖 */
  opacity: 1 !important;
  transition: opacity 0.3s ease !important;
  box-sizing: border-box !important;
}

/* 当侧边栏隐藏时的样式调整 */
.hideSidebar .history-modal-backdrop {
  left: 54px !important; /* 折叠后的侧边栏宽度 */
}

/* 移动端适配 */
@media (max-width: 1024px) {
  .history-modal-backdrop {
    left: 0 !important;
    padding-top: 50px !important;
  }
}

.history-modal-content {
  background-color: white !important;
  border-radius: 16px !important;
  width: 100% !important;
  max-width: 1000px !important;
  max-height: 90vh !important;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04) !important;
  border: 1px solid #e5e7eb !important;
  overflow: hidden !important;
  display: flex !important;
  flex-direction: column !important;
}

.history-modal-header {
  display: flex !important;
  justify-content: space-between !important;
  align-items: center !important;
  padding: 1rem 1.5rem !important;
  border-bottom: 1px solid #e5e7eb !important;
  background: #f8fafc !important;
}

.history-modal-title-section {
  display: flex !important;
  align-items: center !important;
  gap: 0.75rem !important;
}

.history-modal-title {
  font-size: 1.125rem !important;
  font-weight: 600 !important;
  color: #1f2937 !important;
  margin: 0 !important;
}

.history-modal-close {
  background: transparent !important;
  border: none !important;
  color: #6b7280 !important;
  cursor: pointer !important;
  padding: 0.5rem !important;
  transition: all 0.2s ease !important;
  border-radius: 8px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 40px !important;
  height: 40px !important;
}

.history-modal-close:hover {
  color: #1f2937 !important;
  background: rgba(16, 185, 129, 0.1) !important;
}

.history-modal-close svg {
  width: 20px !important;
  height: 20px !important;
  stroke: currentColor !important;
  fill: none !important;
}

.history-modal-controls {
  display: flex !important;
  justify-content: space-between !important;
  align-items: center !important;
  padding: 1rem 1.5rem !important;
  border-bottom: 1px solid #e5e7eb !important;
  background: white !important;
}

.time-range-buttons {
  display: flex !important;
  gap: 0.5rem !important;
}

.indicator-buttons {
  display: flex !important;
  gap: 0.5rem !important;
}

.time-range-btn, .indicator-btn {
  padding: 0.5rem 1rem !important;
  border-radius: 8px !important;
  font-size: 0.875rem !important;
  color: #6b7280 !important;
  background: transparent !important;
  border: 1px solid #d1d5db !important;
  transition: all 0.2s ease !important;
  cursor: pointer !important;
}

.time-range-btn:hover, .indicator-btn:hover {
  background: rgba(16, 185, 129, 0.05) !important;
  border-color: #10b981 !important;
  color: #059669 !important;
}

.time-range-btn.active, .indicator-btn.active {
  background: #10b981 !important;
  border-color: #10b981 !important;
  color: white !important;
}

.history-modal-body {
  flex: 1 !important;
  padding: 1.5rem !important;
  background: white !important;
  overflow: hidden !important;
}

.chart-container {
  width: 100% !important;
  height: 400px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  background: transparent !important;
  border-radius: 6px !important;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .history-modal-content {
    margin: 0.5rem !important;
    max-width: calc(100vw - 1rem) !important;
    max-height: calc(100vh - 1rem) !important;
  }

  .history-modal-controls {
    flex-direction: column !important;
    gap: 1rem !important;
    align-items: stretch !important;
  }

  .time-range-buttons, .indicator-buttons {
    flex-wrap: wrap !important;
    justify-content: center !important;
  }

  .time-range-btn, .indicator-btn {
    padding: 0.375rem 0.75rem !important;
    font-size: 0.8rem !important;
  }

  .chart-container {
    height: 300px !important;
  }
}
</style>
