<template>
  <div class="app-container report-page">
    <el-row :gutter="18">
      <el-col :xl="5" :lg="6" :md="7" :sm="24" :xs="24">
        <section class="glass-panel tree-panel">
          <div class="panel-head">
            <div>
              <p class="panel-eyebrow">Alert Scope</p>
              <h3>统计范围树</h3>
            </div>
          </div>
          <el-tree
            v-loading="treeLoading"
            :data="treeData"
            node-key="id"
            :props="{ label: 'label', children: 'children' }"
            default-expand-all
            highlight-current
            @node-click="handleNodeClick"
          />
        </section>
      </el-col>

      <el-col :xl="19" :lg="18" :md="17" :sm="24" :xs="24">
        <section class="hero-panel">
          <div>
            <p class="panel-eyebrow hero-eyebrow">Alarm Report</p>
            <h2>用能异常报警报表</h2>
            <p class="hero-desc">这里严格区分“当前无数据”和“当前 0 告警”。只有时间范围内存在分表数据时，页面才会把 0 告警解释为真正未命中规则。</p>
          </div>
          <el-tag effect="dark">{{ selectionLabel || '未选择范围' }}</el-tag>
        </section>

        <section class="glass-panel">
          <div class="panel-head">
            <div>
              <p class="panel-eyebrow">Query</p>
              <h3>报警筛选</h3>
            </div>
            <el-button type="primary" @click="handleQuery">刷新报表</el-button>
          </div>

          <el-form :inline="true" :model="queryForm" size="small">
            <el-form-item label="统计范围">
              <el-input :model-value="selectionLabel || '请先在左侧选择节点'" readonly style="width: 260px" />
            </el-form-item>
            <el-form-item label="记录时间">
              <el-date-picker
                v-model="timeRange"
                type="datetimerange"
                value-format="YYYY-MM-DD HH:mm:ss"
                range-separator="-"
                start-placeholder="开始时间"
                end-placeholder="结束时间"
                style="width: 340px"
              />
            </el-form-item>
            <el-form-item label="处理状态">
              <el-select v-model="queryForm.alarmStatus" clearable style="width: 120px">
                <el-option label="未处理" :value="1" />
                <el-option label="已处理" :value="0" />
              </el-select>
            </el-form-item>
          </el-form>
        </section>

        <section v-loading="loading" class="glass-panel">
          <div class="panel-head">
            <div>
              <p class="panel-eyebrow">Summary</p>
              <h3>报警概览</h3>
            </div>
          </div>

          <el-empty v-if="!reportData || reportData.hasData === false" :description="reportData?.emptyReason || '当前条件下无可分析数据'" />

          <template v-else>
            <div class="summary-grid">
              <article class="summary-card">
                <span>告警总数</span>
                <strong>{{ reportData.summary?.totalCount || 0 }}</strong>
              </article>
              <article class="summary-card">
                <span>未处理</span>
                <strong>{{ reportData.summary?.unhandledCount || 0 }}</strong>
              </article>
              <article class="summary-card">
                <span>已处理</span>
                <strong>{{ reportData.summary?.handledCount || 0 }}</strong>
              </article>
            </div>
            <AlarmTrendPanel :trend="reportData.trend || []" />
          </template>
        </section>

        <section v-if="reportData?.ranking?.length" class="glass-panel">
          <div class="panel-head">
            <div>
              <p class="panel-eyebrow">Ranking</p>
              <h3>异常排行</h3>
            </div>
          </div>

          <el-table :data="reportData.ranking" stripe>
            <el-table-column prop="monitorName" label="点位" min-width="180" />
            <el-table-column prop="alarmCount" label="告警数" min-width="100" />
            <el-table-column prop="unhandledCount" label="未处理" min-width="100" />
          </el-table>
        </section>

        <section v-if="reportData?.records?.length" class="glass-panel">
          <div class="panel-head">
            <div>
              <p class="panel-eyebrow">Records</p>
              <h3>最近报警记录</h3>
            </div>
          </div>

          <el-table :data="reportData.records" stripe>
            <el-table-column prop="monitorName" label="点位" min-width="160" />
            <el-table-column prop="alarmTitle" label="告警标题" min-width="220" />
            <el-table-column prop="actualValue" label="实际值" min-width="100" />
            <el-table-column prop="alarmLevel" label="级别" min-width="100" />
            <el-table-column prop="collectTime" label="记录时间" min-width="180" />
          </el-table>
        </section>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue';
