<!--窨井盖监测首页大屏-->
<template>
  <div class="monitor-container">
    <!-- 左侧栏 -->
    <div class="left-col">
      <!-- 待办工单 -->
      <div class="panel">
        <h3 class="panel-title">待办工单 <span class="title-count">{{ workOrders.length }} 条</span></h3>
        <el-table :data="workOrders" class="panel-table" :header-cell-style="tableHeaderStyle" size="small" v-loading="loading.work">
          <el-table-column prop="orderNo" label="工单编号" min-width="120" show-overflow-tooltip />
          <el-table-column label="类型" width="80">
            <template #default="{ row }">{{ orderTypeText(row.orderType) }}</template>
          </el-table-column>
          <el-table-column prop="deviceCode" label="设备" min-width="100" show-overflow-tooltip />
          <el-table-column label="优先级" width="70">
            <template #default="{ row }">
              <span :class="['priority-tag', priorityClass(row.orderLevel)]">{{ priorityText(row.orderLevel) }}</span>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <!-- 告警类型统计（15天内） -->
      <div class="panel">
        <h3 class="panel-title">告警类型统计（15天内）</h3>
        <div ref="alarmChartRef" class="chart" v-loading="loading.alarm" />
      </div>

      <!-- 设备区域信息 -->
      <div class="panel">
        <h3 class="panel-title">设备区域信息</h3>
        <div ref="areaChartRef" class="chart" v-loading="loading.device" />
      </div>
    </div>

    <!-- 中间地图区域 -->
    <div class="center-col">
      <div class="panel map-panel">
        <div class="map-header">
          <span>窨井设备分布</span>
          <div class="map-legend">
            <span><i class="legend-dot online"></i> 在线 {{ stats.online }}</span>
            <span><i class="legend-dot alert"></i> 告警 {{ stats.alarm }}</span>
            <span><i class="legend-dot offline"></i> 离线 {{ stats.offline }}</span>
          </div>
        </div>
        <div id="homeMap" class="bmap-container"></div>
      </div>

      <!-- 设备分类 -->
      <div class="panel chart-panel">
        <h3 class="panel-title">设备分类</h3>
        <div ref="deviceTypeChartRef" class="chart" v-loading="loading.device" />
      </div>
    </div>

    <!-- 右侧栏 -->
    <div class="right-col">
      <!-- 设备列表 -->
      <div class="panel">
        <h3 class="panel-title">设备列表 <span class="title-count">共 {{ filteredDevices.length }} 台</span></h3>
        <div class="filter-bar">
          <el-select v-model="deviceTypeFilter" size="small" placeholder="设备类型" clearable style="width: 120px">
            <el-option label="供水窨井" value="5" />
            <el-option label="排水窨井" value="9" />
            <el-option label="燃气窨井" value="10" />
          </el-select>
        </div>
        <el-table :data="filteredDevices" class="panel-table" :header-cell-style="tableHeaderStyle" size="small" v-loading="loading.device">
          <el-table-column prop="name" label="设备名称" min-width="100" show-overflow-tooltip />
          <el-table-column label="类型" width="70">
            <template #default="{ row }">{{ typeText(row.typeId) }}</template>
          </el-table-column>
          <el-table-column label="电量" width="60">
            <template #default="{ row }">
              <el-tag :type="batteryTag(row.battery)" size="small">{{ row.battery ?? '-' }}%</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="状态" width="60">
            <template #default="{ row }">
              <span :class="['status-dot', row.status]"></span>
              <span class="status-text">{{ statusText(row.status) }}</span>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <!-- 动态信息 -->
      <div class="panel">
        <h3 class="panel-title">动态信息</h3>
        <el-table :data="dynamicLogs" class="panel-table" :header-cell-style="tableHeaderStyle" size="small" v-loading="loading.alarm">
          <el-table-column prop="time" label="时间" width="140" />
          <el-table-column prop="event" label="事件" min-width="120" show-overflow-tooltip />
          <el-table-column label="状态" width="70">
            <template #default="{ row }">
              <span :class="['status-tag', row.alarmStatus === 1 ? 'done' : 'processing']">{{ row.alarmStatus === 1 ? '已处理' : '未处理' }}</span>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount, nextTick, computed } from 'vue'
import * as echarts from 'echarts'
import { getManholeLayerData, getManholeWorkOrderProcessingPage } from '@/api/pipeNetwork/basic'
import { getAlarmDataPage } from '@/api/drainage'
import { ElMessage } from 'element-plus'
import locationIcon from '@/assets/images/location.png'

