<!--故障管理-->
<template>
  <div class="device-maintenance">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-left">
        <el-icon><Monitor /></el-icon>
        <span class="title">智能终端设备运维中心</span>
        <el-tag type="danger" effect="dark">故障设备 {{ faultCount }}</el-tag>
      </div>
      <div class="header-right">
        <el-input
            v-model="searchKeyword"
            placeholder="搜索设备编号/名称/位置"
            clearable
            :prefix-icon="Search"
            style="width: 260px"
        />
        <el-select v-model="faultTypeFilter" placeholder="故障类型" clearable style="width: 140px">
          <el-option label="倾斜超标" value="tilt" />
          <el-option label="水位超限" value="waterLevel" />
          <el-option label="水浸报警" value="waterInfiltration" />
          <el-option label="通讯故障" value="offline" />
          <el-option label="电池低电量" value="battery" />
          <el-option label="信号弱" value="signal" />
        </el-select>
        <el-button type="primary" :icon="Refresh" @click="refreshData" :loading="loading">刷新</el-button>
      </div>
    </div>

    <!-- 统计卡片 -->
    <div class="stats-cards">
      <div class="stat-card critical">
        <div class="stat-value">{{ criticalFaultCount }}</div>
        <div class="stat-label">严重故障</div>
      </div>
      <div class="stat-card warning">
        <div class="stat-value">{{ normalFaultCount }}</div>
        <div class="stat-label">一般故障</div>
      </div>
      <div class="stat-card">
        <div class="stat-value">{{ processingCount }}</div>
        <div class="stat-label">处置中</div>
      </div>
      <div class="stat-card">
        <div class="stat-value">{{ completedCount }}</div>
        <div class="stat-label">正常设备</div>
      </div>
    </div>

    <!-- 主内容区：左侧地图 + 右侧列表 -->
    <div class="main-layout">
      <!-- 左侧GIS地图终端分布 -->
      <div class="map-panel">
        <div class="map-header">
          <span><el-icon><MapLocation /></el-icon> 终端分布地图</span>
          <div class="map-legend">
            <span><i class="legend-dot critical-dot"></i>严重故障</span>
            <span><i class="legend-dot warning-dot"></i>一般故障</span>
            <span><i class="legend-dot normal-dot"></i>正常</span>
            <span><i class="legend-dot processing-dot"></i>处置中</span>
          </div>
        </div>
        <div class="map-container" v-loading="loading">
          <div id="faultManaMap" class="bmap-container"></div>
        </div>
      </div>

      <!-- 右侧设备列表 -->
      <div class="device-list-panel">
        <div class="list-header">
          <span>故障设备列表</span>
          <el-radio-group v-model="listFilter" size="small">
            <el-radio-button label="all">全部故障</el-radio-button>
            <el-radio-button label="pending">待处置</el-radio-button>
            <el-radio-button label="processing">处置中</el-radio-button>
          </el-radio-group>
        </div>
        <div class="device-list">
          <div
              v-for="device in paginatedDevices"
              :key="device.id"
              class="device-item"
              :class="{
              selected: selectedDevice?.id === device.id,
              critical: device.isCritical,
              warning: !device.isCritical
            }"
              @click="selectDevice(device)"
          >
            <div class="device-header">
              <span class="device-code">{{ device.code }}</span>
              <el-tag :type="device.isCritical ? 'danger' : 'warning'" size="small">
                {{ device.isCritical ? '严重' : '一般' }}
              </el-tag>
            </div>
            <div class="device-location">
              <el-icon><Location /></el-icon> {{ device.locationShort }}
            </div>
            <div class="device-fault">{{ device.faultTypeName }}</div>
            <div class="device-status">
              <el-tag :type="getStatusTag(device)" size="small">{{ getStatusText(device) }}</el-tag>
            </div>
          </div>
          <el-empty v-if="!paginatedDevices.length && !loading" description="暂无故障设备" :image-size="80" />
        </div>
        <div class="pagination-area">
          <el-pagination
              small
              layout="prev, pager, next"
              :total="filteredDevices.length"
              :page-size="pageSize"
              v-model:current-page="currentPage"
          />
        </div>
      </div>
    </div>

    <!-- 设备详情与处置抽屉 -->
    <el-drawer v-model="detailDrawerVisible" :title="`设备运维 - ${selectedDevice?.code}`" size="500px" direction="rtl">
      <div v-if="selectedDevice" class="device-detail">
        <!-- 设备基本信息 -->
        <el-descriptions :column="1" border>
          <el-descriptions-item label="设备编号">{{ selectedDevice.code }}</el-descriptions-item>
          <el-descriptions-item label="设备名称">{{ selectedDevice.name }}</el-descriptions-item>
          <el-descriptions-item label="设备类型">{{ selectedDevice.deviceTypeName }}</el-descriptions-item>
          <el-descriptions-item label="所属片区">{{ selectedDevice.district || '—' }}</el-descriptions-item>
          <el-descriptions-item label="详细地址">{{ selectedDevice.location }}</el-descriptions-item>
          <el-descriptions-item label="经纬度">{{ selectedDevice.lng ?? '—' }}, {{ selectedDevice.lat ?? '—' }}</el-descriptions-item>
          <el-descriptions-item label="故障类型">{{ selectedDevice.faultTypeName }}</el-descriptions-item>
          <el-descriptions-item label="故障描述">{{ selectedDevice.faultDesc }}</el-descriptions-item>
          <el-descriptions-item label="故障时间">{{ selectedDevice.abnormalTime || '—' }}</el-descriptions-item>
          <el-descriptions-item label="当前状态">
            <el-tag :type="getStatusTag(selectedDevice)">{{ getStatusText(selectedDevice) }}</el-tag>
          </el-descriptions-item>
        </el-descriptions>

        <!-- 处置操作区 -->
        <div class="operation-section" v-if="!selectedDevice.scrapped">
          <div class="section-title">
            <span><el-icon><Tools /></el-icon> 现场处置操作</span>
          </div>

          <!-- 处置操作按钮组：上报工单 + 报废 -->
          <div class="operation-buttons">
            <el-button type="primary" @click="openWorkOrderDialog" :disabled="selectedDevice.workOrderSubmitted">上报工单</el-button>
            <el-button type="danger" @click="openScrapDialog">报废</el-button>
          </div>
          <div v-if="selectedDevice.workOrderSubmitted" class="order-hint">该设备已有未办结工单，无需重复上报</div>
        </div>

        <!-- 已报废状态展示 -->
        <div class="completed-section" v-else>
          <el-alert title="设备已报废" type="danger" :closable="false" show-icon>
            <div>报废时间: {{ selectedDevice.scrapTime || '—' }}</div>
            <div>报废说明: {{ selectedDevice.scrapRemark || '—' }}</div>
          </el-alert>
        </div>

        <!-- 历史处置记录（工单处理记录） -->
        <div class="history-section">
          <div class="section-title"><el-icon><Document /></el-icon> 历史处置记录（工单）</div>
          <el-timeline v-loading="orderLoading">
            <el-timeline-item
                v-for="record in orderRecords"
                :key="record.orderId"
                :timestamp="record.createTime"
                :type="getOrderTimelineType(record.orderStatus)"
            >
              <div class="order-record">
                <div class="order-record-header">
                  <span class="order-no">{{ record.orderNo }}</span>
                  <el-tag :type="getOrderStatusTag(record.orderStatus)" size="small">{{ getOrderStatusText(record.orderStatus) }}</el-tag>
                </div>
                <div class="order-record-desc">{{ record.orderDesc || '—' }}</div>
              </div>
            </el-timeline-item>
            <el-timeline-item v-if="!orderRecords.length && !orderLoading" timestamp="暂无记录" type="info">
              该设备尚无工单处置记录
            </el-timeline-item>
          </el-timeline>
        </div>
      </div>
    </el-drawer>

    <!-- 上报工单对话框 -->
    <el-dialog v-model="workOrderDialogVisible" title="上报工单" width="460px">
      <el-form label-width="90px">
        <el-form-item label="工单类型">
          <el-select v-model="workOrderForm.orderType" style="width: 100%">
            <el-option label="故障维修" :value="1" />
            <el-option label="日常巡检" :value="2" />
            <el-option label="设备保养" :value="3" />
          </el-select>
        </el-form-item>
        <el-form-item label="工单优先级">
          <el-select v-model="workOrderForm.orderLevel" style="width: 100%">
            <el-option label="紧急" :value="1" />
            <el-option label="一般" :value="2" />
            <el-option label="低" :value="3" />
          </el-select>
        </el-form-item>
        <el-form-item label="问题描述">
          <el-input type="textarea" v-model="workOrderForm.orderDesc" :placeholder="workOrderPlaceholder" rows="3" />
        </el-form-item>
        <el-form-item label="定位信息">
          <div class="location-confirm">
            <el-icon><Location /></el-icon>
            {{ selectedDevice?.location }}
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="workOrderDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="submitting" @click="submitWorkOrder">确认上报</el-button>
      </template>
    </el-dialog>

    <!-- 报废确认对话框 -->
    <el-dialog v-model="scrapDialogVisible" title="报废处理" width="420px">
      <el-form>
        <el-form-item label="报废原因">
          <el-input type="textarea" v-model="scrapRemark" placeholder="请填写报废原因" rows="3" />
        </el-form-item>
        <el-form-item label="设备确认">
          <div class="location-confirm">
            <el-icon><Warning /></el-icon>
            {{ selectedDevice?.code }} - {{ selectedDevice?.name }}（报废后设备将停用）
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="scrapDialogVisible = false">取消</el-button>
        <el-button type="danger" :loading="submitting" @click="confirmScrap">确认报废</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { Monitor, Search, Refresh, MapLocation, Location, Tools, Document, Warning } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { getManholeAlarmMonitorList, addManholeWorkOrder, getManholeWorkOrderPage, updateManholeDeviceStatus } from '@/api/pipeNetwork/basic'
