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

    <el-row :gutter="16" class="mt-4 vibration-grid">
      <el-col :xs="24" :lg="7" :xl="6">
        <VibrationBoardDeviceTree :loading="treeLoading" :tree-data="monitorTreeOptions" :tree-props="treeProps" @node-click="handleTreeNodeClick" />
      </el-col>
      <el-col :xs="24" :lg="17" :xl="18">
        <el-alert
          type="info"
          :closable="false"
          show-icon
          class="section-tip"
          title="对比分析建议选择设备组或全部位移设备，这样横向排名与散点聚类才更有参考价值。"
        />

        <el-row :gutter="16" class="vibration-grid">
          <el-col :xs="24" :xl="12">
            <el-card shadow="never" class="chart-card">
              <template #header>
                <div class="card-header">
                  <div class="card-title-group">
                    <div class="card-title">设备排名对比图</div>
                    <div class="card-subtitle">同时对比位移均值和最新值，适合快速筛出“当前状态已经偏离历史常态”的设备。</div>
                  </div>
                  <HelpButton title="设备排名对比图" :content="COMPARISON_HELP" />
                </div>
              </template>
              <div ref="rankChartRef" class="chart-container-lg" />
            </el-card>
          </el-col>
          <el-col :xs="24" :xl="12">
            <el-card shadow="never" class="chart-card">
              <template #header>
                <div class="card-header">
                  <div class="card-title-group">
                    <div class="card-title">设备散点图</div>
                    <div class="card-subtitle">横轴看均值，纵轴看峰值，气泡越大表示样本量越充足，判断更稳。</div>
                  </div>
                  <HelpButton title="设备散点图" :content="COMPARISON_HELP" />
                </div>
              </template>
              <div ref="scatterChartRef" class="chart-container-lg" />
            </el-card>
          </el-col>
        </el-row>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import * as echarts from 'echarts';
import { getDisplacementComparisonData as getVibrationComparisonData, type VibrationComparisonPageVO } from '@/api/ems/report/displacementBoard';
import HelpButton from '../components/HelpButton.vue';
import VibrationBoardFilter from '../components/VibrationBoardFilter.vue';
import VibrationBoardDeviceTree from '../components/VibrationBoardDeviceTree.vue';
import { COMPARISON_HELP } from '../components/helpContent';
import { useChartResize } from '../components/useChartResize';
import { useVibrationBoardQueryState } from '../components/useVibrationBoardQueryState';
import { buildCategoryDataZoom, getVibrationMetricOption, toNumber, vibrationMetricOptions } from '../components/vibrationBoardShared';

defineOptions({ name: 'VibrationBoardComparison' });

const rankChartRef = ref<HTMLElement>();
const scatterChartRef = ref<HTMLElement>();
const { getChart } = useChartResize(rankChartRef, scatterChartRef);

const {
  loading,
  treeLoading,
  monitorTreeOptions,
  treeProps,
  daterangeRecordTime,
  queryForm,
  loadTree,
  handleTreeNodeClick,
  setTimeRange,
  setSamplingInterval,
  setVibrationParam,
  buildQuery
} = useVibrationBoardQueryState();

const comparisonData = ref<VibrationComparisonPageVO>({ rankItems: [], scatterItems: [] });
const metricColorMap = Object.fromEntries(vibrationMetricOptions.map((item) => [item.field, item.color]));
const activeMetric = computed(() => getVibrationMetricOption(comparisonData.value.metricField || queryForm.value.vibrationParam));

