<template>
  <div v-loading="loading" class="app-container report-workbench">
    <section class="hero-panel">
      <div class="hero-main">
        <div>
          <p class="hero-eyebrow">Hawei Plus Report Center</p>
          <h2>{{ pageTitle }}</h2>
          <p class="hero-desc">{{ pageSubtitle }}</p>
        </div>
        <div class="hero-actions">
          <el-button size="small" @click="goBack">返回</el-button>
          <el-button type="primary" size="small" icon="el-icon-refresh" @click="handleQuery">刷新报表</el-button>
        </div>
      </div>

      <div class="hero-metrics">
        <div class="metric-card">
          <span class="metric-label">分析范围</span>
          <strong class="metric-value">{{ selectionSummary }}</strong>
          <p class="metric-hint">{{ energySelectionSummary }}</p>
        </div>
        <div class="metric-card">
          <span class="metric-label">分析对象</span>
          <strong class="metric-value metric-text">{{ analysisObjectValue }}</strong>
          <p class="metric-hint">{{ analysisObjectFoot }}</p>
        </div>
        <div class="metric-card">
          <span class="metric-label">对比设备</span>
          <strong class="metric-value">{{ deviceCount }}</strong>
          <p class="metric-hint">{{ deviceSelectionSummary }}</p>
        </div>
        <div class="metric-card">
          <span class="metric-label">活跃指标</span>
          <strong class="metric-value">{{ metricConfigs.length }}</strong>
          <p class="metric-hint">{{ metricDescription }}</p>
        </div>
      </div>
    </section>

    <section class="glass-panel query-panel">
      <div class="panel-heading">
        <div>
          <p class="panel-eyebrow">Hawei Plus Query</p>
          <h3>分析筛选区</h3>
        </div>
      </div>

      <el-form class="query-form" :inline="true" :model="queryForm" size="small" label-width="86px">
        <el-form-item label="分组选择">
          <el-checkbox-group v-model="selectedScopeKeys" @change="handleScopeChange">
            <el-checkbox-button v-for="item in availableScopeOptions" :key="item.key" :label="item.key">
              {{ item.label }}<span class="scope-count">({{ item.deviceCount }})</span>
            </el-checkbox-button>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="范围名称">
          <el-input v-model="queryForm.selectionLabel" style="width: 240px" readonly />
        </el-form-item>
        <el-form-item label="记录时间">
          <el-date-picker
            v-model="daterangeRecordTime"
            type="datetimerange"
            value-format="yyyy-MM-dd HH:mm:ss"
            range-separator="-"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            style="width: 340px"
          />
        </el-form-item>
        <el-form-item label="采样间隔">
          <el-input-number v-model="queryForm.samplingInterval" :min="1" :max="1440" controls-position="right" style="width: 122px" />
          <span class="form-suffix">分钟/点</span>
        </el-form-item>
        <el-form-item label="主看指标">
          <el-select v-model="queryForm.primaryMetricField" style="width: 200px" placeholder="自动识别主看指标">
            <el-option v-for="item in availablePrimaryMetricOptions" :key="item.key" :label="item.label" :value="item.key" />
          </el-select>
        </el-form-item>
      </el-form>
    </section>

    <section class="glass-panel selector-panel">
      <div class="panel-heading">
        <div>
          <p class="panel-eyebrow">Hawei Plus Scope</p>
          <h3>设备范围树</h3>
        </div>
        <div class="selector-tags">
          <el-tag size="small" effect="plain">{{ monitorTypeLabel }}</el-tag>
          <el-tag size="small" effect="plain">覆盖率 {{ formatPercent(coverageRatio) }}</el-tag>
        </div>
      </div>

      <div v-loading="treeLoading" class="tree-panel">
        <el-tree
          node-key="id"
          :data="filteredMonitorTreeOptions"
          :props="treeProps"
          default-expand-all
          highlight-current
          :expand-on-click-node="false"
          :current-node-key="currentTreeNodeId"
          @node-click="handleTreeNodeClick"
        />
      </div>
    </section>

    <section class="glass-panel logic-panel">
      <div class="panel-heading">
        <div>
          <p class="panel-eyebrow">Hawei Plus Logic</p>
          <h3>统计口径说明</h3>
        </div>
      </div>
      <div class="logic-grid">
        <div v-for="item in logicCards" :key="item.title" class="logic-card">
          <div class="logic-title">{{ item.title }}</div>
          <p class="logic-desc">{{ item.desc }}</p>
        </div>
      </div>
    </section>

    <div v-if="metricCards.length" class="metric-grid">
      <div v-for="item in metricCards" :key="item.key" class="metric-summary-card" :style="{ borderTopColor: item.color }">
        <div class="metric-name">{{ item.label }}</div>
        <div class="metric-number">
          {{ formatValue(item.latest) }}<span>{{ item.unit }}</span>
        </div>
        <div class="metric-foot">均值 {{ formatValue(item.avg) }}{{ item.unit }}</div>
        <div class="metric-foot">峰值 {{ formatValue(item.max) }}{{ item.unit }}</div>
      </div>
    </div>

    <div v-if="!reportReady" class="empty-panel">
      <el-empty description="当前选择范围在该时间窗口内暂无可分析数据，请调整时间或设备范围后重试。" />
    </div>

    <template v-else>
      <template v-if="mode === 'trend'">
        <div class="chart-grid two-col">
          <article class="chart-card">
            <div class="chart-head">
              <h4>趋势总览</h4>
              <p>{{ hasMultiDevice ? '按主看指标对重点设备做走势比较' : '按多指标回看单设备时间序列波动' }}</p>
            </div>
            <Chart class="chart chart-lg" :chart-option="trendOption" />
          </article>

          <article class="chart-card">
            <div class="chart-head">
              <h4>指标仪表盘</h4>
              <p>{{ hasMultiDevice ? '聚焦群组均值、峰值与最新均值' : '聚焦关键指标当前状态' }}</p>
            </div>
            <Chart class="chart chart-lg" :chart-option="gaugeOption" />
          </article>
        </div>

        <div class="chart-grid one-col">
          <article class="chart-card">
            <div class="chart-head">
              <h4>雷达轮廓图</h4>
              <p>{{ hasMultiDevice ? '观察群组均值与峰值边界' : '观察单设备最新值与峰值边界' }}</p>
            </div>
            <Chart class="chart chart-md" :chart-option="radarOption" />
          </article>
        </div>
      </template>

      <template v-else-if="mode === 'quality'">
        <div class="chart-grid two-col">
          <article class="chart-card">
            <div class="chart-head">
              <h4>流向分析图</h4>
              <p>{{ hasMultiDevice ? '观察设备落入平稳、关注、高位区间的分布' : '观察指标落入不同状态区间的分布' }}</p>
            </div>
            <Chart class="chart chart-lg" :chart-option="sankeyOption" />
          </article>

          <article class="chart-card">
            <div class="chart-head">
              <h4>漏斗筛选图</h4>
              <p>{{ hasMultiDevice ? '快速锁定高风险设备' : '快速锁定高风险采样点' }}</p>
            </div>
            <Chart class="chart chart-lg" :chart-option="funnelOption" />
          </article>
        </div>

        <div class="chart-grid two-col">
          <article class="chart-card">
            <div class="chart-head">
              <h4>数据覆盖率</h4>
              <p>判断当前分析窗口的数据完整度与可用性</p>
            </div>
            <Chart class="chart chart-md" :chart-option="liquidOption" />
          </article>

          <article class="chart-card">
            <div class="chart-head">
              <h4>小时均值图</h4>
              <p>帮助定位波动集中的时间段</p>
            </div>
            <Chart class="chart chart-md" :chart-option="hourlyOption" />
          </article>
        </div>
      </template>

      <template v-else>
        <el-alert
          v-if="!hasMultiDevice"
          type="info"
          :closable="false"
          show-icon
          title="设备对比报表建议选择设备组或多个顶层分组，这样排名与散点图更有业务价值。"
          class="page-alert"
        />

        <div class="chart-grid two-col">
          <article class="chart-card">
            <div class="chart-head">
              <h4>设备趋势对比</h4>
              <p>对主看指标的重点设备走势做横向比对</p>
            </div>
            <Chart class="chart chart-lg" :chart-option="trendOption" />
          </article>

          <article class="chart-card">
            <div class="chart-head">
              <h4>设备排名图</h4>
              <p>按主看指标的均值和最新值综合衡量设备状态</p>
            </div>
            <Chart class="chart chart-lg" :chart-option="deviceRankOption" />
          </article>
        </div>

        <div class="chart-grid one-col">
          <article class="chart-card">
            <div class="chart-head">
              <h4>设备散点图</h4>
              <p>同时观察设备均值、峰值与采样量，适合快速找出高波动设备</p>
            </div>
            <Chart class="chart chart-md" :chart-option="deviceScatterOption" />
          </article>
        </div>
      </template>
    </template>
  </div>