import locationIcon from '@/assets/images/location.png'

// ==================== 常量 ====================
const TYPE_MAP = { '5': '供水窨井', '9': '排水窨井', '10': '燃气窨井' }
const LOW_BATTERY_THRESHOLD = 15
const LOW_SIGNAL_THRESHOLD = 20
const ORDER_STATUS_MAP = { 1: '待派单', 2: '待接单', 3: '已接单', 4: '处理中', 5: '待验收', 6: '已结案', 7: '已驳回', 8: '延期审核', 9: '已延期' }

// ==================== 状态 ====================
const loading = ref(false)
const allDevices = ref([])

// 筛选条件
const searchKeyword = ref('')
const faultTypeFilter = ref('')
const listFilter = ref('all')
const currentPage = ref(1)
const pageSize = 6

// 选择与详情
const selectedDevice = ref(null)
const detailDrawerVisible = ref(false)
const orderRecords = ref([])
const orderLoading = ref(false)

// 上报工单
const workOrderDialogVisible = ref(false)
const workOrderForm = ref({ orderType: 1, orderLevel: 2, orderDesc: '' })
const submitting = ref(false)

// 报废
const scrapDialogVisible = ref(false)
const scrapRemark = ref('')

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

// ==================== 设备数据规范化 ====================
function normalizeDevice(raw) {
  const md = raw?.manholeData || {}
  const st = raw?.equipmentStatus || {}
  const typeId = raw?.equipmentTypeId || ''

  const tiltAngle = parseFloat(md.tiltAngle) || 0
  const angleThreshold = parseFloat(md.angleAlarmThreshold) || 15
  const battery = parseFloat(md.batteryLevel) || 0
  const signal = parseFloat(md.signalStrength) || 0
  const isOnline = Number(st.onlineStatus) === 1
  const scrapped = Number(st.currentStatus) === 4

  // 异常判定
  const tilt = isOnline && tiltAngle > angleThreshold
  const waterInfiltration = isOnline && `${md.waterInfiltrationAlarmStatus}` === '1'
  const waterLevel = isOnline && `${md.waterLevelAlarmStatus}` === '1'
  const lowBattery = battery > 0 && battery <= LOW_BATTERY_THRESHOLD
  const lowSignal = signal > 0 && signal <= LOW_SIGNAL_THRESHOLD
  const offline = !isOnline

  // 故障类型列表
  const faultTypes = []
  if (tilt) faultTypes.push({ type: 'tilt', name: '倾斜超标' })
  if (waterLevel) faultTypes.push({ type: 'waterLevel', name: '水位超限' })
  if (waterInfiltration) faultTypes.push({ type: 'waterInfiltration', name: '水浸报警' })
  if (offline) faultTypes.push({ type: 'offline', name: '通讯故障' })
  if (lowBattery) faultTypes.push({ type: 'battery', name: '电池低电量' })
  if (lowSignal) faultTypes.push({ type: 'signal', name: '信号弱' })

  const hasAlert = faultTypes.length > 0 && !scrapped
  const isCritical = tilt || waterInfiltration || waterLevel

  // 故障描述
  const parts = []
  if (tilt) parts.push(`倾斜角度${tiltAngle}°超过阈值${angleThreshold}°`)
  if (waterInfiltration) parts.push('水浸报警')
  if (waterLevel) parts.push('水位超标报警')
  if (lowBattery) parts.push(`电量仅剩${battery}%`)
  if (lowSignal) parts.push(`信号强度${signal}%`)
  if (offline) parts.push('设备离线')

  let elapsedHours = 0
  const faultTime = md.uploadTime || md.createTime
  if (faultTime) {
    const diff = Date.now() - new Date(faultTime).getTime()
    elapsedHours = Math.max(0, Math.round(diff / (1000 * 60 * 60) * 10) / 10)
  }

  return {
    id: raw?.equipmentId || raw?.equipmentCode || '',
    code: raw?.equipmentCode || raw?.equipmentId || '',
    equipmentId: raw?.equipmentId || '',
    name: raw?.equipmentName || raw?.equipmentCode || '未命名设备',
    deviceTypeName: TYPE_MAP[typeId] || raw?.equipmentTypeName || '未知类型',
    district: raw?.district || '',
    location: raw?.equipmentLocation || '暂无位置信息',
    locationShort: (raw?.equipmentLocation || '暂无位置').slice(0, 20),
    lng: raw?.longitude != null ? Number(raw.longitude) : null,
    lat: raw?.latitude != null ? Number(raw.latitude) : null,
    battery, signal, tiltAngle, angleThreshold,
    status: { tilt, waterInfiltration, waterLevel, lowBattery, lowSignal, offline },
    faultTypes, hasAlert, isCritical, scrapped,
    faultTypeName: faultTypes.map(f => f.name).join('、') || '正常',
    faultDesc: parts.join('；') || '设备状态正常',
    abnormalTime: faultTime || '',
    elapsedHours,
    workOrderSubmitted: !!raw?.workOrderSubmitted,
    statusText: scrapped ? '已报废' : (raw?.workOrderSubmitted ? '处置中' : '待处置')
  }
}

