<script setup lang="ts">
import type { ReportIndicatorModel } from '@/model';

import type { LineSeriesOption } from 'echarts/charts';
import { LineChart }             from 'echarts/charts';

import type {
  GridComponentOption,
  LegendComponentOption,
  MarkLineComponentOption,
  TitleComponentOption,
  TooltipComponentOption,
} from 'echarts/components';
import {
  GridComponent,
  LegendComponent,
  MarkLineComponent,
  TitleComponent,
  TooltipComponent,
  VisualMapComponent,
} from 'echarts/components';


import { use }            from 'echarts/core';
import { CanvasRenderer } from 'echarts/renderers';
import VChart             from 'vue-echarts';


use([
  CanvasRenderer,
  LineChart, MarkLineComponent,
  GridComponent, VisualMapComponent,
  TitleComponent, TooltipComponent, LegendComponent,
]);


const props = defineProps<{
  dataset: ReportIndicatorModel;
  loading?: boolean;
}>();
const emits = defineEmits<{
  destroy: []
}>();

const option = ref({
  title: { text: '', top: 12, left: 'center' } as TitleComponentOption,
  tooltip: { trigger: 'axis' } as TooltipComponentOption,
  legend: { show: false, top: 12, right: 24 } as LegendComponentOption,
  grid: { top: 60, bottom: 24, left: 40, right: 60, containLabel: true } as GridComponentOption,
  xAxis: { type: 'category' } as any,
  yAxis: { type: 'value', scale: true, splitNumber: 10 } as any,
  visualMap: {
    pieces: [],
    show: false,
    type: 'piecewise',
  } as any,
  series: [] as ( LineSeriesOption & MarkLineComponentOption )[],

});
watchEffect(() => update(props.dataset));

function update(data: ReportIndicatorModel | undefined | null) {
  if (!data || !Array.isArray((data as any).range) || !Array.isArray((data as any).records)) {
    option.value.title.text = '';
    option.value.yAxis.name = '' as any;
    option.value.series = [];
    option.value.visualMap.pieces = [] as any;
    return;
  }
  const range = (data.range as any[]).map(t => +t);
  let min = Number.isFinite(range[0]) ? range[0] : 0;
  let max = Number.isFinite(range[1]) ? range[1] : 0;
  const records = [ ...data.records ].reverse();
  const source: any[] = [];
  for ( const { time, value } of records as any[] ) {
    const timeStr = typeof (time as any)?.format === 'function' ? (time as any).format('YYYY/MM/DD') : String(time ?? '');
    const numericValue = +value;
    source.push(timeStr, numericValue);
    if (Number.isFinite(numericValue)) {
      min = Math.min(min, numericValue);
      max = Math.max(max, numericValue);
    }
  }
  option.value.title.text = data.name ?? '';
  option.value.yAxis.name = (data as any).unit ?? '';
  const editor = (data as any).editor ?? {};
  const editorMin = Number.isFinite(+editor.min) ? +editor.min : min;
  const editorMax = Number.isFinite(+editor.max) ? +editor.max : max;
  option.value.yAxis.min = Math.max(editorMin, Math.floor((Number.isFinite(min) ? min : 0) * 0.75));
  option.value.yAxis.max = Math.min(editorMax, Math.floor((Number.isFinite(max) ? max : 0) * 1.25));
  option.value.yAxis.minInterval = editor.step ?? 1;
  if (range.length === 2 && range.every(v => Number.isFinite(v))) {
    option.value.visualMap.pieces = [
      { gt: range[ 1 ], color: '#fc97af' },
      { gte: range[ 0 ], lte: range[ 1 ], color: '#72ccff' },
      { lt: range[ 0 ], color: '#fc97af' },
    ] as any;
  } else {
    option.value.visualMap.pieces = [] as any;
  }
  option.value.series = [
    {
      name: data.name, smooth: true, type: 'line',
      data: (records as any[]).map((record) => [
        typeof record.time?.format === 'function' ? record.time.format('YYYY/MM/DD') : String(record.time ?? ''),
        +record.value,
      ]),
      markLine: {
        data: Array.isArray(data.range) ? (data.range as any[]).map(value => ({ yAxis: +value })) : [],
      },
    },
  ];
}
</script>
<template>
  <v-chart class="chart-container" :option="option" :autoresize="true" />
</template>
<style scoped lang="scss">
.chart-container {
  width: 100%;
  height: 100%;
}
</style>