</template>

<script setup lang="ts">
import Chart from '@/components/Charts/Chart.vue';
import type { EChartsOption } from 'echarts';
import { readMetricValue } from '../iotCurveShared';
import {
  average,
  ceilNumber,
  getBands,
  normalizePercent,
  useIotReportWorkbench
} from '../iotReportShared';

const props = defineProps<{
  mode: 'trend' | 'quality' | 'device';
  pageTitle: string;
  pageSubtitle: string;
}>();

const router = useRouter();

const {
  analysisObjectFoot,
  analysisObjectValue,
  availablePrimaryMetricOptions,
  availableScopeOptions,
  coverageRatio,
  currentTreeNodeId,
  daterangeRecordTime,
  deviceCount,
  deviceStats,
  deviceSelectionSummary,
  energySelectionSummary,
  filteredMonitorTreeOptions,
  formatPercent,
  formatValue,
  getMetricStats,
  getMetricValues,
  getShortDisplayName,
  handleQuery,
  handleScopeChange,
  handleTreeNodeClick,
  hasMultiDevice,
  initialize,
  loading,
  metricCards,
  metricConfigs,
  metricDescription,
  monitorTypeLabel,
  primaryMetric,
  queryForm,
  rawRecords,
  reportReady,
  selectedScopeKeys,
  selectionSummary,
  treeLoading
} = useIotReportWorkbench();