// ==================== 数据加载 ====================
async function loadData() {
  loading.value = true
  try {
    const { data } = await getManholeAlarmMonitorList({})
    const devices = (data?.devices || []).map(normalizeDevice)
    allDevices.value = devices
    await nextTick()
    refreshMarkers()
  } catch (error) {
    ElMessage.error('设备数据加载失败: ' + (error?.message || error?.msg || '未知错误'))
  } finally {
    loading.value = false
  }
}

const refreshData = () => { loadData() }

// ==================== 计算属性 ====================
const faultDevices = computed(() => allDevices.value.filter(d => d.hasAlert))
const filteredDevices = computed(() => {
  let list = faultDevices.value
  if (listFilter.value === 'pending') list = list.filter(d => !d.workOrderSubmitted)
  else if (listFilter.value === 'processing') list = list.filter(d => d.workOrderSubmitted)

  if (searchKeyword.value) {
    const kw = searchKeyword.value.toLowerCase()
    list = list.filter(d =>
        d.code.toLowerCase().includes(kw) ||
        d.name.toLowerCase().includes(kw) ||
        d.location.toLowerCase().includes(kw)
    )
  }
  if (faultTypeFilter.value) {
    list = list.filter(d => d.faultTypes.some(f => f.type === faultTypeFilter.value))
  }
  return list
})