// ==================== 状态 ====================
const loading = reactive({ work: false, alarm: false, device: false })
const stats = reactive({ total: 0, online: 0, offline: 0, alarm: 0 })

const workOrders = ref([])
const allDevices = ref([])
const dynamicLogs = ref([])
const deviceTypeFilter = ref('')

// 图表引用
const alarmChartRef = ref(null)
const areaChartRef = ref(null)
const deviceTypeChartRef = ref(null)
let alarmChart = null, areaChart = null, deviceTypeChart = null

// ==================== 常量映射 ====================
const TYPE_MAP = { '5': '供水窨井', '9': '排水窨井', '10': '燃气窨井' }
const tableHeaderStyle = { background: 'rgba(0,100,200,0.3)', color: '#fff', borderColor: '#2b4b8c' }

const orderTypeText = (t) => ({ 1: '故障维修', 2: '日常巡检', 3: '设备保养' }[t] || '-')
const priorityText = (l) => ({ 1: '紧急', 2: '一般', 3: '低' }[l] || '-')
const priorityClass = (l) => ({ 1: 'high', 2: 'medium', 3: 'low' }[l] || 'low')
const typeText = (id) => TYPE_MAP[id] || '-'
const statusText = (s) => ({ normal: '在线', alert: '告警', offline: '离线' }[s] || s)
const batteryTag = (b) => {
  if (b == null) return 'info'
  if (Number(b) <= 20) return 'danger'
  if (Number(b) <= 50) return 'warning'
  return 'success'
}

// ==================== 筛选后设备列表 ====================
const filteredDevices = computed(() => {
  if (!deviceTypeFilter.value) return allDevices.value
  return allDevices.value.filter(d => d.typeId === deviceTypeFilter.value)
})

// ==================== 数据加载 ====================
async function loadAll() {
  await Promise.allSettled([loadDevices(), loadWorkOrders(), loadAlarmData()])
  await nextTick()
  handleResize()
}

async function loadDevices() {
  loading.device = true
  try {
    const res = await getManholeLayerData({ isQueryManholeData: true })
    const devices = res.data?.devices || []
    allDevices.value = devices.map(d => {
      const onlineStatus = Number(d.equipmentStatus?.onlineStatus)
      const alarmStatus = Number(d.equipmentStatus?.alarmStatus)
      const manholeAlarm = Number(d.manholeData?.alarmStatus)
      const isAlert = alarmStatus === 1 || manholeAlarm === 1 ||
        Number(d.manholeData?.waterInfiltrationAlarmStatus) === 1 ||
        Number(d.manholeData?.waterLevelAlarmStatus) === 1
      let status = 'offline'
      if (isAlert) status = 'alert'
      else if (onlineStatus === 1) status = 'normal'
      return {
        id: d.equipmentId, code: d.equipmentCode, name: d.equipmentName,
        typeId: d.equipmentTypeId, typeName: d.equipmentTypeName,
        location: d.equipmentLocation, district: d.district,
        lng: d.longitude != null ? Number(d.longitude) : null,
        lat: d.latitude != null ? Number(d.latitude) : null,
        battery: d.manholeData?.batteryLevel ?? null,
        status
      }
    })
    const statistics = res.data?.statistics || {}
    stats.total = statistics.total || allDevices.value.length
    stats.online = statistics.online || 0
    stats.offline = statistics.offline || 0
    stats.alarm = statistics.alarm || 0
    renderAreaChart()
    renderDeviceTypeChart()
    refreshMarkers()
  } catch (e) {
    ElMessage.error('设备数据加载失败')
  } finally {
    loading.device = false
  }
}

async function loadWorkOrders() {
  loading.work = true
  try {
    const res = await getManholeWorkOrderProcessingPage({ pageNum: 1, pageSize: 20 })
    workOrders.value = res.data?.records || []
  } catch (e) {
    ElMessage.error('工单数据加载失败')
  } finally {
    loading.work = false
  }
}

async function loadAlarmData() {
  loading.alarm = true
  try {
    const res = await getAlarmDataPage(1, 500, {})
    const records = res.rows || res.data?.records || res.data || []
    const now = new Date()
    const fifteenDaysAgo = new Date(now.getTime() - 15 * 24 * 60 * 60 * 1000)
    // 筛选15天内的告警
    const recentAlarms = records.filter(r => {
      const t = new Date(r.alarmTime || r.createTime)
      return t >= fifteenDaysAgo
    })
    // 告警类型统计
    const typeMap = {}
    recentAlarms.forEach(r => {
      const type = r.warningType || '其他'
      typeMap[type] = (typeMap[type] || 0) + 1
    })
    renderAlarmChart(typeMap)
    // 动态信息（最新10条）
    dynamicLogs.value = records.slice(0, 10).map(r => ({
      time: r.alarmTime || r.createTime || '',
      event: `${r.warningType || '告警'} - ${r.deviceName || r.deviceCode || ''}`,
      alarmStatus: r.alarmStatus ?? 0
    }))
  } catch (e) {
    ElMessage.error('告警数据加载失败')
  } finally {
    loading.alarm = false
  }
}