const treeProps = {
  label: 'label',
  children: 'children'
};

const logicCards = computed(() => {
  const primaryMetricLabel = primaryMetric.value?.label || '主看指标';
  if (props.mode === 'quality') {
    return [
      {
        title: '覆盖率口径',
        desc: `覆盖率 = 当前窗口内全部有效指标值数量 / 理论采样格数量。理论采样格数量由“采样记录数 x 活跃指标数”得到，完全基于本次真实返回数据计算。`
      },
      {
        title: '流向分层口径',
        desc: `流向图把 ${primaryMetricLabel} 或当前活跃指标的真实值按 33% 与 66% 分位拆成“平稳 / 关注 / 高位”三层，不使用人工模拟值。`
      },
      {
        title: '漏斗筛选口径',
        desc: `漏斗图基于 ${primaryMetricLabel} 的真实分布，按均值、P75、P90 逐层筛选，目的是识别高位样本或高位设备占比。`
      }
    ];
  }
  if (props.mode === 'device') {
    return [
      {
        title: '设备排名口径',
        desc: `设备排名以 ${primaryMetricLabel} 在所选时间窗口内的均值降序排列，同时展示最新值，避免只看单个瞬时点导致判断失真。`
      },
      {
        title: '散点图口径',
        desc: `设备散点图 X 轴是 ${primaryMetricLabel} 均值，Y 轴是峰值，气泡大小是采样量，三者全部来自所选窗口内的真实采样记录。`
      },
      {
        title: '趋势对比口径',
        desc: `设备趋势图按统一时间轴对比重点设备的真实采样轨迹，缺失点保持为空，不做虚构插值。`
      }
    ];
  }
  return [
    {
      title: '趋势总览口径',
      desc: hasMultiDevice.value
        ? `趋势图按 ${primaryMetricLabel} 对重点设备做同一时间窗口对比，所有折线都来自真实采样时间与真实采样值。`
        : `趋势图展示当前设备在所选窗口内的真实采样轨迹，多指标并列展示，不使用静态示例数据。`
    },
    {
      title: '仪表盘口径',
      desc: hasMultiDevice.value
        ? `仪表盘分别展示 ${primaryMetricLabel} 的群组均值、群组峰值和最新均值，用于快速判断设备组总体状态。`
        : `仪表盘展示当前窗口内核心指标的最新值，并按该指标真实峰值自动计算量程上限。`
    },
    {
      title: '雷达图口径',
      desc: `雷达图把当前活跃指标归一到 0~100，单设备模式比较“最新值 vs 峰值”，多设备模式比较“群组均值 vs 峰值”。`
    }
  ];
});