const paginatedDevices = computed(() => {
  const start = (currentPage.value - 1) * pageSize
  return filteredDevices.value.slice(start, start + pageSize)
})

const faultCount = computed(() => faultDevices.value.length)
const criticalFaultCount = computed(() => faultDevices.value.filter(d => d.isCritical).length)
const normalFaultCount = computed(() => faultDevices.value.filter(d => !d.isCritical).length)
const processingCount = computed(() => faultDevices.value.filter(d => d.workOrderSubmitted).length)
const completedCount = computed(() => allDevices.value.length - faultDevices.value.length)

const workOrderPlaceholder = computed(() => {
  const descMap = { 1: '请填写故障现象、发生时间等信息', 2: '请填写巡检内容与发现问题', 3: '请填写保养内容与周期' }
  return descMap[workOrderForm.value.orderType] || '请填写工单描述'
})

// ==================== 状态展示 ====================
const getStatusTag = (device) => {
  if (device.scrapped) return 'danger'
  if (device.workOrderSubmitted) return 'warning'
  return 'danger'
}
const getStatusText = (device) => {
  if (device.scrapped) return '已报废'
  if (device.workOrderSubmitted) return '处置中'
  return '待处置'
}

const getOrderStatusTag = (status) => {
  const map = { 1: 'danger', 2: 'warning', 3: 'warning', 4: 'primary', 5: 'primary', 6: 'success', 7: 'info', 8: 'warning', 9: 'danger' }
  return map[status] || 'info'
}
const getOrderStatusText = (status) => ORDER_STATUS_MAP[status] || '未知'
const getOrderTimelineType = (status) => {
  if (Number(status) === 6) return 'success'
  if (Number(status) === 7 || Number(status) === 9) return 'danger'
  return 'primary'
}

