<template>
  <div class="w-full h-100">
    <v-chart v-if="hasData" class="w-full h-full" :option="option" autoresize />
    <div
      v-else
      class="w-full h-full flex items-center justify-center text-gray-500"
    >
      暂无数据
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed } from "vue";
import { forEach } from "lodash";
import VChart from "vue-echarts";
import { useOscilloscopeState } from "./OscilloscopeManager";

// Echarts
import { use } from "echarts/core";
import { LineChart } from "echarts/charts";
import {
  TooltipComponent,
  LegendComponent,
  ToolboxComponent,
  DataZoomComponent,
  GridComponent,
} from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";
import type { ComposeOption } from "echarts/core";
import type { LineSeriesOption } from "echarts/charts";
import type {
  TooltipComponentOption,
  LegendComponentOption,
  ToolboxComponentOption,
  DataZoomComponentOption,
  GridComponentOption,
} from "echarts/components";
import { useRequiredInjection } from "@/utils/Common";

use([
  TooltipComponent,
  LegendComponent,
  ToolboxComponent,
  DataZoomComponent,
  GridComponent,
  LineChart,
  CanvasRenderer,
]);

type EChartsOption = ComposeOption<
  | TooltipComponentOption
  | LegendComponentOption
  | ToolboxComponentOption
  | DataZoomComponentOption
  | GridComponentOption
  | LineSeriesOption
>;

// 使用 manager 获取 oscilloscope 数据
const { oscData } = useRequiredInjection(useOscilloscopeState);

const hasData = computed(() => {
  return (
    oscData.value &&
    oscData.value.x &&
    oscData.value.y &&
    oscData.value.x.length > 0 &&
    (
      Array.isArray(oscData.value.y[0])
        ? oscData.value.y.some((channel: any) => channel.length > 0)
        : oscData.value.y.length > 0
    )
  );
});

const option = computed((): EChartsOption => {
  if (!oscData.value || !oscData.value.x || !oscData.value.y) {
    return {};
  }

  const series: LineSeriesOption[] = [];

  // 兼容单通道和多通道，确保 yChannels 为 number[][]
  const yChannels: number[][] = Array.isArray(oscData.value.y[0])
    ? (oscData.value.y as number[][])
    : [oscData.value.y as number[]];

  forEach(yChannels, (yData, index) => {
    if (!oscData.value || !yData) return;
    const seriesData = oscData.value.x.map((xValue, i) => [
      xValue,
      yData && yData[i] !== undefined ? yData[i] : 0,
    ]);
    series.push({
      type: "line",
      name: `通道 ${index + 1}`,
      data: seriesData,
      smooth: false,
      symbol: "none",
      lineStyle: {
        width: 2,
      },
    });
  });

  return {
    grid: {
      left: "10%",
      right: "10%",
      top: "15%",
      bottom: "25%",
    },
    tooltip: {
      trigger: "axis",
      formatter: (params: any) => {
        if (!oscData.value) return "";
        let result = `时间: ${params[0].data[0].toFixed(2)} ${oscData.value.xUnit}<br/>`;
        params.forEach((param: any) => {
          result += `${param.seriesName}: ${param.data[1].toFixed(3)} ${oscData.value?.yUnit ?? ""}<br/>`;
        });
        return result;
      },
    },
    legend: {
      top: "5%",
      data: series.map((s) => s.name) as string[],
    },
    toolbox: {
      feature: {
        restore: {},
        saveAsImage: {},
      },
    },
    dataZoom: [
      {
        type: "inside",
        start: 0,
        end: 100,
      },
      {
        start: 0,
        end: 100,
      },
    ],
    xAxis: {
      type: "value",
      name: oscData.value ? `时间 (${oscData.value.xUnit})` : "时间",
      nameLocation: "middle",
      nameGap: 30,
      axisLine: {
        show: true,
      },
      axisTick: {
        show: true,
      },
      splitLine: {
        show: false,
      },
    },
    yAxis: {
      type: "value",
      name: oscData.value ? `电压 (${oscData.value.yUnit})` : "电压",
      nameLocation: "middle",
      nameGap: 40,
      axisLine: {
        show: true,
      },
      axisTick: {
        show: true,
      },
      splitLine: {
        show: false,
      },
    },
    series: series,
  };
});
</script>