const buildSeriesTimeAxis = () => Array.from(new Set(rawRecords.value.map((item) => item.__timeKey).filter((item) => item)));

const buildMetricSeriesData = (metric, monitorId = '') => {
  const valueMap = rawRecords.value.reduce(
    (accumulator, item) => {
      const currentMonitorId = String(item.monitorId || item.monitorCode || '');
      if (monitorId && currentMonitorId !== monitorId) {
        return accumulator;
      }
      const metricValue = readMetricValue(item, metric);
      if (metricValue !== null && item.__timeKey) {
        accumulator[item.__timeKey] = metricValue;
      }
      return accumulator;
    },
    {} as Record<string, number>
  );

  return buildSeriesTimeAxis().map((timeKey) => {
    return Object.prototype.hasOwnProperty.call(valueMap, timeKey) ? valueMap[timeKey] : null;
  });
};

const trendOption = computed<EChartsOption | null>(() => {
  if (!reportReady.value || !primaryMetric.value) {
    return null;
  }

  const timeAxis = buildSeriesTimeAxis();
  if (hasMultiDevice.value) {
    const topDevices = deviceStats.value.slice(0, 6);
    return {
      tooltip: {
        trigger: 'axis'
      },
      legend: {
        top: 8,
        data: topDevices.map((item) => getShortDisplayName(item.monitorId))
      },
      grid: {
        top: 54,
        left: '7%',
        right: '4%',
        bottom: 48
      },
      dataZoom: [
        {
          type: 'slider',
          height: 16
        }
      ],
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: timeAxis
      },
      yAxis: {
        type: 'value',
        name: primaryMetric.value.unit ? `${primaryMetric.value.label}(${primaryMetric.value.unit})` : primaryMetric.value.label,
        splitLine: {
          lineStyle: {
            type: 'dashed'
          }
        }
      },
      series: topDevices.map((item) => ({
        name: getShortDisplayName(item.monitorId),
        type: 'line',
        smooth: true,
        connectNulls: true,
        showSymbol: false,
        data: buildMetricSeriesData(primaryMetric.value, item.monitorId)
      }))
    };
  }

  const metrics = metricConfigs.value.slice(0, 3);
  return {
    color: metrics.map((item) => item.color),
    tooltip: {
      trigger: 'axis'
    },
    legend: {
      top: 8,
      data: metrics.map((item) => item.label)
    },
    grid: {
      top: 54,
      left: '7%',
      right: '4%',
      bottom: 48
    },
    dataZoom: [
      {
        type: 'slider',
        height: 16
      }
    ],
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: timeAxis
    },
    yAxis: {
      type: 'value',
      splitLine: {
        lineStyle: {
          type: 'dashed'
        }
      }
    },
    series: metrics.map((item) => ({
      name: item.label,
      type: 'line',
      smooth: true,
      connectNulls: true,
      showSymbol: false,
      areaStyle: {
        opacity: 0.08
      },
      data: buildMetricSeriesData(item)
    }))
  };
});