// ==================== 选择设备 ====================
const selectDevice = async (device) => {
  selectedDevice.value = device
  detailDrawerVisible.value = true
  highlightMarker(device.id)
  if (mapInstance && device.lng != null && device.lat != null) {
    mapInstance.centerAndZoom(new BMapGL.Point(device.lng, device.lat), 15)
  }
  await loadOrderRecords(device)
}

// ==================== 历史处置记录（工单处理记录） ====================
async function loadOrderRecords(device) {
  orderLoading.value = true
  orderRecords.value = []
  try {
    const { data } = await getManholeWorkOrderPage({ deviceId: device.equipmentId, pageNum: 1, pageSize: 20 })
    orderRecords.value = data?.records || data?.rows || []
  } catch (error) {
    ElMessage.error('工单记录加载失败: ' + (error?.message || error?.msg || '未知错误'))
  } finally {
    orderLoading.value = false
  }
}

// ==================== 上报工单 ====================
const openWorkOrderDialog = () => {
  const device = selectedDevice.value
  // 智能推荐工单类型：低电量→设备保养(3)，信号弱→日常巡检(2)，其他→故障维修(1)
  let orderType = 1
  if (device.status.lowBattery) orderType = 3
  else if (device.status.lowSignal) orderType = 2
  workOrderForm.value = {
    orderType,
    orderLevel: device.isCritical ? 1 : 2,
    orderDesc: `【${device.faultTypeName}】${device.faultDesc}`
  }
  workOrderDialogVisible.value = true
}

