<template>
  <div class="dc-chart dc-simple-chart">
    <div v-if="title" class="dc-chart-title">{{ title }}</div>
    <div class="dc-chart-content" :style="{ minHeight: `${height}px` }">
      <Loading :visible="loading"></Loading>
      <template v-if="hasData">
        <BaseChart ref="baseChart" :option="chartOption" :height="height" :group="group"></BaseChart>
        <ChartLegend
          v-if="showLegend"
          simple
          :data="legendData"
          :chart-element="chartElement"
          :chart-type="type"
        ></ChartLegend>
      </template>
      <template v-else>
        <EmptyContent v-if="!loading" :empty_text="emptyText"></EmptyContent>
      </template>
    </div>
  </div>
</template>

<script>
/* eslint-disable no-restricted-syntax,no-param-reassign */

import Loading from '@/components/Loading.vue';
import BaseChart from '@/components/base-chart/BaseChart.vue';
import EmptyContent from '@/components/EmptyContent.vue';
import ChartLegend from '@/components/ChartLegend.vue';
import { colors, getRGBAColor, standardizeValue } from '@/utils';
import { cloneDeep } from 'lodash-es';
import { getSeries } from '@/components/base-chart/seriesOptions';
import {
  getYAxisOption,
  getGridOption,
  getTooltipOption,
  getMarkLineOption,
} from '@/components/base-chart/defaultOption';
import { getAxisFormatter, getSimpleTooltipFormatter } from '@/components/base-chart/formatters';
import { getInstanceByDom } from 'echarts/core';

export default {
  name: 'SimpleChart',
  components: { Loading, BaseChart, EmptyContent, ChartLegend },
  props: {
    type: {
      type: String,
      default: 'line',
    },
    title: {
      type: String,
    },
    height: {
      type: Number,
    },
    data: {
      type: Array,
      default: () => [],
    },
    option: {
      type: Object,
    },
    tooltipShowTotal: {
      type: Boolean,
      default: false,
    },
    emptyText: {
      type: String,
      default: '暂无数据',
    },
    markData: {
      type: Array,
    },
    showLegend: {
      type: Boolean,
      default: true,
    },
    loading: {
      type: Boolean,
      default: false,
    },
    group: {
      type: String,
    },
    fullscreen: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      chartElement: null,
    };
  },
  computed: {
    chart() {
      if (this.chartElement) {
        return getInstanceByDom(this.chartElement);
      }
      return null;
    },
    hasData() {
      return this.data?.length || this.option?.series?.some(x => x.data?.length);
    },
    chartOption() {
      if (!this.option) {
        return null;
      }
      const tooltipValueType = [];
      const tooltipValueDigit = [];
      const newOption = cloneDeep(this.option);
      const { series, yAxis, tooltip } = newOption;
      if (Array.isArray(yAxis)) {
        yAxis.forEach((item, i) => {
          yAxis[i] = getYAxisOption(item);
        });
        if (yAxis.name || yAxis.some(x => x.name)) {
          newOption.grid = getGridOption({ top: '32px' });
        }
      } else {
        newOption.yAxis = getYAxisOption(yAxis);
      }

      series.forEach((item, i) => {
        const { extra, ...option } = item;
        const color = colors[i % colors.length];
        option.itemStyle = { color, ...option.itemStyle };
        if (extra) {
          (Array.isArray(newOption.yAxis) ? newOption.yAxis[option.yAxisIndex] : newOption.yAxis).axisLabel.formatter =
            getAxisFormatter(extra.valueType);
          tooltipValueType[i] = extra.valueType;
          tooltipValueDigit[i] = extra.valueDigit;
          if (extra.showArea) {
            const areaColor = option.areaStyle?.color;
            // areaColor如果是对象，则不做处理
            if (typeof areaColor !== 'object') {
              option.areaStyle = {
                color: {
                  type: 'linear',
                  x: 0,
                  y: 0,
                  x2: 0,
                  y2: 1,
                  colorStops: [
                    {
                      offset: 0,
                      color: areaColor ?? getRGBAColor(option.itemStyle.color, 1),
                    },
                    {
                      offset: 1,
                      color: 'rgba(255, 255, 255, 1)',
                    },
                  ],
                },
              };
            }
          }
        }
        series[i] = getSeries(option.type, option);
      });
      if (this.markData && series[0]) {
        series[0].markLine = getMarkLineOption({
          data: this.markData,
        });
      }
      // 把数据中的-1转成0
      const source =
        this.data?.map(x => {
          const obj = { ...x };
          Object.entries(obj).forEach(([key, value]) => {
            obj[key] = standardizeValue(value);
          });
          return obj;
        }) ?? [];

      newOption.tooltip = getTooltipOption(tooltip);
      return {
        dataset: { source },
        ...newOption,
        tooltip: {
          ...newOption.tooltip,
          formatter: getSimpleTooltipFormatter({
            type: tooltipValueType.every(x => !x) ? 'normal' : tooltipValueType,
            digit: tooltipValueDigit.every(x => !x) ? 2 : tooltipValueDigit,
            tooltipShowTotal: this.tooltipShowTotal,
            markData: this.markData,
          }),
        },
      };
    },
    legendData() {
      if (!this.chartOption) {
        return null;
      }
      const indexObj = {};
      const { series, legend } = this.chartOption;
      if (this.type === 'pie') {
        // eslint-disable-next-line no-shadow
        const { data } = series[0];
        indexObj[0] = [];
        for (const item of data) {
          const { name, itemStyle } = item;
          const obj = {
            name,
            showName: name,
            color: itemStyle.color,
            selected: true,
          };
          indexObj[0].push(obj);
        }
      } else {
        for (const item of series) {
          const { name, encode } = item;
          const obj = {
            name,
            dimensionName: 'total',
            color: item.itemStyle?.color,
            indexLetter: 'A',
            indexName: name,
            selected: legend?.selected?.[encode.y] ?? true,
          };
          const seriesArr = indexObj[name];
          if (!seriesArr) {
            indexObj[name] = [obj];
          } else {
            seriesArr.push(obj);
          }
        }
      }
      return Object.entries(indexObj);
    },
  },
  watch: {
    hasData(val) {
      if (val) {
        this.$nextTick(() => {
          this.chartElement = this.$refs.baseChart.$refs.chart;
        });
      }
    },
  },
  methods: {
    getChart() {
      return this.chart;
    },
  },
};
</script>

<style scoped></style>