const gaugeOption = computed<EChartsOption | null>(() => {
  if (!reportReady.value || !primaryMetric.value) {
    return null;
  }

  if (hasMultiDevice.value) {
    const stats = getMetricStats(primaryMetric.value);
    const latestAverage = average(deviceStats.value.map((item) => item.latest));
    const maxValue = Math.max(1, ceilNumber((stats.max || 1) * 1.15));
    const gaugeData = [
      { label: '群组均值', value: stats.avg || 0, center: ['20%', '55%'], color: primaryMetric.value.color },
      { label: '群组峰值', value: stats.max || 0, center: ['50%', '55%'], color: '#36cfc9' },
      { label: '最新均值', value: latestAverage, center: ['80%', '55%'], color: '#5b8ff9' }
    ];
    return {
      series: gaugeData.map((item) => ({
        type: 'gauge',
        min: 0,
        max: maxValue,
        radius: '78%',
        center: item.center,
        progress: {
          show: true,
          width: 12,
          itemStyle: {
            color: item.color
          }
        },
        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: (value) => `${formatValue(value)} ${primaryMetric.value?.unit || ''}`
        },
        data: [{ value: item.value, name: item.label }]
      }))
    };
  }

  const gaugeMetrics = metricConfigs.value.slice(0, 3);
  const centers =
    gaugeMetrics.length <= 1 ? [['50%', '55%']] : gaugeMetrics.length === 2 ? [['30%', '55%'], ['70%', '55%']] : [['18%', '55%'], ['50%', '55%'], ['82%', '55%']];

  return {
    series: gaugeMetrics.map((item, index) => {
      const stats = getMetricStats(item);
      const latest = stats.latest || 0;
      const maxValue = Math.max(1, ceilNumber((stats.max || latest || 1) * 1.15));
      return {
        type: 'gauge',
        min: 0,
        max: maxValue,
        radius: '78%',
        center: centers[index],
        progress: {
          show: true,
          width: 12,
          itemStyle: {
            color: item.color
          }
        },
        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: (value) => `${formatValue(value)} ${item.unit}`
        },
        data: [{ value: latest, name: item.label }]
      };
    })
  };
});

const radarOption = computed<EChartsOption | null>(() => {
  if (!reportReady.value || !metricConfigs.value.length) {
    return null;
  }
  const metrics = metricConfigs.value.slice(0, 5);
  const indicator = metrics.map((item) => ({ name: item.label, max: 100 }));
  const compareA = metrics.map((item) => {
    const stats = getMetricStats(item);
    return normalizePercent(hasMultiDevice.value ? stats.avg : stats.latest, stats.max);
  });
  const compareB = metrics.map((item) => {
    const stats = getMetricStats(item);
    return normalizePercent(stats.max, stats.max);
  });

  return {
    legend: {
      bottom: 0,
      data: [hasMultiDevice.value ? '群组均值' : '最新值', '峰值上限']
    },
    radar: {
      radius: '60%',
      indicator,
      splitArea: {
        areaStyle: {
          color: ['rgba(91,143,249,0.08)', 'rgba(91,143,249,0.14)']
        }
      }
    },
    series: [
      {
        type: 'radar',
        data: [
          {
            name: hasMultiDevice.value ? '群组均值' : '最新值',
            value: compareA,
            areaStyle: { opacity: 0.18 }
          },
          {
            name: '峰值上限',
            value: compareB,
            areaStyle: { opacity: 0.08 }
          }
        ]
      }
    ]
  };
});

const sankeyOption = computed<EChartsOption | null>(() => {
  if (!reportReady.value || !primaryMetric.value) {
    return null;
  }

  const stageNames = ['平稳', '关注', '高位'];
  if (hasMultiDevice.value) {
    const bands = getBands(getMetricValues(primaryMetric.value));
    const topDevices = deviceStats.value.slice(0, 10);
    return {
      tooltip: { trigger: 'item' },
      series: [
        {
          type: 'sankey',
          left: 12,
          right: 12,
          top: 16,
          bottom: 16,
          emphasis: { focus: 'adjacency' },
          lineStyle: { color: 'gradient', curveness: 0.5 },
          data: topDevices
            .map((item) => ({ name: item.monitorName }))
            .concat(stageNames.map((stage) => ({ name: stage }))),
          links: topDevices.map((item) => ({
            source: item.monitorName,
            target: item.avg <= bands.low ? '平稳' : item.avg <= bands.high ? '关注' : '高位',
            value: item.count
          }))
        }
      ]
    };
  }

  const nodes = [{ name: '采样点' }];
  const links = [] as Array<Record<string, unknown>>;
  metricConfigs.value.forEach((metric) => {
    const values = getMetricValues(metric);
    if (!values.length) {
      return;
    }
    const bands = getBands(values);
    const stageCounter = { 平稳: 0, 关注: 0, 高位: 0 };
    values.forEach((value) => {
      if (value <= bands.low) {
        stageCounter.平稳 += 1;
      } else if (value <= bands.high) {
        stageCounter.关注 += 1;
      } else {
        stageCounter.高位 += 1;
      }
    });
    nodes.push({ name: metric.label });
    links.push({ source: '采样点', target: metric.label, value: values.length });
    stageNames.forEach((stage) => {
      links.push({ source: metric.label, target: stage, value: stageCounter[stage] });
    });
  });

  return {
    tooltip: { trigger: 'item' },
    series: [
      {
        type: 'sankey',
        left: 12,
        right: 12,
        top: 16,
        bottom: 16,
        emphasis: { focus: 'adjacency' },
        lineStyle: { color: 'gradient', curveness: 0.5 },
        data: nodes.concat(stageNames.map((stage) => ({ name: stage }))),
        links
      }
    ]
  };
});