const submitWorkOrder = async () => {
  if (!workOrderForm.value.orderDesc) {
    ElMessage.warning('请填写问题描述')
    return
  }
  submitting.value = true
  try {
    await addManholeWorkOrder({
      deviceId: selectedDevice.value.equipmentId,
      orderType: workOrderForm.value.orderType,
      orderLevel: workOrderForm.value.orderLevel,
      orderDesc: workOrderForm.value.orderDesc
    })
    ElMessage.success('工单上报成功')
    workOrderDialogVisible.value = false
    selectedDevice.value.workOrderSubmitted = true
    selectedDevice.value.statusText = '处置中'
    await loadOrderRecords(selectedDevice.value)
  } catch (error) {
    ElMessage.error('工单上报失败: ' + (error?.message || error?.msg || '未知错误'))
  } finally {
    submitting.value = false
  }
}

// ==================== 报废处理 ====================
const openScrapDialog = () => {
  scrapRemark.value = ''
  scrapDialogVisible.value = true
}

const confirmScrap = async () => {
  if (!scrapRemark.value) {
    ElMessage.warning('请填写报废原因')
    return
  }
  submitting.value = true
  try {
    // 报废：修改设备状态 currentStatus=4-报废
    await updateManholeDeviceStatus({
      equipmentId: selectedDevice.value.equipmentId,
      currentStatus: 4
    })
    ElMessage.success('设备已报废')
    scrapDialogVisible.value = false
    selectedDevice.value.scrapped = true
    selectedDevice.value.statusText = '已报废'
    selectedDevice.value.scrapRemark = scrapRemark.value
    selectedDevice.value.scrapTime = new Date().toLocaleString()
    // 从故障列表移除并刷新地图
    await nextTick()
    refreshMarkers()
  } catch (error) {
    ElMessage.error('报废操作失败: ' + (error?.message || error?.msg || '未知错误'))
  } finally {
    submitting.value = false
  }
}

// ==================== 百度地图 ====================
function initMap() {
  const container = document.getElementById('faultManaMap')
  if (!container || typeof BMapGL === 'undefined') {
    console.warn('BMapGL 未加载或容器不存在')
    return
  }
  try {
    mapInstance = new BMapGL.Map('faultManaMap')
    mapInstance.centerAndZoom(new BMapGL.Point(YUANLING_CENTER.lng, YUANLING_CENTER.lat), 13)
    mapInstance.enableScrollWheelZoom(true)
  } catch (e) {
    console.error('百度地图初始化失败：', e)
  }
}

function getMarkerColor(device) {
  if (device.scrapped) return '#909399'
  if (device.workOrderSubmitted) return '#409EFF'
  if (device.hasAlert) return device.isCritical ? '#F56C6C' : '#E6A23C'
  return '#67C23A'
}

