<!-- 感知信息实时展示 -->
<template>
  <div class="app-container realtime-page" v-loading="loading">
    <div class="hero-panel">
      <div>
        <div class="hero-title">感知信息实时展示</div>
        <div class="hero-subtitle">展示传感设备名称、位置、工作状态及故障关注信息，并同步呈现人机交互记录</div>
      </div>
      <el-button type="primary" icon="Refresh" @click="loadDashboard">刷新</el-button>
    </div>

    <div class="summary-grid">
      <el-card shadow="hover" class="summary-card danger">
        <div class="summary-label">报警关注</div>
        <div class="summary-value">{{ alarmCount }}</div>
        <div class="summary-desc">预警、维修、停用等需值班关注的对象</div>
      </el-card>
      <el-card shadow="hover" class="summary-card success">
        <div class="summary-label">正常监测点</div>
        <div class="summary-value">{{ normalCount }}</div>
        <div class="summary-desc">状态为正常或启用的点位</div>
      </el-card>
      <el-card shadow="hover" class="summary-card primary">
        <div class="summary-label">感知设备</div>
        <div class="summary-value">{{ equipmentCount }}</div>
        <div class="summary-desc">通过点位详情聚合出的关联设备总量</div>
      </el-card>
      <el-card shadow="hover" class="summary-card info">
        <div class="summary-label">设施覆盖</div>
        <div class="summary-value">{{ networkOptions.length }}</div>
        <div class="summary-desc">已纳入实时展示的管网设施数量</div>
      </el-card>
    </div>

    <el-row :gutter="16">
      <el-col :xs="24" :lg="16">
        <el-card shadow="never" class="main-card">
          <template #header>
            <div class="card-header-row">
              <div>
                <div class="card-title">设备信息实时展示</div>
                <div class="card-subtitle">以图元卡片方式查看监测点及所挂接感知设备的实时分布</div>
              </div>
              <div class="filter-group">
                <el-select v-model="filters.networkId" clearable placeholder="按设施筛选" style="width: 200px">
                  <el-option
                    v-for="item in networkOptions"
                    :key="item.networkId"
                    :label="item.networkName"
                    :value="item.networkId"
                  />
                </el-select>
                <el-select v-model="filters.status" clearable placeholder="按状态筛选" style="width: 160px">
                  <el-option v-for="item in statusOptions" :key="item" :label="item" :value="item" />
                </el-select>
              </div>
            </div>
          </template>

          <div v-if="displayCards.length" class="device-grid">
            <div
              v-for="card in displayCards"
              :key="card.pointId"
              class="device-card"
              :class="getCardClass(card.status)"
              @click="openDetail(card)"
            >
              <div class="device-top">
                <div class="device-icon" :class="{ pulse: isAlertStatus(card.status) }">
                  {{ getPointEmoji(card.pointType) }}
                </div>
                <div class="device-info">
                  <div class="device-name">{{ card.pointName }}</div>
                  <div class="device-location">{{ card.location || "未维护位置" }}</div>
                  <div class="device-network">{{ card.networkName || "未关联设施" }}</div>
                </div>
              </div>
              <div class="device-status-line">
                <span class="status-dot" :class="getStatusDotClass(card.status)"></span>
                <span>{{ card.status || "状态未维护" }}</span>
                <span class="device-count">设备 {{ card.equipmentCount }}</span>
              </div>
              <div class="device-meta">
                <span>编码：{{ card.pointCode }}</span>
                <span>类型：{{ card.pointType || "-" }}</span>
              </div>
            </div>
          </div>
          <el-empty v-else description="暂无可展示的感知信息" />
        </el-card>
      </el-col>

      <el-col :xs="24" :lg="8">
        <el-card shadow="never" class="side-card">
          <template #header>
            <div class="card-title">操作员操作记录</div>
          </template>
          <div class="record-list">
            <div v-for="item in operationRecords" :key="item.id" class="record-item">
              <div class="record-time">{{ item.time }}</div>
              <div class="record-content">
                <div class="record-action">{{ item.action }}</div>
                <div class="record-target">{{ item.target }}</div>
              </div>
            </div>
          </div>
        </el-card>

        <el-card shadow="never" class="side-card">
          <template #header>
            <div class="card-title">人机交互信息</div>
          </template>
          <div class="event-list">
            <div v-for="item in eventList" :key="item.id" class="event-item">
              <div class="event-title">{{ item.title }}</div>
              <div class="event-desc">{{ item.description }}</div>
              <div class="event-meta">{{ item.time }} · {{ item.handler }}</div>
            </div>
          </div>
        </el-card>

        <div v-if="activeAlarms.length" class="alert-bar">
          <div class="alert-icon">!</div>
          <div class="alert-messages">
            <div v-for="item in activeAlarms.slice(0, 3)" :key="item.pointId">{{ item.message }}</div>
          </div>
        </div>
      </el-col>
    </el-row>

    <el-dialog title="实时展示详情" v-model="detailOpen" width="960px" append-to-body>
      <el-descriptions :column="2" border v-if="detailData.pointInfo">
        <el-descriptions-item label="监测点名称">{{ detailData.pointInfo.pointName || "-" }}</el-descriptions-item>
        <el-descriptions-item label="监测点编码">{{ detailData.pointInfo.pointCode || "-" }}</el-descriptions-item>
        <el-descriptions-item label="监测类型">{{ detailData.pointInfo.pointType || "-" }}</el-descriptions-item>
        <el-descriptions-item label="当前状态">{{ detailData.pointInfo.status || "-" }}</el-descriptions-item>
        <el-descriptions-item label="所属设施">{{ detailData.networkInfo?.networkName || "-" }}</el-descriptions-item>
        <el-descriptions-item label="位置描述">{{ detailData.pointInfo.location || "-" }}</el-descriptions-item>
      </el-descriptions>

      <el-divider content-position="left">关联设备</el-divider>
      <el-table :data="detailData.equipmentList || []" border max-height="320">
        <el-table-column label="设备编码" prop="equipmentCode" min-width="140" />
        <el-table-column label="设备名称" prop="equipmentName" min-width="180" show-overflow-tooltip />
        <el-table-column label="设备型号" prop="equipmentModel" min-width="120" />
        <el-table-column label="制造商" prop="manufacturer" min-width="140" show-overflow-tooltip />
        <el-table-column label="设备位置" prop="equipmentLocation" min-width="180" show-overflow-tooltip />
      </el-table>
    </el-dialog>
  </div>
