<script setup lang="ts">
const src = computed(() => `${import.meta.env.BASE_URL}iframe/for-plotly.html`);

type I数据 = number[];
type WindowWithPlotly = Window & {
  Plotly: typeof import('plotly.js-dist-min');
};

const iframeRef = useTemplateRef<HTMLIFrameElement>('iframeRef');
let contentWindow: null | WindowWithPlotly = null;

let 频谱图Element: import('plotly.js-dist-min').PlotlyHTMLElement | null = null;
let 瀑布图Element: import('plotly.js-dist-min').PlotlyHTMLElement | null = null;

let _readyPromiseReslove: () => void;
const readyPromise = new Promise<void>((resolve) => {
  _readyPromiseReslove = resolve;
});

const 频谱瀑布图Layout = {
  title: { text: '频谱瀑布图' },
  xaxis: {
    title: { text: '频率 (Hz)' },
    // range: [0, 22_050],
    showgrid: false,
    tickformat: ',d', // 设置为带逗号的整数格式 (推荐，更易读)
  },
  yaxis: {
    title: { text: '时间步' },
    showgrid: false,
    tickformat: ',d', // 设置为带逗号的整数格式 (推荐，更易读)
  },
  margin: { l: 60, r: 40, b: 40, t: 60 },
} satisfies Partial<import('plotly.js-dist-min').Layout>;

const 频谱图Layout = {
  title: { text: '频谱图' },
  xaxis: {
    title: { text: '频率 (Hz)' },
    // range: [0, 22_050],
    showgrid: true,
    gridcolor: '#eee',
    tickformat: ',d', // 设置为带逗号的整数格式 (推荐，更易读)
  },
  yaxis: {
    title: { text: '幅度 (dB)' },
    showgrid: true, // 显示网格线
    gridcolor: '#eee',
    tickformat: ',d', // 设置为带逗号的整数格式 (推荐，更易读)
  },
  margin: { l: 60, r: 40, b: 40, t: 60 },
} satisfies Partial<import('plotly.js-dist-min').Layout>;

// 存储瀑布图数据的数组，限制最大行数以避免内存问题
const 瀑布图数据: number[][] = [];
const 最大时间步 = 50; // 减少时间步长以避免画布大小超出限制
const 数据缩减因子 = 10; // 每10个数据点取平均值以减少数据量

// 辅助函数：对数据进行缩减处理
function 缩减数据(数据: number[]): number[] {
  const 缩减后数据: number[] = [];
  for (let i = 0; i < 数据.length; i += 数据缩减因子) {
    const 片段 = 数据.slice(i, i + 数据缩减因子);
    const 平均值 = 片段.reduce((sum, val) => sum + val, 0) / 片段.length;
    缩减后数据.push(平均值);
  }
  return 缩减后数据;
}

defineExpose({
  添加数据: async (DB数据: I数据, FFT大小: number /* 也叫快速傅里叶变换大小 */, 采样率: number) => {
    const 频率分辨率 = 采样率 / FFT大小;
    await readyPromise;

    {
      // 频谱图
      console.debug('[添加数据被调用]', `数据.length :>> `, DB数据.length);
      // 先清空之前的数据
      await contentWindow!.Plotly.react(频谱图Element!, [], 频谱图Layout);
      const x频率数据 = Array.from({ length: DB数据.length }, (_, i) => i * 频率分辨率);
      await contentWindow!.Plotly.addTraces(频谱图Element!, {
        x: x频率数据,
        y: DB数据,
        type: 'scatter',
        line: { color: 'blue' },
        hovertemplate: '频率: %{x:,d} Hz<br>幅度: %{y:.2f} dB<extra></extra>', // 自定义悬停文本
      });
    }

    {
      // 瀑布图
      // 对数据进行缩减处理
      const 缩减后DB数据 = 缩减数据([...DB数据]);
      console.debug(`缩减后DB数据.length :>> `, 缩减后DB数据.length);
      // 将新数据添加到瀑布图数据数组的顶部
      瀑布图数据.unshift(缩减后DB数据);
      // 限制数组长度
      if (瀑布图数据.length > 最大时间步) {
        瀑布图数据.pop();
      }
      // 准备热图数据
      const x频率数据 = Array.from({ length: 缩减后DB数据.length }, (_, i) => i * 频率分辨率 * 数据缩减因子);
      const y时间步数据 = Array.from({ length: 瀑布图数据.length }, (_, i) => 瀑布图数据.length - 1 - i);
      // 更新瀑布图
      await contentWindow!.Plotly.react(
        瀑布图Element!,
        [
          {
            z: 瀑布图数据,
            x: x频率数据,
            y: y时间步数据,
            type: 'heatmap',
            colorscale: 'Viridis', // 颜色映射，可以根据需要调整
            showscale: true, // 显示颜色条
            hovertemplate: '时间步: %{y}<br>频率: %{x:,d} Hz<br>幅度: %{z:.2f} dB<extra></extra>', // 自定义悬停文本
          },
        ],
        频谱瀑布图Layout,
      );
    }
  },
});

async function onIframeLoad() {
  console.debug('[onIframeLoad] iframe 加载完成');
  contentWindow = iframeRef.value!.contentWindow as WindowWithPlotly;
  频谱图Element = await contentWindow.Plotly.newPlot('PLOTLY_CHART_spectrogram', [], 频谱图Layout);
  瀑布图Element = await contentWindow.Plotly.newPlot('PLOTLY_CHART_waterfall', [], 频谱瀑布图Layout);
  _readyPromiseReslove();
}
onMounted(() => {
  console.debug('[onMounted] comp 加载完成');
});
</script>

<template>
  <iframe ref="iframeRef" @load="onIframeLoad" :src style="width: 100%; height: 100%; border: none" />
</template>