const funnelOption = computed<EChartsOption | null>(() => {
  if (!reportReady.value || !primaryMetric.value) {
    return null;
  }

  if (hasMultiDevice.value) {
    const averages = deviceStats.value.map((item) => item.avg);
    const bands = getBands(averages);
    return {
      tooltip: { trigger: 'item', formatter: '{b}: {c}' },
      series: [
        {
          type: 'funnel',
          left: '12%',
          width: '76%',
          top: 18,
          bottom: 16,
          label: { show: true, position: 'inside' },
          data: [
            { name: '纳入对比设备', value: deviceStats.value.length },
            { name: '均值高于整体均值', value: deviceStats.value.filter((item) => item.avg >= bands.avg).length },
            { name: '进入设备P75', value: deviceStats.value.filter((item) => item.avg >= bands.p75).length },
            { name: '进入设备P90', value: deviceStats.value.filter((item) => item.avg >= bands.p90).length }
          ]
        }
      ]
    };
  }

  const values = getMetricValues(primaryMetric.value);
  const bands = getBands(values);
  return {
    tooltip: { trigger: 'item', formatter: '{b}: {c}' },
    series: [
      {
        type: 'funnel',
        left: '12%',
        width: '76%',
        top: 18,
        bottom: 16,
        label: { show: true, position: 'inside' },
        data: [
          { name: '有效采样', value: values.length },
          { name: '高于均值', value: values.filter((item) => item >= bands.avg).length },
          { name: '进入P75', value: values.filter((item) => item >= bands.p75).length },
          { name: '进入P90', value: values.filter((item) => item >= bands.p90).length }
        ]
      }
    ]
  };
});

const liquidOption = computed<any>(() => {
  const ratio = Number(coverageRatio.value.toFixed(4));
  return {
    series: [
      {
        type: 'liquidFill',
        radius: '74%',
        data: [ratio, Math.max(ratio - 0.08, 0), Math.max(ratio - 0.16, 0)],
        color: ['#36cfc9', '#13c2c2', '#08979c'],
        outline: {
          borderDistance: 4,
          itemStyle: {
            borderWidth: 3,
            borderColor: '#36cfc9'
          }
        },
        label: {
          formatter: `${formatPercent(ratio)}\n覆盖率`,
          fontSize: 20,
          color: '#135200'
        }
      }
    ]
  };
});

const hourlyOption = computed<EChartsOption | null>(() => {
  if (!reportReady.value || !primaryMetric.value) {
    return null;
  }
  const hourMap = {} as Record<string, number[]>;
  rawRecords.value.forEach((item) => {
    const metricValue = readMetricValue(item, primaryMetric.value!);
    if (metricValue === null || !item.__timeKey) {
      return;
    }
    const hour = item.__timeKey.slice(11, 13);
    if (!hourMap[hour]) {
      hourMap[hour] = [];
    }
    hourMap[hour].push(metricValue);
  });
  const hours = Object.keys(hourMap).sort();
  return {
    color: [primaryMetric.value.color],
    tooltip: { trigger: 'axis' },
    grid: {
      top: 20,
      left: '9%',
      right: '4%',
      bottom: 36
    },
    xAxis: {
      type: 'category',
      data: hours
    },
    yAxis: {
      type: 'value',
      splitLine: {
        lineStyle: {
          type: 'dashed'
        }
      }
    },
    series: [
      {
        type: 'bar',
        barWidth: 18,
        data: hours.map((hour) => average(hourMap[hour])),
        itemStyle: {
          borderRadius: [6, 6, 0, 0]
        }
      }
    ]
  };
});

