<template>
  <div class="gwyxqk-screen">
    <!-- ==================== 顶部标题栏 ==================== -->
    <div class="screen-header">
      <div class="header-left">
        <span class="header-time">{{ currentDateTime }}</span>
      </div>
      <div class="header-center">
        <h1 class="header-title">管网运行情况GIS一张图</h1>
      </div>
      <div class="header-right">
      </div>
    </div>

    <!-- ==================== 主体三栏布局 ==================== -->
    <div class="screen-body">
      <!-- ========== 左侧面板 ========== -->
      <div class="panel-left">
        <!-- 管网概况 -->
        <div class="panel-box">
          <div class="panel-title">
            <span class="title-icon">▶</span> 管网概况
          </div>
          <div class="stats-cards">
            <div class="stat-card">
              <div class="stat-val">{{ overviewStats.total }}</div>
              <div class="stat-label">监测点总数</div>
            </div>
            <div class="stat-card">
              <div class="stat-val green">{{ overviewStats.normal }}</div>
              <div class="stat-label">正常运行</div>
            </div>
            <div class="stat-card">
              <div class="stat-val orange">{{ overviewStats.alarm }}</div>
              <div class="stat-label">异常报警</div>
            </div>
            <div class="stat-card">
              <div class="stat-val gray">{{ overviewStats.offline }}</div>
              <div class="stat-label">离线设备</div>
            </div>
          </div>
          <div class="pie-chart-wrapper">
            <div id="gwyxqkPieChart" class="chart-area"></div>
            <div class="pie-legend">
              <div class="legend-item" v-for="(item, i) in pieData" :key="i">
                <span class="legend-dot" :style="{ background: item.color }"></span>
                <span class="legend-label">{{ item.name }}</span>
                <span class="legend-value">{{ item.value }}</span>
              </div>
            </div>
          </div>
        </div>

        <!-- 实时数据表 -->
        <div class="panel-box" style="flex: 1;">
          <div class="panel-title">
            <span class="title-icon">▶</span> 实时数据
            <span class="refresh-time">刷新: {{ refreshTime }}</span>
          </div>
          <div class="realtime-table-wrap">
            <table class="dark-table">
              <thead>
                <tr>
                  <th>监测点名称</th>
                  <th>流量(m³/h)</th>
                  <th>液位(m)</th>
                  <th>状态</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(row, i) in realtimeData" :key="i">
                  <td :title="row.name">{{ row.name }}</td>
                  <td>{{ row.flow }}</td>
                  <td>{{ row.level }}</td>
                  <td>
                    <span :class="'status-tag status-' + row.statusClass">{{ row.status }}</span>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>

      <!-- ========== 中间地图区域 ========== -->
      <div class="panel-center">
        <div class="map-search">
          <input type="text" placeholder="输入监测点名称" class="search-input" />
          <span class="search-icon">🔍</span>
        </div>
        <div id="gwyxqkMap" class="map-container"></div>
      </div>

      <!-- ========== 右侧面板 ========== -->
      <div class="panel-right">
        <!-- 监测曲线 -->
        <div class="panel-box">
          <div class="panel-title">
            <span class="title-icon">▶</span> 监测曲线
            <select v-model="selectedCurveDevice" class="device-select" @change="onCurveDeviceChange">
              <option value="">请选择设备</option>
              <option v-for="d in linkedDeviceList" :key="d.equipmentId" :value="d.equipmentCode">{{ d.equipmentName }}</option>
            </select>
          </div>
          <div class="curve-tabs">
            <span
              v-for="tab in curveTabs"
              :key="tab.value"
              :class="['curve-tab', { active: activeCurveTab === tab.value }]"
              @click="activeCurveTab = tab.value"
            >{{ tab.label }}</span>
          </div>
          <div id="gwyxqkLineChart" class="chart-area-sm"></div>
        </div>

        <!-- 流量统计 -->
        <div class="panel-box">
          <div class="panel-title">
            <span class="title-icon">▶</span> 流量统计
          </div>
          <div id="gwyxqkBarChart" class="chart-area-sm"></div>
        </div>

        <!-- 报警信息 -->
        <div class="panel-box">
          <div class="panel-title">
            <span class="title-icon">▶</span> 报警信息
          </div>
          <div class="alert-stats">
            <div class="alert-stat-card">
              <div class="alert-stat-val">{{ alarmStats.total }}</div>
              <div class="alert-stat-label">报警总数</div>
            </div>
            <div class="alert-stat-card">
              <div class="alert-stat-val green">{{ alarmStats.handled }}</div>
              <div class="alert-stat-label">已处理</div>
            </div>
            <div class="alert-stat-card">
              <div class="alert-stat-val red">{{ alarmStats.unhandled }}</div>
              <div class="alert-stat-label">未处理</div>
            </div>
          </div>
          <div class="alert-table-wrap">
            <table class="dark-table">
              <thead>
                <tr>
                  <th>序号</th>
                  <th>监测点</th>
                  <th>时间</th>
                  <th>类型</th>
                  <th>状态</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(row, i) in alarmList" :key="i">
                  <td>{{ i + 1 }}</td>
                  <td :title="row.point">{{ row.point }}</td>
                  <td>{{ row.time }}</td>
                  <td>{{ row.type }}</td>
                  <td>
                    <span :class="'status-tag status-' + row.handleClass">{{ row.handleStatus }}</span>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup name="Gwyxqk">