</template>

<script setup>
import { computed, onMounted, reactive, ref } from "vue";
import { getMonitorPointDetail, listMonitorPointAll, listPipeNetworkAll } from "@/api/pipeNetwork/pdeviceInform";

const loading = ref(false);
const networkOptions = ref([]);
const pointList = ref([]);
const pointDetailMap = ref({});
const detailOpen = ref(false);
const detailData = ref({});

const filters = reactive({
  networkId: undefined,
  status: undefined
});

const operationRecords = ref([
  { id: 1, time: "08:30:21", action: "值班员查看监测点详情", target: "化工园区关键点位" },
  { id: 2, time: "09:15:47", action: "刷新感知信息展示", target: "管网设施全量数据" },
  { id: 3, time: "10:02:12", action: "核查异常状态点位", target: "城南泵站压力监测点" },
  { id: 4, time: "10:38:55", action: "确认日常巡检结果", target: "今日管网感知列表" }
]);

const eventList = ref([
  { id: 1, title: "重大灾害事件", description: "重点关注异常点位运行情况，必要时联动应急处置。", time: "今日", handler: "中控值班" },
  { id: 2, title: "管网事件", description: "对预警、维修中的监测点进行重点巡查与记录。", time: "实时", handler: "管网运维" },
  { id: 3, title: "日常事件", description: "持续更新巡检、交接班和设备观察信息。", time: "本班次", handler: "值班班组" }
]);

const statusOptions = computed(() => {
  return [...new Set(pointList.value.map((item) => item.status).filter(Boolean))];
});

const displayCards = computed(() => {
  return pointList.value
    .filter((item) => !filters.networkId || item.networkId === filters.networkId)
    .filter((item) => !filters.status || item.status === filters.status)
    .map((item) => {
      const detail = pointDetailMap.value[item.pointId] || {};
      return {
        ...item,
        equipmentCount: (detail.equipmentList || []).length,
        networkName: networkOptions.value.find((network) => network.networkId === item.networkId)?.networkName
      };
    });
});

const activeAlarms = computed(() => {
  return displayCards.value
    .filter((item) => isAlertStatus(item.status))
    .map((item) => ({
      pointId: item.pointId,
      message: `${item.pointName} 当前状态为 ${item.status || "异常"}，请值班人员重点关注`
    }));
});

const alarmCount = computed(() => activeAlarms.value.length);
const normalCount = computed(() => displayCards.value.filter((item) => ["正常", "启用"].includes(item.status)).length);
const equipmentCount = computed(() => {
  return Object.values(pointDetailMap.value).reduce((count, item) => count + (item.equipmentList || []).length, 0);
});

function isAlertStatus(status) {
  return !["正常", "启用"].includes(status);
}

function getPointEmoji(type) {
  if (type?.includes("压力")) return "📊";
  if (type?.includes("流量")) return "💧";
  if (type?.includes("温度")) return "🌡️";
  if (type?.includes("泄漏")) return "🚨";
  return "📡";
}

function getCardClass(status) {
  if (["正常", "启用"].includes(status)) return "is-normal";
  if (status === "预警") return "is-warning";
  return "is-danger";
}

function getStatusDotClass(status) {
  if (["正常", "启用"].includes(status)) return "dot-normal";
  if (status === "预警") return "dot-warning";
  return "dot-danger";
}