// ==================== ECharts ====================
function renderAlarmChart(typeMap) {
  if (!alarmChartRef.value) return
  if (!alarmChart) alarmChart = echarts.init(alarmChartRef.value)
  const colors = ['#ff3333', '#ffb333', '#33cc33', '#3399ff', '#9966ff', '#ff6699', '#33cccc']
  const data = Object.entries(typeMap).map(([name, value], i) => ({
    name, value, itemStyle: { color: colors[i % colors.length] }
  }))
  alarmChart.setOption({
    backgroundColor: 'transparent',
    tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
    legend: { bottom: 0, textStyle: { color: '#ccc', fontSize: 10 } },
    series: [{
      type: 'pie', radius: ['35%', '60%'], center: ['50%', '40%'],
      label: { color: '#ccc', fontSize: 10 },
      data: data.length ? data : [{ name: '暂无数据', value: 0 }]
    }]
  })
}

function renderAreaChart() {
  if (!areaChartRef.value) return
  if (!areaChart) areaChart = echarts.init(areaChartRef.value)
  const areaMap = {}
  allDevices.value.forEach(d => {
    const area = d.district || d.location || '未分配区域'
    // 取区域名（截取前4个字）
    const shortArea = area.length > 6 ? area.slice(0, 6) + '...' : area
    areaMap[shortArea] = (areaMap[shortArea] || 0) + 1
  })
  const entries = Object.entries(areaMap).sort((a, b) => b[1] - a[1]).slice(0, 8)
  areaChart.setOption({
    backgroundColor: 'transparent',
    tooltip: { trigger: 'axis' },
    grid: { left: '12%', right: '8%', bottom: '18%', top: '8%' },
    xAxis: {
      type: 'category', data: entries.map(e => e[0]),
      axisLabel: { color: '#ccc', fontSize: 10, interval: 0, rotate: 30 }
    },
    yAxis: { type: 'value', axisLabel: { color: '#ccc' }, splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } } },
    series: [{ type: 'bar', data: entries.map(e => e[1]), itemStyle: { color: '#3399ff' } }]
  })
}

function renderDeviceTypeChart() {
  if (!deviceTypeChartRef.value) return
  if (!deviceTypeChart) deviceTypeChart = echarts.init(deviceTypeChartRef.value)
  const typeCount = { '5': 0, '9': 0, '10': 0 }
  allDevices.value.forEach(d => { if (typeCount[d.typeId] != null) typeCount[d.typeId]++ })
  const labels = ['供水窨井', '排水窨井', '燃气窨井']
  const values = [typeCount['5'], typeCount['9'], typeCount['10']]
  const colors = ['#3399ff', '#67c23a', '#e6a23c']
  deviceTypeChart.setOption({
    backgroundColor: 'transparent',
    tooltip: { trigger: 'axis' },
    grid: { left: '12%', right: '8%', bottom: '15%', top: '8%' },
    xAxis: {
      type: 'category', data: labels,
      axisLabel: { color: '#ccc', fontSize: 11, interval: 0 }
    },
    yAxis: { type: 'value', axisLabel: { color: '#ccc' }, splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } } },
    series: [{
      type: 'bar', data: values.map((v, i) => ({ value: v, itemStyle: { color: colors[i] } })),
      barWidth: '40%', label: { show: true, position: 'top', color: '#ccc' }
    }]
  })
}

// ==================== 百度地图 ====================
let mapInstance = null
const markerMap = new Map()
const YUANLING_CENTER = { lng: 110.393, lat: 28.452 }

function initMap() {
  const container = document.getElementById('homeMap')
  if (!container || typeof BMapGL === 'undefined') return
  try {
    mapInstance = new BMapGL.Map('homeMap')
    mapInstance.centerAndZoom(new BMapGL.Point(YUANLING_CENTER.lng, YUANLING_CENTER.lat), 13)
    mapInstance.enableScrollWheelZoom(true)
  } catch (e) { console.error('地图初始化失败', e) }
}