const deviceRankOption = computed<EChartsOption | null>(() => {
  if (!reportReady.value || !primaryMetric.value) {
    return null;
  }
  const topDevices = deviceStats.value.slice(0, 10);
  return {
    tooltip: { trigger: 'axis' },
    legend: {
      top: 8,
      data: ['均值', '最新值']
    },
    grid: {
      top: 56,
      left: '12%',
      right: '6%',
      bottom: 36
    },
    xAxis: { type: 'value' },
    yAxis: {
      type: 'category',
      data: topDevices.map((item) => getShortDisplayName(item.monitorId))
    },
    series: [
      {
        name: '均值',
        type: 'bar',
        data: topDevices.map((item) => item.avg),
        itemStyle: { color: primaryMetric.value.color }
      },
      {
        name: '最新值',
        type: 'bar',
        data: topDevices.map((item) => item.latest),
        itemStyle: { color: '#36cfc9' }
      }
    ]
  };
});

const deviceScatterOption = computed<EChartsOption | null>(() => {
  if (!reportReady.value || !primaryMetric.value) {
    return null;
  }
  return {
    tooltip: {
      formatter: (params) => {
        const value = params.value;
        return [
          `设备: ${value[3]}`,
          `编码: ${value[4]}`,
          `均值: ${formatValue(value[0])}${primaryMetric.value?.unit || ''}`,
          `峰值: ${formatValue(value[1])}${primaryMetric.value?.unit || ''}`,
          `采样量: ${value[2]}`
        ].join('<br/>');
      }
    },
    xAxis: {
      type: 'value',
      name: `${primaryMetric.value.label}均值(${primaryMetric.value.unit || '--'})`,
      splitLine: {
        lineStyle: {
          type: 'dashed'
        }
      }
    },
    yAxis: {
      type: 'value',
      name: `${primaryMetric.value.label}峰值(${primaryMetric.value.unit || '--'})`,
      splitLine: {
        lineStyle: {
          type: 'dashed'
        }
      }
    },
    series: [
      {
        type: 'scatter',
        symbolSize: (value) => Math.max(12, Math.min(30, value[2] * 2)),
        itemStyle: {
          color: primaryMetric.value.color,
          opacity: 0.8
        },
        label: {
          show: true,
          formatter: (params) => params.value[3],
          position: 'top',
          fontSize: 11
        },
        data: deviceStats.value.slice(0, 12).map((item) => [item.avg, item.max, item.count, getShortDisplayName(item.monitorId), item.monitorId])
      }
    ]
  };
});

const goBack = () => {
  router.back();
};

onMounted(() => {
  void initialize();
});
</script>

<style scoped>
.report-workbench {
  min-height: calc(100vh - 84px);
  background:
    radial-gradient(circle at top right, rgba(59, 130, 246, 0.12), transparent 24%),
    radial-gradient(circle at top left, rgba(20, 184, 166, 0.1), transparent 28%),
    linear-gradient(180deg, #f3f8ff 0%, #f8fafc 100%);
}

.hero-panel,
.glass-panel {
  border-radius: 24px;
  border: 1px solid rgba(148, 163, 184, 0.18);
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(12px);
  box-shadow: 0 18px 48px rgba(15, 23, 42, 0.08);
}

.hero-panel {
  padding: 24px;
  margin-bottom: 18px;
  background:
    linear-gradient(135deg, rgba(15, 118, 110, 0.96), rgba(37, 99, 235, 0.92)),
    linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0));
  color: #ffffff;
}

.hero-main,
.hero-metrics,
.chart-grid {
  display: grid;
}

.hero-main {
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  align-items: start;
}

.hero-eyebrow,
.panel-eyebrow {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.hero-eyebrow {
  color: rgba(255, 255, 255, 0.72);
}

.hero-panel h2,
.panel-heading h3,
.chart-head h4 {
  margin: 0;
}

.hero-desc {
  max-width: 860px;
  margin: 14px 0 0;
  line-height: 1.75;
  color: rgba(255, 255, 255, 0.84);
}

.hero-actions,
.selector-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.hero-actions {
  justify-content: flex-end;
}

.hero-metrics {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin-top: 24px;
}

.metric-card {
  padding: 16px 18px;
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.18);
}

