<template>
  <div v-loading="loading" class="app-container">
    <VibrationBoardFilter
      :selection-label="queryForm.selectionLabel"
      :time-range="daterangeRecordTime"
      :sampling-interval="queryForm.samplingInterval"
      :vibration-param="queryForm.vibrationParam"
      show-metric
      @update:time-range="setTimeRange"
      @update:sampling-interval="setSamplingInterval"
      @update:vibration-param="setVibrationParam"
      @query="handleQuery"
    />

    <el-row :gutter="16" class="mt-4">
      <el-col :span="6"
        ><el-card
          ><div class="kpi-label">采样记录数</div>
          <div class="kpi-value">{{ toNumber(overviewData.sampleCount) }}</div></el-card
        ></el-col
      >
      <el-col :span="6"
        ><el-card
          ><div class="kpi-label">设备数量</div>
          <div class="kpi-value">{{ toNumber(overviewData.deviceCount) }}</div></el-card
        ></el-col
      >
      <el-col :span="6"
        ><el-card
          ><div class="kpi-label">主看指标</div>
          <div class="kpi-value">{{ overviewData.metricLabel || '--' }}</div></el-card
        ></el-col
      >
      <el-col :span="6"
        ><el-card
          ><div class="kpi-label">覆盖率</div>
          <div class="kpi-value">{{ formatPercent(toNumber(overviewData.coverageRate)) }}</div></el-card
        ></el-col
      >
    </el-row>

    <el-row :gutter="16" class="mt-4">
      <el-col :span="6" v-for="item in overviewData.metricCards || []" :key="item.field">
        <el-card class="metric-card" :style="{ borderTopColor: metricColorMap[item.field || ''] || '#5b8ff9' }">
          <div class="kpi-label">{{ item.label }}</div>
          <div class="kpi-value">
            {{ formatValue(item.latest) }}<span class="unit">{{ item.unit }}</span>
          </div>
          <div class="metric-foot">均值 {{ formatValue(item.avg) }}{{ item.unit }}</div>
          <div class="metric-foot">峰值 {{ formatValue(item.max) }}{{ item.unit }}</div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="16" class="mt-4">
      <el-col :span="6">
        <VibrationBoardDeviceTree :loading="treeLoading" :tree-data="monitorTreeOptions" :tree-props="treeProps" @node-click="handleTreeNodeClick" />
      </el-col>
      <el-col :span="18">
        <el-row :gutter="16">
          <el-col :span="12"
            ><el-card><template #header>仪表盘总览</template><Chart ref="gaugeChart" class="chart-lg" /></el-card
          ></el-col>
          <el-col :span="12"
            ><el-card
              ><template #header>{{ hasMultiDevice ? '设备排名对比图' : '主看指标分布图' }}</template
              ><Chart ref="rankChart" class="chart-lg" /></el-card
          ></el-col>
        </el-row>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import Chart from '@/components/Charts/Chart.vue';
import { getVibrationOverviewData, type VibrationOverviewPageVO } from '@/api/ems/report/vibrationBoard';
import VibrationBoardFilter from '../components/VibrationBoardFilter.vue';
import VibrationBoardDeviceTree from '../components/VibrationBoardDeviceTree.vue';
import { useVibrationBoardQueryState } from '../components/useVibrationBoardQueryState';
import { vibrationMetricOptions } from '../components/vibrationBoardShared';

defineOptions({ name: 'VibrationBoardOverview' });

const gaugeChart = ref<any>();
const rankChart = ref<any>();
const {
  loading,
  treeLoading,
  monitorTreeOptions,
  treeProps,
  daterangeRecordTime,
  queryForm,
  deviceCount,
  hasMultiDevice,
  loadTree,
  handleTreeNodeClick,
  setTimeRange,
  setSamplingInterval,
  setVibrationParam,
  buildQuery
} = useVibrationBoardQueryState();
const overviewData = ref<VibrationOverviewPageVO>({ metricCards: [], gaugeItems: [], deviceRanks: [] });
const metricColorMap = Object.fromEntries(vibrationMetricOptions.map((item) => [item.field, item.color]));