function getStatusColor(status) {
  if (status === 'alert') return '#F56C6C'
  if (status === 'offline') return '#909399'
  return '#67C23A'
}

function refreshMarkers() {
  if (!mapInstance) return
  markerMap.forEach(label => mapInstance.removeOverlay(label))
  markerMap.clear()
  allDevices.value.forEach(d => {
    if (d.lng == null || d.lat == null) return
    const color = getStatusColor(d.status)
    const html = `<div style="text-align:center;cursor:pointer;">
      <div style="color:#fff;background:${color};border-radius:3px;padding:1px 6px;font-size:10px;white-space:nowrap;display:inline-block;margin-bottom:2px;box-shadow:0 1px 3px rgba(0,0,0,0.3);">${d.name}</div>
      <div><img src="${locationIcon}" style="width:22px;height:22px;display:block;margin:0 auto;"/></div>
    </div>`
    const label = new BMapGL.Label(html, {
      position: new BMapGL.Point(d.lng, d.lat),
      offset: new BMapGL.Size(-25, -40)
    })
    label.setStyle({ border: 'none', background: 'transparent', padding: '0', zIndex: '10' })
    mapInstance.addOverlay(label)
    markerMap.set(d.id, label)
  })
}

// ==================== 生命周期 ====================
const handleResize = () => {
  alarmChart && alarmChart.resize()
  areaChart && areaChart.resize()
  deviceTypeChart && deviceTypeChart.resize()
  mapInstance && mapInstance.resize && mapInstance.resize()
}

onMounted(async () => {
  await nextTick()
  initMap()
  window.addEventListener('resize', handleResize)
  loadAll()
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
  alarmChart && alarmChart.dispose()
  areaChart && areaChart.dispose()
  deviceTypeChart && deviceTypeChart.dispose()
  if (mapInstance) {
    mapInstance.clearOverlays && mapInstance.clearOverlays()
    mapInstance = null
  }
  markerMap.clear()
})
</script>

