<script lang="ts" setup name="LineChart">
import * as echarts from 'echarts/core'
import type { ECharts } from 'echarts'
import { init } from 'echarts'
import type { Ref } from 'vue'
import type { ECBasicOption } from 'echarts/types/dist/shared'
import type { lineDataI, lineOption, lineSeriesOption } from './echart-interface'
import tdTheme from './theme.json' // 引入默认主题
import { formatColor, getAlphaColor } from './utils'
const props = defineProps({
  /**
   * id
   */
  id: {
    type: String,
    default: 'chart',
  },
  /**
   * 加载状态
   */
  loading: {
    type: Boolean,
    default: false,
  },
  /**
   * 网格配置
   */
  grid: {
    type: Object,
    default: () => {
      return {
        // top: 50,
        // left: 5,
        // right: 15,
        // bottom: 10,
        // containLabel: true, // 是否包含坐标轴的刻度标签
      }
    },
  },
  /**
   * 图例设置对象
   */
  legend: {
    type: Object,
    default: () => {
      return {
        show: true,
        // icon: 'circle',
        orient: 'horizontal', // 图例方向
        // align: 'left', // 图例标记和文本的对齐，默认自动
        // top: 5,
        // right: 20,
        // itemWidth: 12,
        // itemHeight: 12,
        // padding: [0, 0, 0, 120],
        selected: {}, // 选中状态
      }
    },
  },
  /**
   * 图例列表，非必传
   */
  legendData: {
    type: Array<string>,
    default: () => { return [] },
  },
  /**
   * 图表宽
   */
  width: {
    type: String,
    default: '100%',
  },
  /**
   * 图表高
   */
  height: {
    type: String,
    default: '100%',
  },
  /**
   * X轴刻度数据，格式为['周一','周二'...]
   */
  xAxisData: {
    type: Array<string>,
    default: () => { return [] },
  },
  /**
   * X轴类型
   */
  xAxisType: {
    type: String,
    default: 'category',
    validator: (value: string) => {
      return ['category', 'value', 'time', 'log'].includes(value)
    },
  },
  /**
   * 数据，格式为[{name:'系列名',data:[0,0,0,...0], color:'可选'},...]
   */
  data: {
    type: Array<lineDataI>,
    default: () => { return [] },
  },
  /**
   * 单位
   */
  unit: {
    type: String,
    default: '',
  },
  /**
   * 颜色
   */
  colors: {
    type: Array,
    default: () => {
      return [
        '#2d8cf0',
        '#19be6b',
        '#ff9900',
        '#E46CBB',
        '#9A66E4',
        '#ed3f14',
        '#01C2F9',
      ]
    },
  },
  /**
   * 实虚线
   */
  axisLineType: {
    type: String,
    default: '',
  },
  /**
   * 轴线颜色
   */
  axisLineColor: {
    type: String,
    default: '#7a6b74',
  },
  /**
   * 轴线上文字颜色
   */
  fontColor: {
    type: String,
    default: '#000000',
  },
  /**
   * 是否为渐变折线图
   */
  gradient: {
    type: Boolean,
    default: false,
  },
  /**
   * y轴最大值
   */
  max: {
    type: [String, Number],
    default: '',
  },
  /**
   * 标题
   */
  title: {
    type: String,
    default: '',
  },
  /**
   * 平滑
   */
  smooth: {
    type: Boolean,
    default: false,
  },
  /**
  * 工具
  */
  toolbox: {
    type: Boolean,
    default: false,
  },
  /**
  * 选中状态
  */
  selected: {
    type: Object,
    default: () => ({}),
  },
})

// 图表对象
let chart: ECharts
const chartRef: Ref<HTMLElement | null> = ref(null)