import { ElMessage } from 'element-plus';
import AlarmTrendPanel from '../components/AlarmTrendPanel.vue';
import { getMonitorInfoTree } from '@/api/ems/base/baseMonitorInfo';
import { getEnergyAbnormalAlertReport } from '@/api/ems/report/iotAdvancedReport';
import type { EmsTreeNode, EnergyAbnormalAlertReportVO } from '@/api/ems/types';
import { parseTime } from '@/utils/ruoyi';

defineOptions({
  name: 'EnergyAbnormalAlertReport'
});

const treeLoading = ref(false);
const loading = ref(false);
const treeData = ref<EmsTreeNode[]>([]);
const selectionLabel = ref('');
const reportData = ref<EnergyAbnormalAlertReportVO>();

const createDefaultRange = () => {
  const now = new Date();
  const start = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
  return [parseTime(start, '{y}-{m}-{d} {h}:{i}:{s}'), parseTime(now, '{y}-{m}-{d} {h}:{i}:{s}')];
};

const timeRange = ref<string[]>(createDefaultRange());

const queryForm = reactive({
  monitorIds: [] as string[],
  alarmStatus: undefined as number | undefined
});

const getLeafNodes = (nodes: EmsTreeNode[]): EmsTreeNode[] => {
  let result: EmsTreeNode[] = [];
  (nodes || []).forEach((item) => {
    if (item.children && item.children.length > 0) {
      result = result.concat(getLeafNodes(item.children));
      return;
    }
    if (item.code) {
      result.push(item);
    }
  });
  return result;
};

const loadTree = async () => {
  treeLoading.value = true;
  try {
    const response = await getMonitorInfoTree({});
    treeData.value = response.data || [];
  } finally {
    treeLoading.value = false;
  }
};

const handleNodeClick = (node: EmsTreeNode) => {
  const targetNodes = node.children && node.children.length > 0 ? getLeafNodes([node]) : [node];
  queryForm.monitorIds = targetNodes.map((item) => String(item.code || '')).filter((item) => item);
  selectionLabel.value = String(node.label || '当前节点');
};

const handleQuery = async () => {
  if (!queryForm.monitorIds.length) {
    ElMessage.warning('请先选择统计范围');
    return;
  }
  if (!timeRange.value || timeRange.value.length !== 2) {
    ElMessage.warning('请选择完整的记录时间范围');
    return;
  }
  loading.value = true;
  try {
    const { data } = await getEnergyAbnormalAlertReport({
      monitorIds: queryForm.monitorIds,
      alarmStatus: queryForm.alarmStatus,
      beginRecordTime: timeRange.value[0],
      endRecordTime: timeRange.value[1]
    });
    reportData.value = data || { hasData: false, emptyReason: '接口未返回有效数据' };
  } finally {
    loading.value = false;
  }
};

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

<style scoped>
.report-page {
  min-height: calc(100vh - 84px);
  background:
    radial-gradient(circle at top right, rgba(37, 99, 235, 0.14), transparent 24%),
    radial-gradient(circle at top left, rgba(20, 184, 166, 0.1), transparent 28%), linear-gradient(180deg, #f4f8ff 0%, #f8fafc 100%);
}

.glass-panel,
.hero-panel,
.summary-card {
  border-radius: 24px;
  border: 1px solid rgba(148, 163, 184, 0.18);
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 18px 48px rgba(15, 23, 42, 0.08);
}

.tree-panel,
.glass-panel {
  padding: 18px 20px;
  margin-bottom: 18px;
}

.hero-panel {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 24px;
  margin-bottom: 18px;
  background:
    linear-gradient(135deg, rgba(15, 118, 110, 0.96), rgba(37, 99, 235, 0.92)),
    linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0));
  color: #ffffff;
}

.hero-eyebrow {
  color: rgba(255, 255, 255, 0.72);
}

.hero-panel h2,
.panel-head h3 {
  margin: 0;
}

.hero-desc {
  margin: 14px 0 0;
  max-width: 760px;
  line-height: 1.75;
  color: rgba(255, 255, 255, 0.84);
}

.panel-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}

.panel-eyebrow {
  margin: 0 0 6px;
  color: #2563eb;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
  margin-bottom: 18px;
}

.summary-card {
  padding: 18px;
}

.summary-card span {
  color: #64748b;
  font-size: 13px;
}

.summary-card strong {
  display: block;
  margin-top: 12px;
  font-size: 28px;
  color: #0f172a;
}

@media (max-width: 992px) {
  .hero-panel {
    display: block;
  }
}
</style>