<!-- ==================== 全局样式（非 scoped）：el-table 深色主题覆盖 ==================== -->
<!-- 用 .monitor-container 限定范围，不影响其他页面 -->
<style>
.monitor-container .el-table {
  --el-table-bg-color: transparent;
  --el-table-tr-bg-color: transparent;
  --el-table-header-bg-color: transparent;
  --el-table-current-row-bg-color: rgba(0, 100, 200, 0.25);
  --el-table-row-hover-bg-color: rgba(0, 100, 200, 0.15);
  --el-table-text-color: #dce3ee;
  --el-table-header-text-color: #fff;
  --el-table-border-color: rgba(43, 75, 140, 0.35);
  --el-table-border: 1px solid rgba(43, 75, 140, 0.35);
  --el-fill-color-lighter: rgba(30, 40, 90, 0.25);
  --el-fill-color-light: rgba(30, 40, 90, 0.25);
  --el-fill-color: rgba(30, 40, 90, 0.25);
  --el-fill-color-blank: transparent;
  --el-text-color-regular: #dce3ee;
  --el-text-color-secondary: #9ba8c0;
  --el-border-color: rgba(43, 75, 140, 0.35);
  --el-border-color-lighter: rgba(43, 75, 140, 0.2);
  background: transparent !important;
  border: none !important;
}
/* 隐藏 EP 表格自带的底部/右侧边框伪元素 */
.monitor-container .el-table::before,
.monitor-container .el-table::after,
.monitor-container .el-table .el-table__inner-wrapper::before,
.monitor-container .el-table .el-table__inner-wrapper::after {
  display: none !important;
}
/* 内部容器全透明 */
.monitor-container .el-table .el-table__inner-wrapper,
.monitor-container .el-table .el-table__body-wrapper,
.monitor-container .el-table .el-table__header-wrapper,
.monitor-container .el-table .el-table__body,
.monitor-container .el-table .el-table__header {
  background: transparent !important;
}
/* 表头单元格 — EP 2.x 使用 th.el-table__cell */
.monitor-container .el-table th.el-table__cell {
  background: rgba(0, 100, 200, 0.35) !important;
  color: #fff !important;
  font-weight: 600;
  border-bottom: 1px solid #2b4b8c !important;
}
/* 内容单元格 */
.monitor-container .el-table td.el-table__cell {
  background: transparent !important;
  border-bottom: 1px solid rgba(43, 75, 140, 0.25) !important;
  padding: 7px 0 !important;
}
/* 行 */
.monitor-container .el-table .el-table__row {
  background: transparent !important;
}
.monitor-container .el-table .el-table__row:hover > td.el-table__cell {
  background: rgba(0, 100, 200, 0.15) !important;
}
/* 空数据 */
.monitor-container .el-table .el-table__empty-block {
  background: transparent !important;
}
.monitor-container .el-table .el-table__empty-text {
  color: #8090a8;
}
/* 滚动条 */
.monitor-container .el-table .el-scrollbar__bar {
  opacity: 0.4;
}
/* el-select 输入框深色适配 */
.monitor-container .el-select .el-input__wrapper {
  background: rgba(30, 40, 90, 0.6);
  box-shadow: 0 0 0 1px rgba(43, 75, 140, 0.5) inset;
}
.monitor-container .el-select .el-input__inner {
  color: #dce3ee;
}
/* el-table 在 flex 容器中撑满高度（无 max-height 时） */
.monitor-container .el-table {
  height: 100% !important;
  display: flex;
  flex-direction: column;
}
.monitor-container .el-table .el-table__inner-wrapper {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.monitor-container .el-table .el-table__body-wrapper {
  flex: 1;
  min-height: 0;
}
</style>

<!-- ==================== 页面布局样式（scoped） ==================== -->
<style scoped>
.monitor-container {
  display: flex;
  width: 100%;
  height: 100vh;
  min-height: 600px;
  background: #1a1a4a;
  color: #fff;
  gap: 16px;
  padding: 16px;
  box-sizing: border-box;
  overflow: hidden;
}
.left-col {
  flex: 0 0 25%;
  min-width: 280px;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 0;
}
.right-col {
  flex: 0 0 25%;
  min-width: 280px;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 0;
}
.center-col {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 0;
}
.panel {
  flex: 1;
  background: rgba(30, 40, 90, 0.8);
  border: 1px solid #2b4b8c;
  border-radius: 8px;
  padding: 14px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
/* 设备分类固定高度，不参与均分 */
.chart-panel {
  flex: 0 0 190px;
}
.panel-title {
  margin: 0 0 10px 0;
  font-size: 14px;
  color: #66ccff;
  border-left: 3px solid #66ccff;
  padding-left: 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}
.title-count {
  font-size: 12px;
  color: #aaa;
  font-weight: normal;
}
.panel-table {
  width: 100%;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}
.chart {
  width: 100%;
  flex: 1;
  min-height: 100px;
}
.map-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.map-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: 14px;
  color: #66ccff;
  flex-shrink: 0;
}
.map-legend {
  display: flex;
  gap: 12px;
  font-size: 11px;
}
.legend-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 3px;
}
.legend-dot.online { background: #67c23a; }
.legend-dot.alert { background: #f56c6c; }
.legend-dot.offline { background: #909399; }
.bmap-container {
  width: 100%;
  flex: 1;
  min-height: 200px;
  border-radius: 4px;
  overflow: hidden;
}
.filter-bar {
  margin-bottom: 10px;
  flex-shrink: 0;
}
.priority-tag {
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 11px;
  color: #fff;
}
.priority-tag.high { background: #ff3333; }
.priority-tag.medium { background: #ffb333; color: #333; }
.priority-tag.low { background: #33cc33; }
.status-tag {
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 11px;
  color: #fff;
}
.status-tag.processing { background: #3399ff; }
.status-tag.done { background: #33cc33; }
.status-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 3px;
}
.status-dot.normal { background: #67c23a; }
.status-dot.alert { background: #f56c6c; }
.status-dot.offline { background: #909399; }
.status-text {
  font-size: 11px;
  color: #dce3ee;
}

/* === 响应式 === */
@media (max-width: 1600px) {
  .left-col, .right-col { flex: 0 0 24%; min-width: 260px; max-width: 380px; }
  .monitor-container { gap: 12px; padding: 12px; }
  .panel { padding: 12px; }
  .chart-panel { flex-basis: 170px; }
}
@media (max-width: 1366px) {
  .left-col, .right-col { flex: 0 0 27%; min-width: 240px; max-width: 340px; }
  .monitor-container { gap: 10px; padding: 10px; }
  .panel { padding: 10px; }
  .chart-panel { flex-basis: 150px; }
}
@media (max-width: 1024px) {
  .monitor-container {
    flex-direction: column;
    height: auto;
    min-height: 100vh;
    overflow: auto;
  }
  .left-col, .right-col {
    flex: 1 1 auto;
    min-width: 100%;
    max-width: 100%;
  }
  .center-col {
    flex: 1 1 auto;
    min-width: 100%;
  }
}
</style>