.metric-label {
  display: block;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.72);
}

.metric-value {
  display: block;
  margin-top: 10px;
  font-size: 22px;
  font-weight: 700;
}

.metric-text {
  font-size: 18px;
}

.metric-hint {
  margin: 10px 0 0;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.78);
  line-height: 1.55;
}

.glass-panel {
  padding: 18px 20px;
  margin-bottom: 18px;
}

.panel-heading {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}

.panel-eyebrow {
  color: #2563eb;
}

.query-form :deep(.el-form-item) {
  margin-right: 18px;
}

.form-suffix,
.scope-count {
  margin-left: 6px;
  color: #64748b;
}

.tree-panel {
  max-height: 280px;
  overflow: auto;
  padding: 12px 10px;
  border-radius: 16px;
  background: linear-gradient(180deg, #fafcff 0%, #f5f8ff 100%);
}

.metric-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 18px;
}

.logic-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}

.logic-card {
  padding: 16px;
  border-radius: 18px;
  border: 1px solid rgba(226, 232, 240, 0.92);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(248, 250, 252, 0.94)),
    linear-gradient(135deg, rgba(37, 99, 235, 0.05), rgba(20, 184, 166, 0.04));
}

.logic-title {
  color: #0f172a;
  font-size: 15px;
  font-weight: 700;
}

.logic-desc {
  margin: 10px 0 0;
  color: #64748b;
  line-height: 1.7;
  font-size: 13px;
}

.metric-summary-card {
  padding: 16px 18px;
  border-radius: 20px;
  border: 1px solid rgba(226, 232, 240, 0.95);
  border-top: 4px solid #2563eb;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(248, 250, 252, 0.94));
  box-shadow: 0 16px 40px rgba(15, 23, 42, 0.06);
}

.metric-name {
  color: #64748b;
  font-size: 13px;
}

.metric-number {
  margin-top: 12px;
  color: #0f172a;
  font-size: 26px;
  font-weight: 700;
}

.metric-number span {
  margin-left: 6px;
  font-size: 14px;
  color: #64748b;
}

.metric-foot {
  margin-top: 8px;
  color: #64748b;
  font-size: 12px;
}

.empty-panel {
  padding: 48px 16px;
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(226, 232, 240, 0.95);
}

.chart-grid {
  gap: 16px;
  margin-bottom: 18px;
}

.two-col {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.one-col {
  grid-template-columns: 1fr;
}

.chart-card {
  padding: 16px;
  border-radius: 24px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(248, 250, 252, 0.94)),
    linear-gradient(135deg, rgba(37, 99, 235, 0.06), rgba(20, 184, 166, 0.05));
  border: 1px solid rgba(226, 232, 240, 0.9);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.8),
    0 18px 48px rgba(37, 99, 235, 0.06);
}

.chart-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 12px;
}

.chart-head p {
  margin: 4px 0 0;
  color: #64748b;
  font-size: 12px;
  max-width: 320px;
  line-height: 1.6;
}

.chart {
  width: 100%;
  border-radius: 18px;
}

.chart-lg {
  height: 48vh;
  min-height: 360px;
}

.chart-md {
  height: 42vh;
  min-height: 320px;
}

.page-alert {
  margin-bottom: 16px;
}

@media (max-width: 1400px) {
  .hero-metrics,
  .metric-grid,
  .logic-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 992px) {
  .hero-main,
  .two-col {
    grid-template-columns: 1fr;
  }

  .hero-actions {
    justify-content: flex-start;
  }
}

@media (max-width: 768px) {
  .hero-panel,
  .glass-panel,
  .chart-card {
    padding: 16px;
    border-radius: 20px;
  }

  .hero-metrics,
  .metric-grid,
  .logic-grid {
    grid-template-columns: 1fr;
  }

  .chart-lg,
  .chart-md {
    height: 38vh;
    min-height: 280px;
  }
}
</style>
