<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-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="DISTRIBUTION_HELP" />
                </div>
              </template>
              <div ref="intervalChartRef" 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="DISTRIBUTION_HELP" />
                </div>
              </template>
              <div ref="histogramChartRef" class="chart-container-lg" />
            </el-card>
          </el-col>
        </el-row>

        <el-card shadow="never" class="chart-card mt-4">
          <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="DISTRIBUTION_HELP" />
            </div>
          </template>
          <div ref="calendarChartRef" class="chart-container" />
        </el-card>

        <el-card shadow="never" class="chart-card mt-4">
          <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="DISTRIBUTION_HELP" />
            </div>
          </template>
          <div ref="hourlyChartRef" class="chart-container-xl" />
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import * as echarts from 'echarts';
import { getDisplacementDistributionData as getVibrationDistributionData, type VibrationDistributionPageVO } from '@/api/ems/report/displacementBoard';
import HelpButton from '../components/HelpButton.vue';
import VibrationBoardFilter from '../components/VibrationBoardFilter.vue';
import VibrationBoardDeviceTree from '../components/VibrationBoardDeviceTree.vue';
import { DISTRIBUTION_HELP } from '../components/helpContent';
import { useChartResize } from '../components/useChartResize';
import { useVibrationBoardQueryState } from '../components/useVibrationBoardQueryState';
import { getVibrationMetricOption, toNumber, vibrationHeatmapColors } from '../components/vibrationBoardShared';

defineOptions({ name: 'VibrationBoardDistribution' });

const intervalChartRef = ref<HTMLElement>();
const histogramChartRef = ref<HTMLElement>();
const calendarChartRef = ref<HTMLElement>();
const hourlyChartRef = ref<HTMLElement>();
const { getChart } = useChartResize(intervalChartRef, histogramChartRef, calendarChartRef, hourlyChartRef);

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

const distributionData = ref<VibrationDistributionPageVO>({
  intervalBuckets: [],
  histogramBuckets: [],
  calendarHeatmap: [],
  hourlyHeatmap: []
});
const activeMetric = computed(() => getVibrationMetricOption(distributionData.value.metricField || queryForm.value.vibrationParam));

const clearCharts = () => {
  getChart(intervalChartRef)?.clear();
  getChart(histogramChartRef)?.clear();
  getChart(calendarChartRef)?.clear();
  getChart(hourlyChartRef)?.clear();
};

