<template>
  <div class="app-container">
    <el-card shadow="never">
      <el-form :inline="true" :model="queryForm" size="small">
        <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: 380px"
          />
        </el-form-item>
        <el-form-item label="高温阈值">
          <el-input-number v-model="queryForm.highTempThreshold" :min="0" :max="100" :precision="1" style="width: 120px" />
          <span class="ml-1 text-xs text-gray-400">℃</span>
        </el-form-item>
        <el-form-item label="低温阈值">
          <el-input-number v-model="queryForm.lowTempThreshold" :min="-50" :max="50" :precision="1" style="width: 120px" />
          <span class="ml-1 text-xs text-gray-400">℃</span>
        </el-form-item>
        <el-form-item label="温升阈值">
          <el-input-number v-model="queryForm.rapidRiseThreshold" :min="0.1" :max="10" :precision="1" :step="0.1" style="width: 120px" />
          <span class="ml-1 text-xs text-gray-400">℃/min</span>
        </el-form-item>
        <el-form-item label="抖动阈值">
          <el-input-number v-model="queryForm.stddevThreshold" :min="0.1" :max="10" :precision="1" :step="0.1" style="width: 120px" />
          <span class="ml-1 text-xs text-gray-400">σ</span>
        </el-form-item>
        <el-form-item label="连续样本数">
          <el-input-number v-model="queryForm.continuousMinSamples" :min="1" :max="60" style="width: 120px" />
          <span class="ml-1 text-xs text-gray-400">个</span>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-row :gutter="16" class="mt-4">
      <el-col :xs="12" :sm="6">
        <el-card shadow="hover" class="kpi-card kpi-danger">
          <el-statistic title="高温事件" :value="highTempPage.total" />
        </el-card>
      </el-col>
      <el-col :xs="12" :sm="6">
        <el-card shadow="hover" class="kpi-card kpi-primary">
          <el-statistic title="低温事件" :value="lowTempPage.total" />
        </el-card>
      </el-col>
      <el-col :xs="12" :sm="6">
        <el-card shadow="hover" class="kpi-card kpi-warning">
          <!-- KPI 统计改走分页总数，避免随着翻页只显示当前页条数 -->
          <el-statistic title="温升过快" :value="rapidRisePage.total" />
        </el-card>
      </el-col>
      <el-col :xs="12" :sm="6">
        <el-card shadow="hover" class="kpi-card kpi-purple">
          <el-statistic title="温度抖动" :value="jitterList.length" />
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="16" class="mt-4">
      <el-col :xs="24" :sm="12">
        <el-card shadow="never">
          <template #header>
            <div class="card-header">
              <el-tag type="danger" size="small">高温事件明细</el-tag>
              <HelpButton title="异常分析 — 高温事件" :content="ANOMALY_HELP" />
            </div>
          </template>
          <div class="table-v2-wrapper">
            <el-auto-resizer>
              <template #default="{ width, height }">
                <el-table-v2
                  :columns="highTempColumns"
                  :data="highTempList"
                  :width="width"
                  :height="height"
                  :row-height="40"
                  :header-height="40"
                />
              </template>
            </el-auto-resizer>
          </div>
          <div class="pagination-wrapper">
            <el-pagination
              background
              layout="total, sizes, prev, pager, next"
              :total="highTempPage.total"
              :page-size="highTempPage.pageSize"
              :page-sizes="PAGE_SIZE_OPTIONS"
              :current-page="highTempPage.pageNum"
              @current-change="handleHighTempPageChange"
              @size-change="handleHighTempSizeChange"
            />
          </div>
        </el-card>
      </el-col>
      <el-col :xs="24" :sm="12">
        <el-card shadow="never">
          <template #header>
            <div class="card-header">
              <el-tag type="primary" size="small">低温事件明细</el-tag>
              <HelpButton title="异常分析 — 低温事件" :content="ANOMALY_HELP" />
            </div>
          </template>
          <div class="table-v2-wrapper">
            <el-auto-resizer>
              <template #default="{ width, height }">
                <el-table-v2
                  :columns="lowTempColumns"
                  :data="lowTempList"
                  :width="width"
                  :height="height"
                  :row-height="40"
                  :header-height="40"
                />
              </template>
            </el-auto-resizer>
          </div>
          <div class="pagination-wrapper">
            <el-pagination
              background
              layout="total, sizes, prev, pager, next"
              :total="lowTempPage.total"
              :page-size="lowTempPage.pageSize"
              :page-sizes="PAGE_SIZE_OPTIONS"
              :current-page="lowTempPage.pageNum"
              @current-change="handleLowTempPageChange"
              @size-change="handleLowTempSizeChange"
            />
          </div>
        </el-card>
      </el-col>
    </el-row>

    <el-card shadow="never" class="mt-4">
      <template #header>
        <div class="card-header">
          <span class="font-bold">连续高温时段</span>
          <HelpButton title="连续高温时段" :content="ANOMALY_HELP" />
        </div>
      </template>
      <el-table :data="continuousList" stripe size="small" max-height="300">
        <el-table-column prop="monitorId" label="测点ID" width="150" />
        <el-table-column prop="monitorName" label="测点名称" width="180" />
        <el-table-column prop="startTime" label="开始时间" width="200" />
        <el-table-column prop="endTime" label="结束时间" width="200" />
        <el-table-column prop="maxTemp" label="最高温" width="100" align="right">
          <template #default="{ row }">
            <span class="text-red-500 font-bold">{{ row.maxTemp?.toFixed(2) }}℃</span>
          </template>
        </el-table-column>
        <el-table-column prop="sampleCount" label="持续样本数" width="100" align="right" />
      </el-table>
    </el-card>

    <el-row :gutter="16" class="mt-4">
      <el-col :xs="24" :sm="12">
        <el-card shadow="never">
          <template #header>
            <div class="card-header">
              <el-tag type="warning" size="small">温升过快事件</el-tag>
              <HelpButton title="温升过快事件" :content="ANOMALY_HELP" />
            </div>
          </template>
          <!--
            温升过快在噪声 / 工况切换时极易爆量，原先普通 el-table 会一次性
            把几千条行渲染进 DOM；这里升级到 el-table-v2 虚拟滚动 + 分页，
            保证任何查询范围下浏览器都只渲染可视窗口内的若干行。
          -->
          <div class="table-v2-wrapper-sm">
            <el-auto-resizer>
              <template #default="{ width, height }">
                <el-table-v2
                  :columns="rapidRiseColumns"
                  :data="rapidRiseList"
                  :width="width"
                  :height="height"
                  :row-height="40"
                  :header-height="40"
                />
              </template>
            </el-auto-resizer>
          </div>
          <div class="pagination-wrapper">
            <el-pagination
              background
              layout="total, sizes, prev, pager, next"
              :total="rapidRisePage.total"
              :page-size="rapidRisePage.pageSize"
              :page-sizes="PAGE_SIZE_OPTIONS"
              :current-page="rapidRisePage.pageNum"
              @current-change="handleRapidRisePageChange"
              @size-change="handleRapidRiseSizeChange"
            />
          </div>
        </el-card>
      </el-col>
      <el-col :xs="24" :sm="12">
        <el-card shadow="never">
          <template #header>
            <div class="card-header">
              <el-tag type="info" size="small">温度抖动异常（按小时）</el-tag>
              <HelpButton title="温度抖动异常" :content="ANOMALY_HELP" />
            </div>
          </template>
          <el-table :data="jitterList" stripe size="small" max-height="320">
            <el-table-column prop="monitorName" label="测点" show-overflow-tooltip />
            <el-table-column prop="avgTemp" label="小时均温" width="90" align="right">
              <template #default="{ row }">
                <span>{{ row.avgTemp?.toFixed(2) ?? '-' }}℃</span>
              </template>
            </el-table-column>
            <el-table-column prop="tempStddev" label="标准差" width="80" align="right">
              <template #default="{ row }">
                <span class="text-purple-500 font-bold">{{ row.tempStddev?.toFixed(4) }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="statTime" label="时段" width="160" />
          </el-table>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { h, ref, reactive, onMounted } from 'vue';
import {
  getHighTempEvents,
  getLowTempEvents,
  getContinuousHighTemp,
  getRapidRiseEvents,
  getJitterAnomalies
} from '@/api/ems/report/tempBoard';
import type { TempBoardQuery, TempBoardAnomalyVO } from '@/api/ems/report/tempBoard';
import HelpButton from '../components/HelpButton.vue';
import { ANOMALY_HELP } from '../components/helpContent';

defineOptions({ name: 'TempBoardAnomaly' });

type PageState = {
  pageNum: number;
  pageSize: number;
  total: number;
};

const timeRange = ref<[string, string]>(['', '']);
const queryForm = reactive<TempBoardQuery>({
  highTempThreshold: 35,
  lowTempThreshold: 10,
  rapidRiseThreshold: 1.0,
  stddevThreshold: 2.0,
  continuousMinSamples: 2
});
const loading = ref(false);
const highTempList = ref<TempBoardAnomalyVO[]>([]);
const lowTempList = ref<TempBoardAnomalyVO[]>([]);
const continuousList = ref<TempBoardAnomalyVO[]>([]);
const rapidRiseList = ref<TempBoardAnomalyVO[]>([]);
const jitterList = ref<TempBoardAnomalyVO[]>([]);
const highTempPage = reactive<PageState>({ pageNum: 1, pageSize: 20, total: 0 });
const lowTempPage = reactive<PageState>({ pageNum: 1, pageSize: 20, total: 0 });
// 温升过快同样启用分页，避免 10 测点 × 高频触发场景下的 DOM 爆炸。
const rapidRisePage = reactive<PageState>({ pageNum: 1, pageSize: 20, total: 0 });

// 与框架常见分页区间保持一致，预先导出便于跳转到质量页、规格对齐。
const PAGE_SIZE_OPTIONS = [20, 50, 100];

function buildEventColumns(textColor: string) {
  return [
    {
      key: 'monitorName',
      dataKey: 'monitorName',
      title: '测点',
      width: 220
    },
    {
      key: 'temperature',
      dataKey: 'temperature',
      title: '温度',
      width: 120,
      align: 'right',
      cellRenderer: ({ cellData }: { cellData: number }) =>
        h('span', { class: `font-bold ${textColor}` }, `${cellData?.toFixed(2) ?? '-'}℃`)
    },
    {
      key: 'collectTime',
      dataKey: 'collectTime',
      title: '时间',
      width: 180
    }
  ];
}

const highTempColumns: any[] = buildEventColumns('text-red-500');
const lowTempColumns: any[] = buildEventColumns('text-blue-500');

// 温升过快列：虚拟滚动下手动拼 cellRenderer，保持与普通表一致的视觉。
const rapidRiseColumns: any[] = [
  { key: 'monitorName', dataKey: 'monitorName', title: '测点', width: 220 },
  {
    key: 'risePerMin',
    dataKey: 'risePerMin',
    title: '温升速率',
    width: 120,
    align: 'right',
    cellRenderer: ({ cellData }: { cellData: number }) =>
      h('span', { class: 'text-orange-500 font-bold' }, cellData != null ? cellData.toFixed(2) : '-')
  },
  { key: 'collectTime', dataKey: 'collectTime', title: '时间', width: 180 }
];

/** 初始化默认时间范围：昨天8:30 ~ 今天8:30 */
function initTimeRange() {
  const now = new Date();
  const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 8, 30, 0);
  const start = new Date(end.getTime() - 24 * 3600 * 1000);
  const p = (n: number) => n.toString().padStart(2, '0');
  const fmt = (d: Date) =>
    `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
  timeRange.value = [fmt(start), fmt(end)];
}

function syncTimeRange() {
  if (timeRange.value?.[0]) {
    queryForm.startTime = timeRange.value[0];
    queryForm.endTime = timeRange.value[1];
  }
}

async function loadHighTempList() {
  const { data } = await getHighTempEvents({
    ...queryForm,
    pageNum: highTempPage.pageNum,
    pageSize: highTempPage.pageSize
  });
  highTempList.value = data.rows;
  highTempPage.total = data.total;
}

async function loadLowTempList() {
  const { data } = await getLowTempEvents({
    ...queryForm,
    pageNum: lowTempPage.pageNum,
    pageSize: lowTempPage.pageSize
  });
  lowTempList.value = data.rows;
  lowTempPage.total = data.total;
}

async function loadRapidRiseList() {
  // 温升过快独立接口：走分页，翻页时不触发连续高温/抖动的重拉。
  const { data } = await getRapidRiseEvents({
    ...queryForm,
    pageNum: rapidRisePage.pageNum,
    pageSize: rapidRisePage.pageSize
  });
  rapidRiseList.value = data.rows;
  rapidRisePage.total = data.total;
}

async function loadOtherSections() {
  const [continuousRes, jitterRes] = await Promise.all([
    getContinuousHighTemp(queryForm),
    getJitterAnomalies(queryForm)
  ]);
  continuousList.value = continuousRes.data;
  jitterList.value = jitterRes.data;
}

async function handleQuery() {
  syncTimeRange();
  highTempPage.pageNum = 1;
  lowTempPage.pageNum = 1;
  // 切换查询条件时所有分页明细都回到首页，避免旧 offset 越界成空结果。
  rapidRisePage.pageNum = 1;
  loading.value = true;
  try {
    // 各自独立接口，翻页时只重拉对应表，不会把连续高温 / 抖动等聚合接口一起重跑。
    await Promise.all([
      loadHighTempList(),
      loadLowTempList(),
      loadRapidRiseList(),
      loadOtherSections()
    ]);
  } finally {
    loading.value = false;
  }
}

async function handleHighTempPageChange(page: number) {
  highTempPage.pageNum = page;
  syncTimeRange();
  await loadHighTempList();
}

async function handleHighTempSizeChange(size: number) {
  // 改每页条数后回到第一页，避免 offset 超出总数后空数据。
  highTempPage.pageSize = size;
  highTempPage.pageNum = 1;
  syncTimeRange();
  await loadHighTempList();
}

async function handleLowTempPageChange(page: number) {
  lowTempPage.pageNum = page;
  syncTimeRange();
  await loadLowTempList();
}

async function handleLowTempSizeChange(size: number) {
  lowTempPage.pageSize = size;
  lowTempPage.pageNum = 1;
  syncTimeRange();
  await loadLowTempList();
}

async function handleRapidRisePageChange(page: number) {
  rapidRisePage.pageNum = page;
  syncTimeRange();
  await loadRapidRiseList();
}

async function handleRapidRiseSizeChange(size: number) {
  rapidRisePage.pageSize = size;
  rapidRisePage.pageNum = 1;
  syncTimeRange();
  await loadRapidRiseList();
}

onMounted(() => {
  initTimeRange();
  handleQuery();
});
</script>

<style scoped>
.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.kpi-card {
  text-align: center;
}

.kpi-danger :deep(.el-statistic__number) {
  color: #f56c6c;
}

.kpi-primary :deep(.el-statistic__number) {
  color: #409eff;
}

.kpi-warning :deep(.el-statistic__number) {
  color: #e6a23c;
}

.kpi-purple :deep(.el-statistic__number) {
  color: #9b59b6;
}

.table-v2-wrapper {
  height: 500px;
}

.table-v2-wrapper-sm {
  /* 温升过快在两列布局里与右侧抖动表视觉对齐；太高会挤压页脚分页。 */
  height: 320px;
}

.pagination-wrapper {
  display: flex;
  justify-content: flex-end;
  margin-top: 12px;
}
</style>