const renderCharts = () => {
  const rankChart = getChart(rankChartRef);
  const scatterChart = getChart(scatterChartRef);
  const unit = comparisonData.value.unit || activeMetric.value.unit;
  const rankItems = comparisonData.value.rankItems || [];
  const scatterItems = comparisonData.value.scatterItems || [];
  const currentMetricColor = metricColorMap[comparisonData.value.metricField || queryForm.value.vibrationParam] || activeMetric.value.color;

  if (rankChart) {
    if (!rankItems.length) {
      rankChart.clear();
    } else {
      const categoryNames = rankItems.map((item) => item.monitorName || item.monitorId || '--');
      rankChart.setOption(
        {
          color: [currentMetricColor, '#36cfc9'],
          tooltip: {
            trigger: 'axis',
            axisPointer: { type: 'shadow' },
            formatter: (params: any[]) => {
              const rows = params.map((item) => `${item.marker}${item.seriesName}: <b>${Number(item.value).toFixed(2)} ${unit}</b>`);
              return [`<b>${params[0]?.name || '--'}</b>`, ...rows].join('<br/>');
            }
          },
          legend: {
            top: 8,
            data: ['均值', '最新值'],
            textStyle: { color: '#475569' }
          },
          grid: { left: 150, right: 28, top: 56, bottom: 20 },
          xAxis: {
            type: 'value',
            name: unit,
            splitLine: { lineStyle: { type: 'dashed', color: 'rgba(148, 163, 184, 0.35)' } },
            axisLabel: { color: '#64748b' }
          },
          yAxis: {
            type: 'category',
            data: categoryNames,
            axisLabel: { color: '#334155', width: 110, overflow: 'truncate' }
          },
          dataZoom: buildCategoryDataZoom(categoryNames.length),
          series: [
            {
              name: '均值',
              type: 'bar',
              barMaxWidth: 16,
              data: rankItems.map((item) => toNumber(item.avg)),
              itemStyle: {
                borderRadius: [0, 6, 6, 0],
                color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                  { offset: 0, color: currentMetricColor },
                  { offset: 1, color: `${currentMetricColor}55` }
                ])
              }
            },
            {
              name: '最新值',
              type: 'bar',
              barMaxWidth: 16,
              data: rankItems.map((item) => toNumber(item.latest)),
              itemStyle: {
                borderRadius: [0, 6, 6, 0],
                color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                  { offset: 0, color: '#36cfc9' },
                  { offset: 1, color: '#a7f3d0' }
                ])
              }
            }
          ]
        },
        true
      );
    }
  }

  if (scatterChart) {
    if (!scatterItems.length) {
      scatterChart.clear();
      return;
    }
    const sampleCounts = scatterItems.map((item) => toNumber(item.sampleCount));
    scatterChart.setOption(
      {
        tooltip: {
          formatter: (params: any) =>
            [
              `<b>${params.value[3]}</b>`,
              `均值: ${Number(params.value[0]).toFixed(2)} ${unit}`,
              `峰值: ${Number(params.value[1]).toFixed(2)} ${unit}`,
              `采样量: ${params.value[2]}`
            ].join('<br/>')
        },
        visualMap: {
          min: sampleCounts.length ? Math.min(...sampleCounts) : 0,
          max: sampleCounts.length ? Math.max(...sampleCounts) : 0,
          dimension: 2,
          orient: 'horizontal',
          left: 'center',
          bottom: 6,
          calculable: true,
          text: ['采样量高', '采样量低'],
          inRange: {
            symbolSize: [14, 42],
            color: ['#dbeafe', currentMetricColor]
          }
        },
        grid: { left: 60, right: 24, top: 24, bottom: 80 },
        xAxis: {
          type: 'value',
          name: `均值（${unit}）`,
          splitLine: { lineStyle: { type: 'dashed', color: 'rgba(148, 163, 184, 0.35)' } },
          axisLabel: { color: '#64748b' }
        },
        yAxis: {
          type: 'value',
          name: `峰值（${unit}）`,
          splitLine: { lineStyle: { type: 'dashed', color: 'rgba(148, 163, 184, 0.35)' } },
          axisLabel: { color: '#64748b' }
        },
        series: [
          {
            name: '设备散点',
            type: 'scatter',
            emphasis: { focus: 'series' },
            label: {
              show: true,
              position: 'top',
              color: '#334155',
              fontSize: 11,
              formatter: (params: any) => params.value[3]
            },
            itemStyle: {
              shadowBlur: 12,
              shadowColor: 'rgba(15, 23, 42, 0.14)'
            },
            data: scatterItems.map((item) => [
              toNumber(item.avg),
              toNumber(item.max),
              toNumber(item.sampleCount),
              item.monitorName || item.monitorId || '--'
            ])
          }
        ]
      },
      true
    );
  }
};

const handleQuery = async () => {
  loading.value = true;
  try {
    const { data } = await getVibrationComparisonData(buildQuery());
    comparisonData.value = data || { rankItems: [], scatterItems: [] };
    await nextTick();
    // 对比页经常在切换设备树后快速重复查询，这里统一在下一帧重绘，避免旧尺寸和旧图层残留。
    renderCharts();
  } finally {
    loading.value = false;
  }
};

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

<style scoped lang="scss">
@import '../components/vibrationBoardReport.scss';
</style>