import { ref, reactive, onMounted, onUnmounted, watch } from 'vue'
import * as echarts from 'echarts'
import locationIcon from '@/assets/images/location.png'
import { getPipeNetworkPage, getEquipmentPage, getAlarmDataPage, getRadarDataByCode, getRadarDataHistory } from '@/api/drainage'

// ==================== 实时时间 ====================
const currentDateTime = ref('')
let timer = null

function updateTime() {
  const now = new Date()
  const pad = n => String(n).padStart(2, '0')
  const weekDays = ['日', '一', '二', '三', '四', '五', '六']
  currentDateTime.value = `${now.getFullYear()}/${pad(now.getMonth() + 1)}/${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())} 星期${weekDays[now.getDay()]}`
}

// ==================== 刷新时间 ====================
const refreshTime = ref('')
function updateRefreshTime() {
  const now = new Date()
  const pad = n => String(n).padStart(2, '0')
  refreshTime.value = `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
}

// ==================== 管网概况（从API数据计算）====================
const overviewStats = reactive({ total: 0, normal: 0, alarm: 0, offline: 0 })

const pieData = ref([
  { name: '正常运行', value: 0, color: '#67c23a' },
  { name: '预警', value: 0, color: '#e6a23c' },
  { name: '报警', value: 0, color: '#f56c6c' },
  { name: '离线', value: 0, color: '#909399' }
])

// ==================== 实时数据（从radar_data API加载）====================
const realtimeData = ref([])

// ==================== 监测曲线 ====================
const curveTabs = [
  { label: '24小时', value: '24h' },
  { label: '7天', value: '7d' },
  { label: '15天', value: '15d' },
  { label: '30天', value: '30d' }
]
const activeCurveTab = ref('24h')

// ==================== 设备下拉与曲线选择 ====================
const linkedDeviceList = ref([])
const selectedCurveDevice = ref('')

// ==================== 报警信息（从API加载）====================
const alarmStats = reactive({ total: 0, handled: 0, unhandled: 0 })
const alarmList = ref([])

// ==================== 地图数据（从API加载）====================
const mapPoints = ref([])
const pipeNetworkData = ref([])

// ==================== 设备状态映射 ====================
function getEquipStatusInfo(equipment) {
  if (equipment.onlineStatus === 0) return { status: '离线', color: '#909399' }
  if (equipment.alarmStatus === 1) return { status: '报警', color: '#f56c6c' }
  if (equipment.currentStatus === 3) return { status: '预警', color: '#e6a23c' }
  return { status: '正常', color: '#67c23a' }
}

function getCurrentStatusText(val) {
  const map = { 1: '在用', 2: '闲置', 3: '维修', 4: '报废', 5: '待入库' }
  return map[val] || '未知'
}

// ==================== 分页响应兼容提取 ====================
function extractPage(res) {
  const page = res.code !== undefined ? res.data : res
  return page.records || page.rows || []
}

// ==================== 数据加载 ====================
async function loadMapData() {
  try {
    // 1. 获取所有管网
    const pnRes = await getPipeNetworkPage(1, 999, {})
    const pipeNetworks = extractPage(pnRes)
    pipeNetworkData.value = pipeNetworks
    console.log('[gwyxqk] 管网数据：', pipeNetworks.length, '条')

    // 2. 从管网收集关联设备ID（去重）
    const linkedEqIds = new Set()
    pipeNetworks.forEach(pn => {
      if (pn.equipmentId) {
        // equipmentId 可能是逗号分隔的多个ID
        String(pn.equipmentId).split(',').forEach(id => {
          const trimmed = id.trim()
          if (trimmed) linkedEqIds.add(trimmed)
        })
      }
    })
    console.log('[gwyxqk] 管网关联设备ID数量：', linkedEqIds.size)

    // 3. 获取所有排水设备
    const eqRes = await getEquipmentPage(1, 999, { equipmentTypeId: 'drainage' })
    const allEquipment = extractPage(eqRes)
    console.log('[gwyxqk] 排水设备总数：', allEquipment.length)

    // 4. 匹配关联设备（同时兼容 id 和 equipmentId 字段）
    const linkedEquipment = allEquipment.filter(eq => {
      const eqId = String(eq.id || '')
      const eqEquipId = String(eq.equipmentId || '')
      return linkedEqIds.has(eqId) || linkedEqIds.has(eqEquipId)
    })
    console.log('[gwyxqk] 匹配到的关联设备：', linkedEquipment.length)

    // 构建关联设备列表（供下拉选择）
    linkedDeviceList.value = linkedEquipment.map(eq => ({
      equipmentId: eq.equipmentId || eq.id,
      equipmentCode: eq.equipmentCode || '',
      equipmentName: eq.equipmentName || '未命名设备'
    }))
    if (linkedDeviceList.value.length > 0 && !selectedCurveDevice.value) {
      selectedCurveDevice.value = linkedDeviceList.value[0].equipmentCode
    }

    // 5. 获取报警数据
    let alarmRecords = []
    try {
      const alarmRes = await getAlarmDataPage(1, 999, { deviceType: 'drainage' })
      alarmRecords = extractPage(alarmRes)
    } catch (alarmErr) {
      console.warn('[gwyxqk] 报警数据加载失败：', alarmErr)
    }

    // 构建报警设备编码集合
    const alarmDeviceCodes = new Set(alarmRecords.map(a => a.deviceCode))

    // 6. 确定用于展示和统计的设备列表（优先关联设备，无关联则用全部设备）
    const displayEquipment = linkedEquipment.length > 0 ? linkedEquipment : allEquipment

    // 对每个设备，始终优先使用关联管网的points字段坐标（与排水管网基础数据管理页面保持一致）
    displayEquipment.forEach(eq => {
      const parentNetwork = pipeNetworks.find(pn => {
        const ids = String(pn.equipmentId || '').split(',').map(s => s.trim())
        return ids.includes(String(eq.id || '')) || ids.includes(String(eq.equipmentId || ''))
      })
      if (parentNetwork) {
        const pts = parsePipeNetworkPoints(parentNetwork)
        if (pts.length > 0) {
          eq.longitude = String(pts[0].lng)
          eq.latitude = String(pts[0].lat)
          console.log('[gwyxqk] 设备', eq.equipmentCode, '使用管网points坐标', pts[0].lng, pts[0].lat)
        }
      }
    })

    // 7. 统计概况
    const totalCount = displayEquipment.length
    const offlineCount = displayEquipment.filter(e => e.onlineStatus === 0).length
    const alarmCount = displayEquipment.filter(e => e.onlineStatus === 1 && alarmDeviceCodes.has(e.equipmentCode)).length
    const warningCount = displayEquipment.filter(e => e.onlineStatus === 1 && !alarmDeviceCodes.has(e.equipmentCode) && e.currentStatus === 3).length
    const normalCount = totalCount - offlineCount - alarmCount - warningCount

    overviewStats.total = totalCount
    overviewStats.offline = offlineCount
    overviewStats.alarm = alarmCount
    overviewStats.normal = normalCount >= 0 ? normalCount : 0

    pieData.value = [
      { name: '正常运行', value: overviewStats.normal, color: '#67c23a' },
      { name: '预警', value: warningCount, color: '#e6a23c' },
      { name: '报警', value: overviewStats.alarm, color: '#f56c6c' },
      { name: '离线', value: overviewStats.offline, color: '#909399' }
    ]

    // 8. 转换设备为地图点位（使用管网名称作为监测点名称）
    mapPoints.value = displayEquipment
      .filter(e => {
        const lng = parseFloat(e.longitude)
        const lat = parseFloat(e.latitude)
        return lng && lat && !isNaN(lng) && !isNaN(lat)
      })
      .map(e => {
        const statusInfo = getEquipStatusInfo(e)
        // 查找设备关联的管网名称作为监测点名称
        const parentPn = pipeNetworks.find(pn => {
          const ids = String(pn.equipmentId || '').split(',').map(s => s.trim())
          return ids.includes(String(e.id || '')) || ids.includes(String(e.equipmentId || ''))
        })
        const monitorName = parentPn ? (parentPn.name || parentPn.networkName || '监测点') : (e.equipmentName || '未命名设备')
        return {
          name: monitorName,
          lng: parseFloat(e.longitude),
          lat: parseFloat(e.latitude),
          status: statusInfo.status,
          color: statusInfo.color,
          equipment: e
        }
      })
    console.log('[gwyxqk] mapPoints生成：', mapPoints.value.length, '个点', mapPoints.value.map(p => p.name + '(' + p.lng + ',' + p.lat + ')'))

    // 9. 加载实时数据（传入管网列表用于获取监测点名称）
    await loadRealtimeData(displayEquipment, pipeNetworks)

    // 10. 加载报警信息
    loadAlarmData(alarmRecords, displayEquipment)

    console.log('[gwyxqk] 数据加载完成')
  } catch (error) {
    console.error('加载地图数据失败：', error)
  }
}

// ==================== 实时数据加载（/latest 返回单条 RadarData 对象）====================
async function loadRealtimeData(equipmentList, pipeNetworks) {
  console.log('[gwyxqk] loadRealtimeData 收到设备：', equipmentList.length, '条', equipmentList.map(e => e.equipmentCode))
  const rows = []
  for (const eq of equipmentList) {
    const code = eq.equipmentCode
    // 监测点名称使用关联管网名称
    const parentPn = (pipeNetworks || []).find(pn => {
      const ids = String(pn.equipmentId || '').split(',').map(s => s.trim())
      return ids.includes(String(eq.id || '')) || ids.includes(String(eq.equipmentId || ''))
    })
    const name = parentPn ? (parentPn.name || parentPn.networkName || '监测点') : (eq.equipmentName || '未命名设备')
    let flow = '--'
    let level = '--'
    let status = '离线'
    let statusClass = 'offline'

    if (eq.onlineStatus === 1) {
      status = '正常'
      statusClass = 'normal'
    }

    if (code) {
      try {
        const radarRes = await getRadarDataByCode(code)
        console.log('[gwyxqk] 设备', code, 'radar /latest 原始响应：', radarRes)
        // /latest 接口直接返回单条 RadarData 对象
        const latest = radarRes.code !== undefined ? radarRes.data : radarRes
        if (latest) {
          // 兼容驼峰和下划线两种字段命名
          const waterLevel = latest.waterLevel ?? latest.water_level
          const instantFlow = latest.meter1InstantFlow ?? latest.meter1_instant_flow
          const flowSpeed = latest.flowSpeed ?? latest.flow_speed
          level = waterLevel != null ? Number(waterLevel).toFixed(2) : '--'
          flow = instantFlow != null ? Number(instantFlow).toFixed(1) :
                 flowSpeed != null ? Number(flowSpeed).toFixed(1) : '--'
        }
      } catch (err) {
        console.warn('[gwyxqk] 设备', code, 'radar_data查询失败：', err)
      }
    }

    rows.push({ name, flow, level, status, statusClass })
  }
  realtimeData.value = rows
  console.log('[gwyxqk] 实时数据加载完成：', rows.length, '条')
}

// ==================== 报警数据加载 ====================
function loadAlarmData(alarmRecords, equipmentList) {
  // 构建设备编码→名称映射
  const codeNameMap = {}
  equipmentList.forEach(eq => {
    if (eq.equipmentCode) codeNameMap[eq.equipmentCode] = eq.equipmentName || eq.equipmentCode
  })

  // 过滤只保留关联设备的报警
  const linkedCodes = new Set(Object.keys(codeNameMap))
  const filtered = linkedCodes.size > 0
    ? alarmRecords.filter(a => linkedCodes.has(a.deviceCode))
    : alarmRecords

  // 统计
  const total = filtered.length
  const handled = filtered.filter(a => a.handleStatus === 1 || a.handleStatus === '已处理' || a.status === 1).length
  const unhandled = total - handled

  alarmStats.total = total
  alarmStats.handled = handled
  alarmStats.unhandled = unhandled

  // 列表
  alarmList.value = filtered.slice(0, 50).map(a => {
    const isHandled = a.handleStatus === 1 || a.handleStatus === '已处理' || a.status === 1
    return {
      point: codeNameMap[a.deviceCode] || a.deviceCode || '-',
      time: a.alarmTime || a.createTime || '-',
      type: a.warningType || a.alarmType || '-',
      handleStatus: isHandled ? '已处理' : '未处理',
      handleClass: isHandled ? 'normal' : 'alarm'
    }
  })
  console.log('[gwyxqk] 报警数据加载完成：', total, '条')
}

// ==================== 地图初始化 ====================
let mapInstance = null

function initMap() {
  const container = document.getElementById('gwyxqkMap')
  if (!container || typeof BMapGL === 'undefined') {
    console.warn('BMapGL 未加载或容器不存在')
    return
  }

  try {
    mapInstance = new BMapGL.Map('gwyxqkMap')
    // 默认中心点，有数据时以第一个设备点为中心
    let centerLng = 110.393
    let centerLat = 28.452
    if (mapPoints.value.length > 0) {
      centerLng = mapPoints.value[0].lng
      centerLat = mapPoints.value[0].lat
    }
    const centerPoint = new BMapGL.Point(centerLng, centerLat)
    mapInstance.centerAndZoom(centerPoint, 14)
    mapInstance.enableScrollWheelZoom(true)

    // 地图只显示实时数据中的设备点位，自动定位到第一个设备
    console.log('[gwyxqk] 初始化地图，设备点数量：', mapPoints.value.length)
    mapPoints.value.forEach(point => {
      addMapMarker(point)
    })
  } catch (e) {
    console.error('百度地图初始化失败：', e)
  }
}

function addMapMarker(point) {
  const color = point.color || '#409eff'
  const bPoint = new BMapGL.Point(point.lng, point.lat)

  const html = `<div style="text-align:center;cursor:pointer;">
    <div style="color:#fff;background:${color};border-radius:4px;padding:2px 6px;font-size:11px;white-space:nowrap;display:inline-block;margin-bottom:2px;">${point.name}</div>
    <div style="color:#fff;font-size:10px;background:rgba(0,0,0,0.6);border-radius:3px;padding:1px 4px;margin-bottom:2px;">状态：${point.status}</div>
    <div><img src="${locationIcon}" style="width:24px;height:24px;display:block;margin:0 auto;"/></div>
  </div>`

  const label = new BMapGL.Label(html, {
    position: bPoint,
    offset: new BMapGL.Size(-30, -55)
  })
  label.setStyle({
    border: 'none',
    background: 'transparent',
    padding: '0'
  })
  mapInstance.addOverlay(label)

  // 点击标记弹出设备信息窗口
  label.addEventListener('click', function () {
    const eq = point.equipment || {}
    const infoContent = `<div style="color:#333;font-size:13px;padding:4px;">
      <div style="font-weight:bold;margin-bottom:6px;">${point.name}</div>
      <div>设备编号：${eq.equipmentCode || '-'}</div>
      <div>安装位置：${eq.equipmentLocation || '-'}</div>
      <div>设备状态：<b style="color:${color}">${getCurrentStatusText(eq.currentStatus)}</b></div>
      <div>报警状态：<b style="color:${eq.alarmStatus === 1 ? '#f56c6c' : '#67c23a'}">${eq.alarmStatus === 1 ? '报警' : '正常'}</b></div>
      <div>在线状态：<b style="color:${eq.onlineStatus === 1 ? '#67c23a' : '#909399'}">${eq.onlineStatus === 1 ? '在线' : '离线'}</b></div>
      <div>最近维护：${eq.lastMaintainDate || '-'}</div>
      <div>下次维护：${eq.nextMaintainDate || '-'}</div>
      <div>经度：${point.lng}</div>
      <div>纬度：${point.lat}</div>
    </div>`
    const infoWindow = new BMapGL.InfoWindow(infoContent, {
      width: 240,
      title: ''
    })
    mapInstance.openInfoWindow(infoWindow, bPoint)
  })
}

// 解析管网points字段为坐标数组
function parsePipeNetworkPoints(network) {
  // 优先从 points JSON 字段解析
  if (network.points) {
    try {
      const parsed = typeof network.points === 'string' ? JSON.parse(network.points) : network.points
      if (Array.isArray(parsed) && parsed.length > 0) return parsed
    } catch (e) { /* ignore */ }
  }
  // 回退到 longitude/latitude 字段
  if (network.longitude && network.latitude) {
    return [{ name: network.name || network.networkName || '管网', lng: Number(network.longitude), lat: Number(network.latitude) }]
  }
  return []
}

function addPipeNetworkMarker(network) {
  const points = parsePipeNetworkPoints(network)
  if (points.length === 0) {
    console.log('[gwyxqk] 管网无坐标跳过：', network.name || network.networkName)
    return
  }
  const networkName = network.name || network.networkName || '管网'
  points.forEach(p => {
    if (!p.lng || !p.lat) return
    const bPoint = new BMapGL.Point(Number(p.lng), Number(p.lat))
    const pointName = p.name || networkName

    const html = `<div style="text-align:center;cursor:pointer;">
      <div style="color:#fff;background:#409eff;border-radius:4px;padding:2px 6px;font-size:11px;white-space:nowrap;display:inline-block;margin-bottom:2px;">${pointName}</div>
      <div style="color:#fff;font-size:10px;background:rgba(0,0,0,0.6);border-radius:3px;padding:1px 4px;margin-bottom:2px;">${network.networkType || '-'}</div>
      <div><img src="${locationIcon}" style="width:20px;height:20px;display:block;margin:0 auto;"/></div>
    </div>`

    const label = new BMapGL.Label(html, {
      position: bPoint,
      offset: new BMapGL.Size(-30, -50)
    })
    label.setStyle({
      border: 'none',
      background: 'transparent',
      padding: '0'
    })
    mapInstance.addOverlay(label)

    // 点击标记弹出管网信息窗口
    label.addEventListener('click', function () {
      const infoContent = `<div style="color:#333;font-size:13px;padding:4px;">
        <div style="font-weight:bold;margin-bottom:6px;">${pointName}</div>
        <div>所属管网：${networkName}</div>
        <div>管网类型：${network.networkType || '-'}</div>
        <div>所在区域：${network.area || '-'}</div>
        <div>经度：${p.lng}</div>
        <div>纬度：${p.lat}</div>
      </div>`
      const infoWindow = new BMapGL.InfoWindow(infoContent, {
        width: 240,
        title: ''
      })
      mapInstance.openInfoWindow(infoWindow, bPoint)
    })
  })
}

// ==================== ECharts 图表 ====================
let pieChart = null
let lineChart = null
let barChart = null

function initPieChart() {
  const dom = document.getElementById('gwyxqkPieChart')
  if (!dom) return
  pieChart = echarts.init(dom)
  const total = pieData.value.reduce((s, d) => s + d.value, 0)
  pieChart.setOption({
    tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
    legend: { show: false },
    graphic: [{
      type: 'text',
      left: 'center',
      top: '38%',
      style: { text: '管网状态', fill: '#a0cfff', fontSize: 12, textAlign: 'center' }
    }, {
      type: 'text',
      left: 'center',
      top: '52%',
      style: { text: String(total), fill: '#fff', fontSize: 22, fontWeight: 'bold', textAlign: 'center' }
    }],
    series: [{
      type: 'pie',
      radius: ['45%', '70%'],
      center: ['50%', '50%'],
      label: { show: false },
      labelLine: { show: false },
      data: pieData.value.map(d => ({ name: d.name, value: d.value, itemStyle: { color: d.color } })),
      emphasis: { scale: true, scaleSize: 5 }
    }]
  })
}

// ==================== 监测曲线（/page 分页接口，按 startTime/endTime 查询）====================
const curveChartData = ref({ labels: [], flowData: [], levelData: [] })

// 时间格式化工具：yyyy-MM-dd HH:mm:ss
function fmtDateTime(d) {
  const pad = n => String(n).padStart(2, '0')
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
}

async function loadCurveHistory() {
  const code = selectedCurveDevice.value
  if (!code) {
    curveChartData.value = { labels: [], flowData: [], levelData: [] }
    return
  }

  // 根据 activeCurveTab 计算时间范围
  const now = new Date()
  const start = new Date()
  const tab = activeCurveTab.value
  if (tab === '24h') start.setHours(start.getHours() - 24)
  else if (tab === '7d') start.setDate(start.getDate() - 7)
  else if (tab === '15d') start.setDate(start.getDate() - 15)
  else start.setDate(start.getDate() - 30)

  const startTime = fmtDateTime(start)
  const endTime = fmtDateTime(now)

  try {
    const res = await getRadarDataHistory(code, startTime, endTime)
    console.log('[gwyxqk] 曲线历史数据原始响应：', res)
    const pageData = res.code !== undefined ? res.data : res
    const records = pageData.records || pageData.rows || (Array.isArray(pageData) ? pageData : [])
    console.log('[gwyxqk] 曲线历史数据：', code, startTime, '~', endTime, records.length, '条')

    const labels = []
    const flowData = []
    const levelData = []

    records.forEach(r => {
      const t = r.createTime || r.create_time || ''
      // 24h 显示 HH:mm，其他显示 MM-dd
      if (tab === '24h') {
        labels.push(t.substring(11, 16))
      } else {
        labels.push(t.substring(5, 10))
      }
      // 兼容驼峰和下划线字段命名
      const instantFlow = r.meter1InstantFlow ?? r.meter1_instant_flow
      const waterLevel = r.waterLevel ?? r.water_level
      flowData.push(instantFlow != null ? Number(instantFlow) : 0)
      levelData.push(waterLevel != null ? Number(waterLevel) : 0)
    })

    // 如果数据为空，显示空图表提示
    if (labels.length === 0) {
      labels.push('暂无数据')
      flowData.push(0)
      levelData.push(0)
    }

    curveChartData.value = { labels, flowData, levelData }
  } catch (err) {
    console.warn('[gwyxqk] 曲线历史数据加载失败：', err)
    curveChartData.value = { labels: [], flowData: [], levelData: [] }
  }
}

function onCurveDeviceChange() {
  console.log('[gwyxqk] 切换曲线设备：', selectedCurveDevice.value)
  loadCurveHistory().then(() => {
    initLineChart()
  })
}

function initLineChart(tab, labels, flowData, levelData) {
  const dom = document.getElementById('gwyxqkLineChart')
  if (!dom) return
  if (!lineChart) {
    lineChart = echarts.init(dom)
  }
  const currentTab = tab || activeCurveTab.value
  // 优先使用外部传入数据，否则从 curveChartData 取
  const chartLabels = labels || curveChartData.value.labels
  const chartFlow = flowData || curveChartData.value.flowData
  const chartLevel = levelData || curveChartData.value.levelData
  lineChart.setOption({
    tooltip: { trigger: 'axis' },
    legend: {
      data: ['流量(m³/h)', '液位(m)'],
      textStyle: { color: '#7ec8e3', fontSize: 10 },
      top: 0,
      right: 10,
      itemWidth: 12,
      itemHeight: 8
    },
    grid: { left: 40, right: 40, top: 30, bottom: 25 },
    xAxis: {
      type: 'category',
      data: chartLabels,
      axisLabel: { color: '#7ec8e3', fontSize: 9, interval: currentTab === '30d' ? 4 : currentTab === '15d' ? 2 : 'auto' },
      axisLine: { lineStyle: { color: '#1a3a5c' } }
    },
    yAxis: [
      {
        type: 'value',
        name: 'm³/h',
        nameTextStyle: { color: '#7ec8e3', fontSize: 10 },
        axisLabel: { color: '#7ec8e3', fontSize: 10 },
        splitLine: { lineStyle: { color: '#1a3a5c' } },
        axisLine: { show: false }
      },
      {
        type: 'value',
        name: 'm',
        nameTextStyle: { color: '#e6a23c', fontSize: 10 },
        axisLabel: { color: '#e6a23c', fontSize: 10 },
        splitLine: { show: false },
        axisLine: { show: false }
      }
    ],
    series: [
      {
        name: '流量(m³/h)',
        type: 'line',
        data: chartFlow,
        smooth: true,
        symbol: 'none',
        lineStyle: { color: '#409eff', width: 2 },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(64,158,255,0.3)' },
            { offset: 1, color: 'rgba(64,158,255,0.02)' }
          ])
        }
      },
      {
        name: '液位(m)',
        type: 'line',
        yAxisIndex: 1,
        data: chartLevel,
        smooth: true,
        symbol: 'none',
        lineStyle: { color: '#e6a23c', width: 2 },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(230,162,60,0.3)' },
            { offset: 1, color: 'rgba(230,162,60,0.02)' }
          ])
        }
      }
    ]
  })
}

// ==================== 流量统计（各设备最新流量柱状图，/latest 返回单条对象）====================
async function initBarChart() {
  const dom = document.getElementById('gwyxqkBarChart')
  if (!dom) return
  if (!barChart) {
    barChart = echarts.init(dom)
  }

  const devices = linkedDeviceList.value
  if (devices.length === 0) {
    barChart.setOption({
      xAxis: { type: 'category', data: [] },
      yAxis: { type: 'value' },
      series: [{ type: 'bar', data: [] }]
    })
    return
  }

  const names = []
  const values = []
  for (const d of devices) {
    names.push(d.equipmentName || d.equipmentCode)
    let flowVal = 0
    if (d.equipmentCode) {
      try {
        const radarRes = await getRadarDataByCode(d.equipmentCode)
        console.log('[gwyxqk] 柱状图设备', d.equipmentCode, '/latest 响应：', radarRes)
        // /latest 直接返回单条对象
        const latest = radarRes.code !== undefined ? radarRes.data : radarRes
        if (latest) {
          const instantFlow = latest.meter1InstantFlow ?? latest.meter1_instant_flow
          const flowSpeed = latest.flowSpeed ?? latest.flow_speed
          flowVal = instantFlow != null ? Number(instantFlow) :
                    flowSpeed != null ? Number(flowSpeed) : 0
        }
      } catch (err) {
        console.warn('[gwyxqk] 柱状图设备', d.equipmentCode, '数据加载失败：', err)
      }
    }
    values.push(Math.round(flowVal * 10) / 10)
  }

  console.log('[gwyxqk] 流量统计柱状图数据：', names.length, '个设备')
  barChart.setOption({
    tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
    grid: { left: 50, right: 10, top: 10, bottom: 30 },
    xAxis: {
      type: 'category',
      data: names,
      axisLabel: { color: '#7ec8e3', fontSize: 9, rotate: 20 },
      axisLine: { lineStyle: { color: '#1a3a5c' } }
    },
    yAxis: {
      type: 'value',
      name: 'm³/h',
      nameTextStyle: { color: '#7ec8e3', fontSize: 10 },
      axisLabel: { color: '#7ec8e3', fontSize: 10 },
      splitLine: { lineStyle: { color: '#1a3a5c' } },
      axisLine: { show: false }
    },
    series: [{
      type: 'bar',
      data: values,
      barWidth: 14,
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#409eff' },
          { offset: 1, color: '#1a3a5c' }
        ]),
        borderRadius: [2, 2, 0, 0]
      }
    }]
  })
}

// ==================== 监测曲线Tab切换 ====================
watch(activeCurveTab, (val) => {
  console.log('[gwyxqk] 切换曲线Tab：', val)
  if (selectedCurveDevice.value) {
    loadCurveHistory().then(() => {
      initLineChart(val)
    })
  } else {
    initLineChart(val)
  }
})

// ==================== 生命周期 ====================
onMounted(async () => {
  updateTime()
  timer = setInterval(() => {
    updateTime()
    updateRefreshTime()
  }, 1000)
  updateRefreshTime()

  // 先从API加载数据
  await loadMapData()

  // 延迟初始化确保 DOM 渲染完成
  setTimeout(() => {
    initMap()
    initPieChart()
    // 加载默认设备的曲线历史数据
    if (selectedCurveDevice.value) {
      loadCurveHistory().then(() => {
        initLineChart()
      })
    } else {
      initLineChart()
    }
    initBarChart()
  }, 300)
})

onUnmounted(() => {
  if (timer) clearInterval(timer)
  if (pieChart) pieChart.dispose()
  if (lineChart) lineChart.dispose()
  if (barChart) barChart.dispose()
  if (mapInstance) mapInstance = null
})

// 监听窗口大小变化，重绘图表
window.addEventListener('resize', () => {
  if (pieChart) pieChart.resize()
  if (lineChart) lineChart.resize()
  if (barChart) barChart.resize()
})
</script>

<style scoped>
/* ==================== 全局暗色大屏 ==================== */
.gwyxqk-screen {
  width: 100%;
  height: 100vh;
  background: #0a1929;
  color: #fff;
  font-family: 'Microsoft YaHei', sans-serif;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* ==================== 顶部标题栏 ==================== */
.screen-header {
  height: 64px;
  background: linear-gradient(180deg, #0d2137 0%, #0a1929 100%);
  border-bottom: 1px solid rgba(64, 158, 255, 0.3);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  flex-shrink: 0;
  position: relative;
}

.screen-header::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 10%;
  right: 10%;
  height: 1px;
  background: linear-gradient(90deg, transparent, #409eff, transparent);
}

.header-left {
  flex: 1;
  text-align: left;
}

.header-time {
  font-size: 15px;
  color: #a0cfff;
  letter-spacing: 1px;
}

.header-center {
  flex: 2;
  text-align: center;
}

.header-title {
  font-size: 26px;
  font-weight: 700;
  margin: 0;
  letter-spacing: 4px;
  background: linear-gradient(180deg, #fff 0%, #7ec8e3 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  text-shadow: none;
}

.header-right {
  flex: 1;
  text-align: right;
}

/* ==================== 主体三栏 ==================== */
.screen-body {
  flex: 1;
  display: flex;
  padding: 12px;
  gap: 12px;
  min-height: 0;
}

.panel-left,
.panel-right {
  width: 22%;
  min-width: 260px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
}

.panel-center {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  position: relative;
}

/* ==================== 面板盒子 ==================== */
.panel-box {
  background: rgba(6, 30, 65, 0.8);
  border: 1px solid rgba(64, 158, 255, 0.2);
  border-radius: 6px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.panel-title {
  font-size: 14px;
  font-weight: 600;
  color: #7ec8e3;
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

.title-icon {
  color: #409eff;
  font-size: 10px;
}

.refresh-time {
  margin-left: auto;
  font-size: 11px;
  color: #607080;
  font-weight: 400;
}

/* ==================== 管网概况统计卡片 ==================== */
.stats-cards {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
  flex-shrink: 0;
}

.stat-card {
  flex: 1;
  background: rgba(10, 25, 50, 0.6);
  border: 1px solid rgba(64, 158, 255, 0.15);
  border-radius: 6px;
  padding: 8px 4px;
  text-align: center;
}

.stat-val {
  font-size: 20px;
  font-weight: 700;
  color: #409eff;
}

.stat-val.green {
  color: #67c23a;
}

.stat-val.orange {
  color: #e6a23c;
}

.stat-val.gray {
  color: #909399;
}

.stat-label {
  font-size: 10px;
  color: #7ec8e3;
  margin-top: 2px;
}

/* ==================== 环形图 ==================== */
.pie-chart-wrapper {
  display: flex;
  align-items: center;
  height: 140px;
}

.chart-area {
  width: 55%;
  height: 140px;
}

.pie-legend {
  width: 45%;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
}

.legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex-shrink: 0;
}

.legend-label {
  color: #a0cfff;
  flex: 1;
}

.legend-value {
  color: #fff;
  font-weight: 600;
}

/* ==================== 实时数据表格 ==================== */
.realtime-table-wrap {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

.dark-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}

.dark-table th {
  background: rgba(20, 60, 110, 0.6);
  color: #7ec8e3;
  padding: 7px 6px;
  text-align: center;
  border-bottom: 1px solid rgba(64, 158, 255, 0.2);
  font-weight: 500;
  white-space: nowrap;
}

.dark-table td {
  padding: 6px;
  text-align: center;
  color: #d0e8ff;
  border-bottom: 1px solid rgba(64, 158, 255, 0.08);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 80px;
}

.dark-table tbody tr:nth-child(odd) {
  background: rgba(10, 25, 50, 0.4);
}

.dark-table tbody tr:nth-child(even) {
  background: rgba(20, 40, 70, 0.3);
}

.dark-table tbody tr:hover {
  background: rgba(64, 158, 255, 0.1);
}

.status-tag {
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 11px;
}

.status-normal {
  color: #67c23a;
  background: rgba(103, 194, 58, 0.15);
}

.status-warning {
  color: #e6a23c;
  background: rgba(230, 162, 60, 0.15);
}

.status-alarm {
  color: #f56c6c;
  background: rgba(245, 108, 108, 0.15);
}

.status-offline {
  color: #909399;
  background: rgba(144, 147, 153, 0.15);
}

/* ==================== 中间地图 ==================== */
.map-container {
  flex: 1;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid rgba(64, 158, 255, 0.2);
  min-height: 0;
}

.map-search {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 10;
  display: flex;
  align-items: center;
}

.search-input {
  background: rgba(6, 30, 65, 0.85);
  border: 1px solid rgba(64, 158, 255, 0.3);
  color: #a0cfff;
  padding: 6px 30px 6px 12px;
  border-radius: 4px;
  font-size: 12px;
  outline: none;
  width: 160px;
}

.search-input::placeholder {
  color: #4a6a8a;
}

.search-icon {
  position: absolute;
  right: 8px;
  font-size: 14px;
  cursor: pointer;
}

/* ==================== 监测曲线Tab ==================== */
.curve-tabs {
  display: flex;
  gap: 0;
  background: rgba(10, 25, 50, 0.6);
  border: 1px solid rgba(64, 158, 255, 0.2);
  border-radius: 4px;
  margin-bottom: 8px;
  flex-shrink: 0;
  overflow: hidden;
}

.curve-tab {
  flex: 1;
  text-align: center;
  padding: 5px 4px;
  font-size: 11px;
  color: #a0cfff;
  cursor: pointer;
  transition: all 0.3s;
  border-right: 1px solid rgba(64, 158, 255, 0.1);
}

.curve-tab:last-child {
  border-right: none;
}

.curve-tab.active {
  background: rgba(64, 158, 255, 0.25);
  color: #fff;
  font-weight: 600;
}

.curve-tab:hover {
  background: rgba(64, 158, 255, 0.15);
}

.device-select {
  margin-left: 10px;
  background: #0d2137;
  color: #7ec8e3;
  border: 1px solid #1a3a5c;
  border-radius: 3px;
  padding: 2px 6px;
  font-size: 11px;
  outline: none;
}

.chart-area-sm {
  width: 100%;
  height: 150px;
  flex-shrink: 0;
}

/* ==================== 报警信息 ==================== */
.alert-stats {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
  flex-shrink: 0;
}

.alert-stat-card {
  flex: 1;
  background: rgba(10, 25, 50, 0.6);
  border: 1px solid rgba(64, 158, 255, 0.15);
  border-radius: 6px;
  padding: 8px;
  text-align: center;
}

.alert-stat-val {
  font-size: 20px;
  font-weight: 700;
  color: #e6a23c;
}

.alert-stat-val.green {
  color: #67c23a;
}

.alert-stat-val.red {
  color: #f56c6c;
}

.alert-stat-label {
  font-size: 10px;
  color: #7ec8e3;
  margin-top: 2px;
}

.alert-table-wrap {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

/* ==================== 滚动条样式 ==================== */
::-webkit-scrollbar {
  width: 4px;
}

::-webkit-scrollbar-track {
  background: rgba(10, 25, 50, 0.3);
}

::-webkit-scrollbar-thumb {
  background: rgba(64, 158, 255, 0.3);
  border-radius: 2px;
}

::-webkit-scrollbar-thumb:hover {
  background: rgba(64, 158, 255, 0.5);
}
</style>