function loadDashboard() {
  loading.value = true;
  return Promise.all([listPipeNetworkAll(), listMonitorPointAll()])
    .then(async ([networkRes, pointRes]) => {
      networkOptions.value = networkRes.data || [];
      pointList.value = pointRes.data || [];
      const details = await Promise.all(pointList.value.map((item) => getMonitorPointDetail(item.pointId)));
      const map = {};
      details.forEach((detail, index) => {
        map[pointList.value[index].pointId] = detail.data || {};
      });
      pointDetailMap.value = map;
      operationRecords.value.unshift({
        id: Date.now(),
        time: new Date().toLocaleTimeString(),
        action: "刷新感知信息展示",
        target: `加载 ${pointList.value.length} 个监测点`
      });
      operationRecords.value = operationRecords.value.slice(0, 8);
    })
    .finally(() => {
      loading.value = false;
    });
}

function openDetail(card) {
  detailData.value = pointDetailMap.value[card.pointId] || {};
  detailOpen.value = true;
  operationRecords.value.unshift({
    id: Date.now() + Math.random(),
    time: new Date().toLocaleTimeString(),
    action: "查看实时详情",
    target: card.pointName
  });
  operationRecords.value = operationRecords.value.slice(0, 8);
}

onMounted(() => {
  loadDashboard();
});
</script>

<style scoped>
.realtime-page {
  background: linear-gradient(180deg, #f3f7fd 0%, #f8fafc 100%);
}

.hero-panel {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
  padding: 20px 24px;
  border-radius: 18px;
  background: linear-gradient(135deg, #0f2742, #1d4f7d);
  color: #fff;
}

.hero-title {
  font-size: 24px;
  font-weight: 700;
}

.hero-subtitle {
  margin-top: 8px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.84);
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 16px;
}

.summary-card {
  border: none;
  color: #fff;
}

.summary-card :deep(.el-card__body) {
  padding: 20px;
}

.summary-card.primary {
  background: linear-gradient(135deg, #2563eb, #5b93ff);
}

.summary-card.success {
  background: linear-gradient(135deg, #059669, #34d399);
}

.summary-card.danger {
  background: linear-gradient(135deg, #dc2626, #ff7070);
}

.summary-card.info {
  background: linear-gradient(135deg, #7c3aed, #9d72ff);
}

.summary-label {
  font-size: 14px;
}

.summary-value {
  margin: 8px 0 10px;
  font-size: 30px;
  font-weight: 700;
}

.summary-desc {
  font-size: 12px;
  opacity: 0.9;
}

.main-card,
.side-card {
  border-radius: 16px;
}

.card-header-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.card-title {
  font-size: 16px;
  font-weight: 600;
  color: #1f2937;
}

.card-subtitle {
  margin-top: 4px;
  font-size: 12px;
  color: #6b7280;
}

.filter-group {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.device-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.device-card {
  padding: 16px;
  border-radius: 16px;
  background: #fff;
  border: 1px solid #e5edf7;
  cursor: pointer;
  transition: all 0.2s ease;
}

.device-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 24px rgba(15, 23, 42, 0.08);
}

.device-card.is-normal {
  border-left: 4px solid #16a34a;
}

.device-card.is-warning {
  border-left: 4px solid #f59e0b;
  background: #fffaf0;
}

.device-card.is-danger {
  border-left: 4px solid #dc2626;
  background: #fff5f5;
}

.device-top {
  display: flex;
  gap: 12px;
}

.device-icon {
  width: 52px;
  height: 52px;
  border-radius: 14px;
  background: #eff6ff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
}

.device-icon.pulse {
  animation: pulse 1s infinite;
}

.device-info {
  flex: 1;
}

.device-name {
  font-size: 16px;
  font-weight: 700;
  color: #111827;
}

.device-location,
.device-network,
.device-meta,
.record-time,
.record-target,
.event-desc,
.event-meta {
  font-size: 12px;
  color: #6b7280;
}

.device-network {
  margin-top: 4px;
}

.device-status-line {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  font-size: 12px;
  color: #374151;
}

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

.dot-normal {
  background: #16a34a;
}

.dot-warning {
  background: #f59e0b;
}

.dot-danger {
  background: #dc2626;
}

.device-count {
  margin-left: auto;
  color: #1d4ed8;
}

.device-meta {
  margin-top: 8px;
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.record-list,
.event-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.record-item,
.event-item {
  padding: 12px;
  border-radius: 12px;
  background: #f8fafc;
  border: 1px solid #edf2f7;
}

.record-action,
.event-title {
  font-size: 14px;
  font-weight: 600;
  color: #111827;
}

.record-target,
.event-desc,
.event-meta {
  margin-top: 4px;
}

.alert-bar {
  margin-top: 16px;
  display: flex;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 14px;
  background: #dc2626;
  color: #fff;
}

.alert-icon {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
}

.alert-messages {
  font-size: 12px;
  line-height: 1.7;
}

@keyframes pulse {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.08);
  }
}

@media (max-width: 1200px) {
  .summary-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .device-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .hero-panel,
  .card-header-row {
    flex-direction: column;
    align-items: flex-start;
  }

  .summary-grid {
    grid-template-columns: 1fr;
  }
}
</style>
