<template>
  <div v-loading="loading" class="app-container displacement-board-page">
    <DisplacementBoardFilter
      :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="setDisplacementParam"
      @query="handleQuery"
    />

    <el-row :gutter="16" class="mt-4 displacement-grid">
      <el-col :xs="24" :lg="7" :xl="6">
        <DisplacementBoardDeviceTree :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="bandTip" />

        <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="ADVANCED_HELP" />
                </div>
              </template>
              <div ref="sankeyChartRef" class="chart-container-xl" />
        </el-card>

        <el-row :gutter="16" class="mt-4 displacement-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="ADVANCED_HELP" />
                </div>
              </template>
              <div ref="treemapChartRef" 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 { getDisplacementAdvancedData, type DisplacementAdvancedPageVO } from '@/api/ems/report/displacementBoard';
import HelpButton from '../components/DisplacementHelpButton.vue';
import DisplacementBoardFilter from '../components/DisplacementBoardFilter.vue';
import DisplacementBoardDeviceTree from '../components/DisplacementBoardDeviceTree.vue';
import { ADVANCED_HELP } from '../components/helpContent';
import { useChartResize } from '../components/useChartResize';
import { useDisplacementBoardQueryState } from '../components/useDisplacementBoardQueryState';
import { toNumber, displacementMetricOptions } from '../components/displacementBoardShared';

defineOptions({ name: 'DisplacementBoardAdvanced' });

const sankeyChartRef = ref<HTMLElement>();
const treemapChartRef = ref<HTMLElement>();
const parallelChartRef = ref<HTMLElement>();
const { getChart } = useChartResize(sankeyChartRef, treemapChartRef, parallelChartRef);

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

const advancedData = ref<DisplacementAdvancedPageVO>({
  sankeyNodes: [],
  sankeyLinks: [],
  treemapItems: [],
  parallelAxes: [],
  parallelSeries: []
});

const riskBandColorMap: Record<string, string> = {
  高位: '#ef4444',
  关注: '#f59e0b',
  平稳: '#10b981'
};

const bandTip = computed(() => {
  const lowBandUpper = advancedData.value.lowBandUpper;
  const focusBandUpper = advancedData.value.focusBandUpper;
  if (lowBandUpper === undefined || focusBandUpper === undefined) {
    return '高级分析会根据当前位移指标的风险分带，对设备群做迁移与占比分析。';
  }
  return `当前风险分带建议：平稳 ≤ ${lowBandUpper}，关注区 ≤ ${focusBandUpper}，其上视为高位。`;
});

const getNodeColor = (name?: string) => {
  if (!name) {
    return '#5b8ff9';
  }
  if (name.includes('高')) {
    return riskBandColorMap['高位'];
  }
  if (name.includes('关注') || name.includes('预警')) {
    return riskBandColorMap['关注'];
  }
  return riskBandColorMap['平稳'];
};

const renderCharts = () => {
  const sankeyChart = getChart(sankeyChartRef);
  const treemapChart = getChart(treemapChartRef);
  const parallelChart = getChart(parallelChartRef);
  const sankeyNodes = advancedData.value.sankeyNodes || [];
  const sankeyLinks = advancedData.value.sankeyLinks || [];
  const treemapItems = advancedData.value.treemapItems || [];
  const parallelAxes = advancedData.value.parallelAxes || [];
  const parallelSeries = advancedData.value.parallelSeries || [];

  if (sankeyChart) {
    if (!sankeyNodes.length || !sankeyLinks.length) {
      sankeyChart.clear();
    } else {
      sankeyChart.setOption(
        {
          tooltip: {
            trigger: 'item',
            formatter: (params: any) => {
              if (params.dataType === 'edge') {
                return `${params.data.source} → ${params.data.target}<br/>流量: <b>${params.data.value}</b>`;
              }
              return `${params.name}`;
            }
          },
          series: [
            {
              type: 'sankey',
              left: 16,
              right: 24,
              top: 24,
              bottom: 16,
              nodeGap: 26,
              emphasis: { focus: 'adjacency' },
              data: sankeyNodes.map((item) => ({
                name: item.name,
                itemStyle: { color: getNodeColor(item.name) }
              })),
              links: sankeyLinks.map((item) => ({
                source: item.source,
                target: item.target,
                value: toNumber(item.value)
              })),
              lineStyle: {
                color: 'gradient',
                curveness: 0.52,
                opacity: 0.5
              },
              label: { color: '#334155', fontSize: 12 }
            }
          ]
        },
        true
      );
    }
  }

  if (treemapChart) {
    if (!treemapItems.length) {
      treemapChart.clear();
    } else {
      treemapChart.setOption(
        {
          tooltip: {
            formatter: (params: any) =>
              `${params.name}<br/>值: <b>${Number(params.value).toFixed(2)}</b><br/>风险带: <b>${params.data.levelTag || '--'}</b>`
          },
          series: [
            {
              type: 'treemap',
              roam: false,
              breadcrumb: { show: false },
              visibleMin: 8,
              data: treemapItems.map((item) => ({
                name: item.name,
                value: toNumber(item.value),
                levelTag: item.levelTag,
                itemStyle: {
                  color: riskBandColorMap[item.levelTag || ''] || '#5b8ff9',
                  borderColor: '#fff',
                  borderWidth: 2,
                  gapWidth: 2
                }
              })),
              upperLabel: { show: false },
              label: {
                show: true,
                color: '#fff',
                formatter: (params: any) => `${params.name}\n${Number(params.value).toFixed(1)}`
              }
            }
          ]
        },
        true
      );
    }
  }

  if (parallelChart) {
    if (!parallelAxes.length || !parallelSeries.length) {
      parallelChart.clear();
      return;
    }
    parallelChart.setOption(
      {
        color: [...displacementMetricOptions.map((item) => item.color), '#8b5cf6', '#64748b'] as string[],
        tooltip: {
          trigger: 'item'
        },
        legend: {
          type: 'scroll',
          top: 8,
          data: parallelSeries.map((item) => item.monitorName || item.monitorId || '--'),
          textStyle: { color: '#475569' }
        },
        parallelAxis: parallelAxes.map((item) => ({
          dim: toNumber(item.dim),
          name: item.name,
          max: Math.max(toNumber(item.max), 1),
          nameLocation: 'end',
          nameGap: 18,
          axisLabel: { color: '#64748b' }
        })),
        parallel: {
          left: 52,
          right: 24,
          top: 64,
          bottom: 42,
          parallelAxisDefault: {
            type: 'value',
            axisLine: { lineStyle: { color: '#cbd5e1' } },
            axisTick: { show: false },
            splitLine: { lineStyle: { type: 'dashed', color: 'rgba(148, 163, 184, 0.3)' } }
          }
        },
        series: parallelSeries.map((item) => ({
          name: item.monitorName || item.monitorId || '--',
          type: 'parallel',
          smooth: 0.2,
          lineStyle: { width: 1.6, opacity: 0.42 },
          emphasis: { lineStyle: { width: 3, opacity: 0.95 } },
          data: [(item.values || []).map((value) => toNumber(value))]
        }))
      },
      true
    );
  }
};

const handleQuery = async () => {
  loading.value = true;
  try {
    const { data } = await getDisplacementAdvancedData(buildQuery());
    advancedData.value = data || {
      sankeyNodes: [],
      sankeyLinks: [],
      treemapItems: [],
      parallelAxes: [],
      parallelSeries: []
    };
    await nextTick();
    renderCharts();
  } finally {
    loading.value = false;
  }
};

onMounted(() => {
  void Promise.all([loadTree(), handleQuery()]);
});
</script>

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