// 监听数据变化
watch(
  [() => props.xAxisData, props.data], ([newName, newNums], [oldName, oldNums]) => {
    console.log(props.selected)
    refreshChart()
  },
  {
    immediate: true,
    deep: true,
  },
)
// 构建option
function buildOption() {
  const option: any = {
    grid: props.grid,
    legend: props.legend, // 图例
    toolbox: {
      show: props.toolbox,
      feature: {
        dataZoom: {
          yAxisIndex: 'none',
        },
        dataView: { readOnly: false },
        magicType: { type: ['line', 'bar'] },
        restore: {},
        saveAsImage: {},
      },
    },
    tooltip: {
      trigger: 'axis',
      textStyle: {
        fontSize: 16,
      },
      axisPointer: {
        type: 'cross',
        label: {
          fontSize: 13,
        },
      },
      valueFormatter: (value: string | number) => {
        return value ? value + props.unit : ''
      },
    }, // 提示框
    xAxis: [
      {
        type: props.xAxisType,
        boundaryGap: true,
        axisLine: {
          lineStyle: {
            color: props.axisLineColor, // 轴线的颜色
          },
        },
        axisLabel: {
          color: props.fontColor, // X轴名称颜色
          fontSize: 14,
        },

        axisTick: {
          show: true,
          alignWithLabel: true,
        },
        // splitLine: {
        //   show: false,
        //   lineStyle: {
        //     color: ['#7a6b74'],
        //     type: props.axisLineType,
        //   },
        // },
      },
    ],
    yAxis: [
      {
        name: props.unit,
        type: 'value',
        max: (value: any) => {
          return value.max
        },
        min: (value: any) => {
          return value.min
        },
        // boundaryGap: true,
        axisLine: {
          show: false,
          lineStyle: {
            color: props.axisLineColor, // 轴线的颜色
          },
        },
        nameTextStyle: {
          color: props.fontColor,
          fontSize: 14,
          verticalAlign: 'middle',
        },
        splitLine: {
          show: true,
          lineStyle: {
            color: ['#bfbfbf'],
            type: 'solid',
          },
        },
      },
    ],
    series: [] as lineSeriesOption[],
  }
  // 标题
  if (props.title) {
    option.title = {
      show: true,
      text: props.title,
    }
  }
  // 图例
  if (props.legend && props.legendData.length > 0) {
    option.legend!.data = props.legendData
  }
  // 选中状态
  if (props.selected) {
    console.log(props.selected, 'props.selected')
    option.legend.selected = props.selected
  }
  // x轴数据
  if (props.xAxisData && props.xAxisData.length > 0) {
    if (Array.isArray(option.xAxis) && option.xAxis.length > 0) {
      option.xAxis[0].data = props.xAxisData // 横轴
    }
  }
  if (props.max && Array.isArray(option.yAxis) && option.yAxis.length > 0) {
    option.yAxis[0].max = props.max
  }
  // 数据
  if (props.data) {
    const newSeries: lineSeriesOption[] = []
    // 遍历data， 拆分轴线名称，数据和颜色
    for (const itemIndex in props.data) {
      const item = props.data[itemIndex]
      const series: any = {
        name: item.name, // 线系列名
        type: 'line',
        // symbol: 'none', // 去掉折线节点
        smooth: props.smooth, // 曲线平滑设置
        lineStyle: {
          width: 2,
        },
        data: item.data,
        markPoint: {
          data: [
            { type: 'max', name: 'Max' },
            { type: 'min', name: 'Min' },
          ],
        },
        markLine: {
          data: [{ type: 'average', name: 'Avg' }],
        },
      }
      // 线段颜色
      if (item.color || props.colors.length > 0) {
        series.itemStyle = {
          color: item.color ? formatColor(item.color) : formatColor(props.colors[itemIndex] as string),
        }
        // 如果开启渐变
        if (props.gradient) {
          series.areaStyle = {
            color: new echarts.graphic.LinearGradient(
              0, 0, 0, 1, // 变化度 ,渐变方向
              [
                {
                  offset: 0.1,
                  color: item.color ? getAlphaColor(item.color, 0.6) : getAlphaColor(props.colors[itemIndex] as string, 0.6),
                },
                {
                  offset: 1,
                  color: '#fff',
                },
              ],
            ),
          }
        }
      }
      newSeries.push(series)
    }
    option.series = newSeries
  }
  return option
}
// 初始化图表
function initChart() {
  chart = init(chartRef.value as HTMLElement, tdTheme)
  chart.setOption({})
}

// 刷新图表
function refreshChart() {
  if (chart) {
    console.log('渲染折线图')

    const option = buildOption()
    chart.setOption(option as unknown as ECBasicOption, true)
    chart.resize()
  }
}
window.addEventListener('resize', () => {
  chart.resize()
})

onMounted(() => {
  initChart()
})
</script>

<template>
  <div
    v-show="props.xAxisData.length" :id="id" ref="chartRef" v-loading="loading" class="chart"
    :style="{ height, width }"
  />
  <el-empty v-show="!props.xAxisData.length" :style="{ height, width }" />
</template>

<style lang="scss" scoped>
.chart {
  width: 100%;
  height: 100%;
}
</style>