const toNumber = (value: number | string | undefined) => Number(value ?? 0);
const formatValue = (value: number | string | undefined) => (value === null || value === undefined || value === '' ? '--' : Number(value).toFixed(2));
const formatPercent = (value: number) => `${(Number(value || 0) * 100).toFixed(1)}%`;

const renderCharts = () => {
  const gaugeItems = overviewData.value.gaugeItems || [];
  const deviceRanks = overviewData.value.deviceRanks || [];
  if (gaugeItems.length) {
    gaugeChart.value?.setData({
      series: gaugeItems.map((item, index) => ({
        type: 'gauge',
        min: 0,
        max: toNumber(item.maxValue),
        radius: '78%',
        center: [
          ['18%', '55%'],
          ['50%', '55%'],
          ['82%', '55%']
        ][index] || ['50%', '55%'],
        progress: { show: true, width: 12, itemStyle: { color: ['#5b8ff9', '#36cfc9', '#f59e0b'][index] || '#5b8ff9' } },
        axisLine: { lineStyle: { width: 12 } },
        pointer: { show: false },
        axisTick: { show: false },
        splitLine: { length: 10 },
        axisLabel: { distance: 16, fontSize: 10 },
        title: { offsetCenter: [0, '82%'], fontSize: 12 },
        detail: { offsetCenter: [0, '22%'], fontSize: 18, formatter: `${formatValue(item.value)} ${item.unit || ''}` },
        data: [{ value: toNumber(item.value), name: item.name }]
      }))
    });
  } else {
    // 空结果时同步清空仪表盘，避免 KPI 已回到空态但图表仍停留在上一轮查询。
    gaugeChart.value?.setData(null);
  }

  if (hasMultiDevice.value) {
    if (!deviceRanks.length) {
      rankChart.value?.setData(null);
      return;
    }
    rankChart.value?.setData({
      tooltip: { trigger: 'axis' },
      xAxis: { type: 'value' },
      yAxis: { type: 'category', data: deviceRanks.map((item) => item.monitorName) },
      series: [
        {
          type: 'bar',
          data: deviceRanks.map((item) => toNumber(item.avg)),
          itemStyle: { color: metricColorMap[queryForm.value.vibrationParam] || '#5b8ff9' }
        }
      ]
    });
    return;
  }

  const stats = overviewData.value.primaryMetricStats;
  if (!stats) {
    rankChart.value?.setData(null);
    return;
  }
  rankChart.value?.setData({
    xAxis: { type: 'category', data: ['最小值', '均值', '最大值'] },
    yAxis: { type: 'value', name: overviewData.value.unit || '' },
    series: [
      {
        type: 'bar',
        data: [toNumber(stats.min), toNumber(stats.avg), toNumber(stats.max)],
        itemStyle: { color: metricColorMap[queryForm.value.vibrationParam] || '#5b8ff9' }
      }
    ]
  });
};

const handleQuery = async () => {
  loading.value = true;
  try {
    const { data } = await getVibrationOverviewData(buildQuery());
    overviewData.value = data || { metricCards: [], gaugeItems: [], deviceRanks: [] };
    await nextTick();
    renderCharts();
  } finally {
    loading.value = false;
  }
};

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

<style scoped>
.kpi-label {
  color: #5b6573;
  font-size: 13px;
}
.kpi-value {
  margin-top: 12px;
  font-size: 26px;
  font-weight: 700;
  color: #1f2329;
}
.metric-card {
  border-top: 4px solid #5b8ff9;
}
.metric-foot {
  margin-top: 8px;
  font-size: 12px;
  color: #86909c;
}
.unit {
  margin-left: 4px;
  font-size: 14px;
}
.chart-lg {
  height: 420px;
}
</style>