function addMapMarker(device) {
  if (!mapInstance || device.lng == null || device.lat == null) return
  const color = getMarkerColor(device)
  const bPoint = new BMapGL.Point(device.lng, device.lat)
  const html = `<div style="text-align:center;cursor:pointer;">
    <div style="color:#fff;background:${color};border-radius:4px;padding:2px 8px;font-size:11px;white-space:nowrap;display:inline-block;margin-bottom:2px;box-shadow:0 1px 4px rgba(0,0,0,0.3);">
      ${device.name}
    </div>
    <div><img src="${locationIcon}" style="width:26px;height:26px;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', zIndex: '10' })
  label.addEventListener('click', () => selectDevice(device))
  mapInstance.addOverlay(label)
  markerMap.set(device.id, label)
}

function refreshMarkers() {
  if (!mapInstance) return
  markerMap.forEach(label => mapInstance.removeOverlay(label))
  markerMap.clear()
  allDevices.value.forEach(device => addMapMarker(device))
}

function highlightMarker(id) {
  markerMap.forEach((label, key) => {
    const dom = label.getContentContainer ? label.getContentContainer() : null
    if (!dom) return
    const isSelected = key === id
    dom.style.zIndex = isSelected ? '999' : '10'
    const title = dom.querySelector('div')
    if (title) title.style.outline = isSelected ? '2px solid #409EFF' : 'none'
  })
}

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

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

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

<style scoped>
.device-maintenance {
  background: #f0f2f6;
  min-height: 100vh;
  padding: 14px 20px 20px;
  box-sizing: border-box;
}

.page-header {
  background: white;
  border-radius: 12px;
  padding: 12px 20px;
  margin-bottom: 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

.header-left { display: flex; align-items: center; gap: 12px; }
.header-left .title { font-size: 20px; font-weight: 600; }
.header-right { display: flex; gap: 12px; flex-wrap: wrap; }

.stats-cards {
  display: flex;
  gap: 14px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}

.stat-card {
  background: white;
  border-radius: 12px;
  padding: 10px 22px;
  text-align: center;
  min-width: 108px;
  flex: 1;
  max-width: 220px;
}
.stat-card.critical .stat-value { color: #f56c6c; }
.stat-card.warning .stat-value { color: #e6a23c; }
.stat-value { font-size: 24px; font-weight: bold; line-height: 1.3; }
.stat-label { font-size: 13px; color: #606266; margin-top: 2px; }

.main-layout {
  display: flex;
  gap: 14px;
  height: calc(100vh - 236px);
  min-height: 520px;
}

.map-panel {
  flex: 1;
  min-width: 0;
  background: white;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.map-header {
  padding: 12px 16px;
  border-bottom: 1px solid #e9ecef;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;
  font-size: 14px;
  flex-shrink: 0;
}

.map-legend { display: flex; gap: 16px; font-size: 12px; }
.legend-dot { display: inline-block; width: 10px; height: 10px; border-radius: 10px; margin-right: 4px; }
.critical-dot { background: #f56c6c; }
.warning-dot { background: #e6a23c; }
.normal-dot { background: #67c23a; }
.processing-dot { background: #409eff; }

.map-container {
  flex: 1;
  position: relative;
  min-height: 0;
}
.bmap-container { width: 100%; height: 100%; }

.device-list-panel {
  width: 360px;
  flex-shrink: 0;
  background: white;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.list-header {
  padding: 12px 16px;
  border-bottom: 1px solid #e9ecef;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;
  font-size: 14px;
  flex-shrink: 0;
}

.device-list {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
  max-height: none;
}

.device-item {
  padding: 10px 12px;
  margin-bottom: 8px;
  border-radius: 10px;
  background: #fafbfc;
  border: 1px solid #e9ecef;
  cursor: pointer;
  transition: all 0.2s;
}

.device-item.selected { background: #ecf5ff; border-color: #409eff; }
.device-item.critical { border-left: 3px solid #f56c6c; }
.device-item.warning { border-left: 3px solid #e6a23c; }

.device-header { display: flex; justify-content: space-between; margin-bottom: 6px; }
.device-code { font-weight: 600; }
.device-location { font-size: 12px; color: #6c757d; display: flex; align-items: center; gap: 4px; margin-bottom: 4px; }
.device-fault { font-size: 12px; color: #f56c6c; margin-bottom: 4px; }

.device-detail { padding: 8px; }
.section-title {
  font-weight: 600;
  font-size: 15px;
  margin: 20px 0 12px 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.operation-buttons { display: flex; gap: 12px; margin: 16px 0; }
.order-hint { font-size: 12px; color: #e6a23c; margin-bottom: 8px; }
.location-confirm { background: #f5f7fa; padding: 8px; border-radius: 8px; display: flex; align-items: center; gap: 8px; }

.order-record { padding: 4px 0; }
.order-record-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; }
.order-no { font-weight: 600; font-size: 13px; }
.order-record-desc { font-size: 12px; color: #606266; }

.pagination-area { padding: 10px; text-align: center; border-top: 1px solid #eee; flex-shrink: 0; }
</style>
