<!-- 报警信息关联 -->
<template>
  <div class="app-container alarm-correlation-page">
    <el-card shadow="never" class="page-card header-card">
      <div class="page-header">
        <div>
          <div class="page-title">报警信息关联</div>
          <div class="page-subtitle">统一管理报警与预警的关联关系，将设备超指标异常报警与预警信息建立对应，作为发布和处置的重要依据</div>
        </div>
        <div class="header-actions">
          <el-button type="primary" icon="Refresh" @click="loadAllData">刷新数据</el-button>
        </div>
      </div>
    </el-card>

    <div class="summary-grid">
      <el-card shadow="hover" class="summary-card primary">
        <div class="summary-label">报警总数</div>
        <div class="summary-value">{{ stats.totalAlarms }}</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">{{ stats.linkedCount }}</div>
        <div class="summary-desc">已建立报警与预警关联关系</div>
      </el-card>
      <el-card shadow="hover" class="summary-card warning">
        <div class="summary-label">未关联</div>
        <div class="summary-value">{{ stats.unlinkedCount }}</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">{{ availableWarnings.length }}</div>
        <div class="summary-desc">可作为关联目标的预警信息</div>
      </el-card>
    </div>

    <el-card shadow="never" class="page-card">
      <el-form :model="queryParams" :inline="true">
        <el-form-item label="设备编码">
          <el-input
            v-model="queryParams.deviceCode"
            placeholder="请输入设备编码"
            clearable
            style="width: 220px"
            @keyup.enter="handleQuery"
          />
        </el-form-item>
        <el-form-item label="告警类型">
          <el-input
            v-model="queryParams.warningType"
            placeholder="请输入告警类型"
            clearable
            style="width: 220px"
            @keyup.enter="handleQuery"
          />
        </el-form-item>
        <el-form-item label="报警状态">
          <el-select v-model="queryParams.alarmStatus" placeholder="请选择报警状态" clearable style="width: 180px">
            <el-option label="未处理" :value="0" />
            <el-option label="已处理" :value="1" />
          </el-select>
        </el-form-item>
        <el-form-item label="关联状态">
          <el-select v-model="queryParams.associationStatus" placeholder="请选择关联状态" clearable style="width: 180px">
            <el-option label="已关联" value="linked" />
            <el-option label="未关联" value="unlinked" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card shadow="never" class="page-card">
      <el-table v-loading="loading" :data="pagedAlarmList" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" />
        <el-table-column label="设备编码" prop="deviceCode" min-width="160" />
        <el-table-column label="告警类型" prop="warningTypeText" width="120" />
        <el-table-column label="告警编码" prop="warningCode" width="160" />
        <el-table-column label="阈值范围" prop="thresholdText" width="160" />
        <el-table-column label="实际值" prop="actualValue" width="120" />
        <el-table-column label="报警时间" prop="alarmTime" width="180" />
        <el-table-column label="报警状态" width="100" align="center">
          <template #default="scope">
            <el-tag :type="scope.row.alarmStatus === 1 ? 'success' : 'warning'">
              {{ scope.row.alarmStatus === 1 ? "已处理" : "未处理" }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="关联状态" width="100" align="center">
          <template #default="scope">
            <el-tag :type="scope.row.linkedWarning ? 'success' : 'info'">
              {{ scope.row.linkedWarning ? "已关联" : "未关联" }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="关联预警" min-width="180">
          <template #default="scope">
            <span
              v-if="scope.row.linkedWarning"
              class="warning-link"
              @click="openWarningDetail(scope.row.linkedWarning.warningId)"
            >
              {{ scope.row.linkedWarning.warningName }}
            </span>
            <span v-else class="empty-text">-</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" fixed="right" width="220" align="center">
          <template #default="scope">
            <el-button link type="primary" @click="openAssociationDialog(scope.row)" v-if="!scope.row.linkedWarning">
              关联预警
            </el-button>
            <el-button link type="success" @click="openWarningDetail(scope.row.linkedWarning.warningId)" v-if="scope.row.linkedWarning">
              查看预警
            </el-button>
            <el-button link type="info" @click="openAlarmDetail(scope.row)">报警详情</el-button>
          </template>
        </el-table-column>
      </el-table>

      <pagination
        v-show="total > 0"
        :total="total"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        @pagination="handlePageChange"
      />
    </el-card>

    <div class="batch-bar" v-if="selectedRows.length">
      <span>已选择 {{ selectedRows.length }} 条报警</span>
      <el-button type="primary" @click="openBatchAssociationDialog">批量关联预警</el-button>
      <el-button @click="selectedRows = []">清空选择</el-button>
    </div>

    <el-dialog v-model="associationDialog.visible" title="关联预警" width="620px" append-to-body>
      <el-form label-width="100px">
        <el-form-item label="设备编码">
          <el-input :model-value="associationDialog.row?.deviceCode || '-'" disabled />
        </el-form-item>
        <el-form-item label="告警类型">
          <el-input :model-value="associationDialog.row?.warningTypeText || '-'" disabled />
        </el-form-item>
        <el-form-item label="报警内容">
          <el-input :model-value="buildAlarmContent(associationDialog.row)" type="textarea" :rows="3" disabled />
        </el-form-item>
        <el-form-item label="选择预警">
          <el-select v-model="associationDialog.warningId" placeholder="请选择预警" filterable style="width: 100%">
            <el-option
              v-for="item in availableWarnings"
              :key="item.warningId"
              :label="item.warningName"
              :value="item.warningId"
            >
              <div class="warning-option">
                <span>{{ item.warningName }}</span>
                <el-tag :type="getWarningLevelType(item.warningLevel)">{{ item.warningLevelText }}</el-tag>
              </div>
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="associationDialog.visible = false">取 消</el-button>
          <el-button type="primary" :loading="submitLoading" @click="confirmAssociation">确 定</el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog v-model="batchDialog.visible" title="批量关联预警" width="620px" append-to-body>
      <el-form label-width="100px">
        <el-form-item label="报警数量">
          <el-input :model-value="`已选 ${batchSelectableCount} 条未关联报警`" disabled />
        </el-form-item>
        <el-form-item label="选择预警">
          <el-select v-model="batchDialog.warningId" placeholder="请选择预警" filterable style="width: 100%">
            <el-option
              v-for="item in availableWarnings"
              :key="item.warningId"
              :label="item.warningName"
              :value="item.warningId"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="batchDialog.visible = false">取 消</el-button>
          <el-button type="primary" :loading="submitLoading" @click="confirmBatchAssociation">确 定</el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog v-model="warningDetailVisible" title="预警详情" width="900px" append-to-body>
      <template v-if="warningDetailData.basicInfo">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="预警编号">{{ warningDetailData.basicInfo.warningNo || "-" }}</el-descriptions-item>
          <el-descriptions-item label="预警名称">{{ warningDetailData.basicInfo.warningName || "-" }}</el-descriptions-item>
          <el-descriptions-item label="告警类型">{{ formatTypeText(warningDetailData.basicInfo.warningType) }}</el-descriptions-item>
          <el-descriptions-item label="预警级别">{{ formatLevelText(warningDetailData.basicInfo.warningLevel) }}</el-descriptions-item>
          <el-descriptions-item label="预警位置" :span="2">{{ warningDetailData.basicInfo.location || "-" }}</el-descriptions-item>
          <el-descriptions-item label="发布时间">{{ warningDetailData.basicInfo.publishTime || "-" }}</el-descriptions-item>
          <el-descriptions-item label="状态">{{ warningDetailData.basicInfo.status || "-" }}</el-descriptions-item>
          <el-descriptions-item label="内容描述" :span="2">{{ warningDetailData.basicInfo.warningContent || "-" }}</el-descriptions-item>
        </el-descriptions>

        <el-divider content-position="left">已关联报警</el-divider>
        <el-table :data="warningDetailData.alarmList || []" border size="small">
          <el-table-column label="设备编码" prop="device_code" min-width="160" />
          <el-table-column label="告警类型" prop="warning_type" width="120" />
          <el-table-column label="告警编码" prop="warning_code" width="160" />
          <el-table-column label="阈值" prop="warning_value" width="120" />
          <el-table-column label="实际值" prop="actual_value" width="120" />
          <el-table-column label="报警时间" prop="alarm_time" width="180" />
        </el-table>
      </template>
    </el-dialog>

    <el-dialog v-model="alarmDetailVisible" title="报警详情" width="680px" append-to-body>
      <el-descriptions :column="2" border v-if="currentAlarmDetail">
        <el-descriptions-item label="报警ID">{{ currentAlarmDetail.id || "-" }}</el-descriptions-item>
        <el-descriptions-item label="设备编码">{{ currentAlarmDetail.deviceCode || "-" }}</el-descriptions-item>
        <el-descriptions-item label="告警类型">{{ currentAlarmDetail.warningTypeText || "-" }}</el-descriptions-item>
        <el-descriptions-item label="告警编码">{{ currentAlarmDetail.warningCode || "-" }}</el-descriptions-item>
        <el-descriptions-item label="阈值范围">{{ currentAlarmDetail.thresholdText || "-" }}</el-descriptions-item>
        <el-descriptions-item label="实际值">{{ currentAlarmDetail.actualValue || "-" }}</el-descriptions-item>
        <el-descriptions-item label="报警时间">{{ currentAlarmDetail.alarmTime || "-" }}</el-descriptions-item>
        <el-descriptions-item label="报警状态">{{ currentAlarmDetail.alarmStatus === 1 ? "已处理" : "未处理" }}</el-descriptions-item>
        <el-descriptions-item label="处理时间">{{ currentAlarmDetail.handleTime || "-" }}</el-descriptions-item>
        <el-descriptions-item label="处理人">{{ currentAlarmDetail.handleUser || "-" }}</el-descriptions-item>
        <el-descriptions-item label="处理备注" :span="2">{{ currentAlarmDetail.handleRemark || currentAlarmDetail.remark || "-" }}</el-descriptions-item>
      </el-descriptions>
    </el-dialog>
  </div>
</template>

<script setup>
import { computed, onMounted, reactive, ref } from "vue";
import { ElMessage } from "element-plus";
import {
  getAlarmPageData,
  getAlertTypeDictionaryData,
  getLinkedAlarmListData,
  getWarningDetailData,
  getdbyjlistData,
  updateWarningAlarm
} from "@/api/smxyjldczxt/yjxxfb/yjfb.js";

const loading = ref(false);
const submitLoading = ref(false);
const warningTypeOptions = ref([]);
const availableWarnings = ref([]);
const rawAlarmList = ref([]);
const selectedRows = ref([]);
const linkedAlarmMap = ref({});

const total = ref(0);
const warningDetailVisible = ref(false);
const alarmDetailVisible = ref(false);
const warningDetailData = ref({});
const currentAlarmDetail = ref(null);

const associationDialog = reactive({
  visible: false,
  row: null,
  warningId: ""
});

const batchDialog = reactive({
  visible: false,
  warningId: ""
});

const queryParams = reactive({
  pageNum: 1,
  pageSize: 10,
  deviceCode: "",
  warningType: "",
  alarmStatus: undefined,
  associationStatus: ""
});

const warningTypeLabelMap = computed(() => {
  return warningTypeOptions.value.reduce((acc, item) => {
    acc[item.dictValue] = item.dictLabel;
    return acc;
  }, {});
});

const filteredAlarmList = computed(() => {
  let list = [...rawAlarmList.value];
  if (queryParams.associationStatus === "linked") {
    list = list.filter((item) => item.linkedWarning);
  }
  if (queryParams.associationStatus === "unlinked") {
    list = list.filter((item) => !item.linkedWarning);
  }
  return list;
});

const pagedAlarmList = computed(() => filteredAlarmList.value);

const stats = computed(() => {
  const linkedCount = rawAlarmList.value.filter((item) => item.linkedWarning).length;
  return {
    totalAlarms: rawAlarmList.value.length,
    linkedCount,
    unlinkedCount: rawAlarmList.value.length - linkedCount
  };
});

const batchSelectableCount = computed(() => {
  return selectedRows.value.filter((item) => !item.linkedWarning).length;
});

function formatTypeText(value) {
  return warningTypeLabelMap.value[value] || value || "-";
}

function formatLevelText(value) {
  const map = {
    "1": "一级",
    "2": "二级",
    "3": "三级",
    "4": "四级"
  };
  return map[value] || value || "-";
}

function getWarningLevelType(level) {
  return {
    "1": "danger",
    "2": "warning",
    "3": "success",
    "4": "info"
  }[level] || "info";
}

function normalizeWarningRow(item) {
  return {
    warningId: item.warningId || item.warning_id,
    warningNo: item.warningNo || item.warning_no,
    warningName: item.warningName || item.warning_name,
    warningType: item.warningType || item.warning_type,
    warningLevel: item.warningLevel || item.warning_level,
    warningLevelText: formatLevelText(item.warningLevel || item.warning_level),
    publishTime: item.publishTime || item.publish_time,
    status: item.status,
    location: item.location,
    warningContent: item.warningContent || item.warning_content
  };
}

function buildThresholdText(item) {
  if (item.warningValue) {
    return item.warningValue;
  }
  if (item.minValue !== null && item.minValue !== undefined && item.maxValue !== null && item.maxValue !== undefined) {
    return `${item.minValue} ~ ${item.maxValue}`;
  }
  if (item.minValue !== null && item.minValue !== undefined) {
    return `<= ${item.minValue}`;
  }
  if (item.maxValue !== null && item.maxValue !== undefined) {
    return `>= ${item.maxValue}`;
  }
  return "-";
}

function normalizeAlarmRow(item) {
  const linkedWarning = linkedAlarmMap.value[item.id];
  return {
    ...item,
    warningTypeText: formatTypeText(item.warningType),
    thresholdText: buildThresholdText(item),
    linkedWarning
  };
}

function buildAlarmContent(row) {
  if (!row) {
    return "-";
  }
  return `告警类型：${row.warningTypeText || "-"}\n阈值范围：${row.thresholdText || "-"}\n实际值：${row.actualValue || "-"}`;
}

async function loadWarningTypes() {
  const res = await getAlertTypeDictionaryData({ dictType: "alert_type" });
  warningTypeOptions.value = res.rows || [];
}

async function loadWarnings() {
  const res = await getdbyjlistData({
    pageNum: 1,
    pageSize: 200
  });
  availableWarnings.value = (res.data?.records || []).map(normalizeWarningRow);
}

async function buildLinkedAlarmMap() {
  const map = {};
  await Promise.all(
    availableWarnings.value.map(async (warning) => {
      const res = await getLinkedAlarmListData(warning.warningId);
      (res.data || []).forEach((alarm) => {
        const alarmId = alarm.alarmId || alarm.alarm_id;
        if (alarmId) {
          map[alarmId] = {
            warningId: warning.warningId,
            warningName: warning.warningName,
            warningLevel: warning.warningLevel,
            warningLevelText: warning.warningLevelText
          };
        }
      });
    })
  );
  linkedAlarmMap.value = map;
}

async function loadAlarms() {
  const res = await getAlarmPageData({
    pageNum: queryParams.pageNum,
    pageSize: queryParams.pageSize,
    deviceCode: queryParams.deviceCode || undefined,
    warningType: queryParams.warningType || undefined,
    alarmStatus: queryParams.alarmStatus
  });
  const pageData = res.data || {};
  const records = pageData.records || [];
  total.value = pageData.total || 0;
  rawAlarmList.value = records.map(normalizeAlarmRow);
}

async function loadAllData() {
  loading.value = true;
  try {
    await loadWarnings();
    await buildLinkedAlarmMap();
    await loadAlarms();
  } finally {
    loading.value = false;
  }
}

function handleSelectionChange(val) {
  selectedRows.value = val;
}

function handleQuery() {
  queryParams.pageNum = 1;
  loadAllData();
}

function resetQuery() {
  queryParams.pageNum = 1;
  queryParams.pageSize = 10;
  queryParams.deviceCode = "";
  queryParams.warningType = "";
  queryParams.alarmStatus = undefined;
  queryParams.associationStatus = "";
  loadAllData();
}

function handlePageChange() {
  selectedRows.value = [];
  loadAlarms();
}

function openAssociationDialog(row) {
  associationDialog.row = row;
  associationDialog.warningId = "";
  associationDialog.visible = true;
}

async function linkAlarmsToWarning(warningId, alarmIds) {
  return updateWarningAlarm({
    warningId,
    alarmIds
  });
}

async function confirmAssociation() {
  if (!associationDialog.warningId) {
    ElMessage.warning("请选择预警");
    return;
  }
  submitLoading.value = true;
  try {
    const linkedRes = await getLinkedAlarmListData(associationDialog.warningId);
    const currentIds = (linkedRes.data || []).map((item) => item.alarmId || item.alarm_id).filter(Boolean);
    const nextIds = Array.from(new Set([...currentIds, associationDialog.row.id]));
    const res = await linkAlarmsToWarning(associationDialog.warningId, nextIds);
    if (res.code !== 200) {
      ElMessage.error(res.msg || "关联失败");
      return;
    }
    ElMessage.success("关联成功");
    associationDialog.visible = false;
    await loadAllData();
  } finally {
    submitLoading.value = false;
  }
}

function openBatchAssociationDialog() {
  if (!batchSelectableCount.value) {
    ElMessage.warning("请选择未关联报警");
    return;
  }
  batchDialog.warningId = "";
  batchDialog.visible = true;
}

async function confirmBatchAssociation() {
  if (!batchDialog.warningId) {
    ElMessage.warning("请选择预警");
    return;
  }
  const selectedIds = selectedRows.value.filter((item) => !item.linkedWarning).map((item) => item.id);
  if (!selectedIds.length) {
    ElMessage.warning("当前没有可关联的报警");
    return;
  }
  submitLoading.value = true;
  try {
    const linkedRes = await getLinkedAlarmListData(batchDialog.warningId);
    const currentIds = (linkedRes.data || []).map((item) => item.alarmId || item.alarm_id).filter(Boolean);
    const nextIds = Array.from(new Set([...currentIds, ...selectedIds]));
    const res = await linkAlarmsToWarning(batchDialog.warningId, nextIds);
    if (res.code !== 200) {
      ElMessage.error(res.msg || "批量关联失败");
      return;
    }
    ElMessage.success("批量关联成功");
    batchDialog.visible = false;
    selectedRows.value = [];
    await loadAllData();
  } finally {
    submitLoading.value = false;
  }
}

async function openWarningDetail(warningId) {
  const res = await getWarningDetailData(warningId);
  warningDetailData.value = res.data || {};
  warningDetailVisible.value = true;
}

function openAlarmDetail(row) {
  currentAlarmDetail.value = row;
  alarmDetailVisible.value = true;
}

onMounted(async () => {
  await loadWarningTypes();
  await loadAllData();
});
</script>

<style scoped>
.alarm-correlation-page {
  background: #f5f7fb;
}

.page-card {
  border-radius: 16px;
  margin-bottom: 16px;
}

.header-card {
  background: linear-gradient(135deg, #eff6ff, #f8fbff);
  border: 1px solid #dbeafe;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}

.page-title {
  font-size: 22px;
  font-weight: 700;
  color: #1e3a8a;
}

.page-subtitle {
  margin-top: 8px;
  font-size: 13px;
  color: #64748b;
}

.header-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.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.warning {
  background: linear-gradient(135deg, #d97706, #f7b955);
}

.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;
}

.warning-link {
  color: #409eff;
  cursor: pointer;
}

.warning-link:hover {
  color: #66b1ff;
}

.empty-text {
  color: #9ca3af;
}

.warning-option {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.batch-bar {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  background: #fff;
  border-radius: 999px;
  box-shadow: 0 10px 30px rgba(15, 23, 42, 0.15);
  padding: 12px 20px;
  display: flex;
  align-items: center;
  gap: 12px;
}

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

@media (max-width: 768px) {
  .page-header {
    flex-direction: column;
    align-items: flex-start;
  }

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

  .batch-bar {
    left: 12px;
    right: 12px;
    transform: none;
    border-radius: 16px;
    flex-wrap: wrap;
  }
}
</style>