const renderCharts = () => {
  const intervalChart = getChart(intervalChartRef);
  const histogramChart = getChart(histogramChartRef);
  const calendarChart = getChart(calendarChartRef);
  const hourlyChart = getChart(hourlyChartRef);
  const unit = distributionData.value.unit || activeMetric.value.unit;
  const intervalData = distributionData.value.intervalBuckets || [];
  const histogramData = distributionData.value.histogramBuckets || [];
  const calendarData = (distributionData.value.calendarHeatmap || []).map((item) => [item.statDate, toNumber(item.avgValue)]);
  const hourlyData = (distributionData.value.hourlyHeatmap || []).map((item) => [toNumber(item.statHour), item.statDate, toNumber(item.avgValue)]);
  const days = [...new Set(hourlyData.map((item) => item[1] as string))].sort();

  if (!intervalData.length && !histogramData.length && !calendarData.length && !hourlyData.length) {
    // 空结果必须立即清图，否则用户会误以为上一轮查询结果仍然有效。
    clearCharts();
    return;
  }

  if (intervalChart && intervalData.length) {
    intervalChart.setOption(
      {
        color: ['#0ea5a4', '#38bdf8', '#60a5fa', '#facc15', '#fb923c', '#ef4444'],
        tooltip: {
          trigger: 'item',
          formatter: (params: any) => `${params.name}<br/>样本数: <b>${params.value}</b><br/>占比: <b>${params.percent}%</b>`
        },
        legend: {
          type: 'scroll',
          orient: 'vertical',
          left: 8,
          top: 'middle',
          textStyle: { color: '#475569' }
        },
        series: [
          {
            name: '区间分布',
            type: 'pie',
            radius: ['42%', '72%'],
            center: ['64%', '50%'],
            roseType: 'radius',
            itemStyle: {
              borderRadius: 8,
              borderColor: '#fff',
              borderWidth: 2
            },
            label: { formatter: '{b}\n{d}%', color: '#334155' },
            data: intervalData.map((item) => ({ name: item.label, value: toNumber(item.count) }))
          }
        ]
      },
      true
    );
  }

  if (histogramChart && histogramData.length) {
    histogramChart.setOption(
      {
        color: [activeMetric.value.color],
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'shadow' },
          formatter: (params: any[]) => `${params[0].axisValue}<br/>样本数: <b>${params[0].value}</b>`
        },
        grid: { left: 56, right: 24, top: 24, bottom: 56 },
        xAxis: {
          type: 'category',
          data: histogramData.map((item) => `${toNumber(item.startValue).toFixed(1)}~${toNumber(item.endValue).toFixed(1)}`),
          axisLabel: { rotate: 28, color: '#475569' }
        },
        yAxis: {
          type: 'value',
          name: '样本数',
          splitLine: { lineStyle: { type: 'dashed', color: 'rgba(148, 163, 184, 0.35)' } },
          axisLabel: { color: '#64748b' }
        },
        series: [
          {
            name: '样本数',
            type: 'bar',
            barMaxWidth: 28,
            data: histogramData.map((item) => toNumber(item.count)),
            itemStyle: {
              borderRadius: [8, 8, 0, 0],
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: activeMetric.value.color },
                { offset: 1, color: `${activeMetric.value.color}26` }
              ])
            }
          }
        ]
      },
      true
    );
  }

  if (calendarChart && calendarData.length) {
    const values = calendarData.map((item) => item[1] as number);
    calendarChart.setOption(
      {
        tooltip: {
          formatter: (params: any) => `${params.value[0]}<br/>日均值: <b>${Number(params.value[1]).toFixed(2)} ${unit}</b>`
        },
        visualMap: {
          min: Math.min(...values),
          max: Math.max(...values),
          calculable: true,
          orient: 'horizontal',
          left: 'center',
          bottom: 0,
          textStyle: { color: '#475569' },
          inRange: { color: vibrationHeatmapColors }
        },
        calendar: {
          top: 24,
          left: 24,
          right: 24,
          cellSize: ['auto', 26],
          range: [calendarData[0][0], calendarData[calendarData.length - 1][0]],
          splitLine: { show: false },
          itemStyle: { borderRadius: 4, borderWidth: 2, borderColor: '#fff' },
          yearLabel: { show: false },
          dayLabel: { color: '#64748b' },
          monthLabel: { color: '#334155' }
        },
        series: [
          {
            type: 'heatmap',
            coordinateSystem: 'calendar',
            data: calendarData
          }
        ]
      },
      true
    );
  }

  if (hourlyChart && hourlyData.length) {
    const values = hourlyData.map((item) => item[2] as number);
    hourlyChart.setOption(
      {
        tooltip: {
          formatter: (params: any) =>
            `${params.value[1]} ${String(params.value[0]).padStart(2, '0')}:00<br/>平均值: <b>${Number(params.value[2]).toFixed(2)} ${unit}</b>`
        },
        grid: { left: 90, right: 24, top: 24, bottom: 70 },
        xAxis: {
          type: 'category',
          data: Array.from({ length: 24 }, (_, index) => `${index.toString().padStart(2, '0')}:00`),
          splitArea: { show: true },
          axisLabel: { color: '#475569' }
        },
        yAxis: {
          type: 'category',
          data: days,
          splitArea: { show: true },
          axisLabel: { color: '#475569' }
        },
        visualMap: {
          min: Math.min(...values),
          max: Math.max(...values),
          calculable: true,
          orient: 'horizontal',
          left: 'center',
          bottom: 8,
          textStyle: { color: '#475569' },
          inRange: { color: vibrationHeatmapColors }
        },
        series: [
          {
            name: '小时热力',
            type: 'heatmap',
            data: hourlyData,
            emphasis: {
              itemStyle: {
                shadowBlur: 14,
                shadowColor: 'rgba(15, 23, 42, 0.18)'
              }
            },
            itemStyle: { borderRadius: 2, borderColor: '#fff', borderWidth: 1 }
          }
        ]
      },
      true
    );
  }
};

const handleQuery = async () => {
  loading.value = true;
  try {
    const { data } = await getVibrationDistributionData(buildQuery());
    distributionData.value = data || {
      intervalBuckets: [],
      histogramBuckets: [],
      calendarHeatmap: [],
      hourlyHeatmap: []
    };
    await nextTick();
    renderCharts();
  } finally {
    loading.value = false;
  }
};

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

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