<script setup lang="ts">
import { Ref, defineProps, watchEffect,ref ,computed,unref,onMounted} from "vue";
import type { EChartsOption } from "echarts";
import { useECharts } from "../../../hooks/web/useECharts";
import useEchartsAutoTooltip from "../../../components/chart/logic/useEchartsAutoTooltip";
import { useLineXAxisAuto } from "../../../components/chart/logic/useLineXAxisAuto";
import {
  colorList,
  mergeOptions,
  circleIconPath,
  removeExtraCssText,
  getCommonTheme,
  yaLineTooltipFormatter,
  getLineChartThemeColor,
} from "@/components/chart/options/index";
import { isObject, isTowArray } from "@/utils/is";
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions, getInstance, echarts } = useECharts(
  chartRef as Ref<HTMLDivElement>
);

/**
 * @author changjun
 * @description 折线图组件
 * @prop { String } title 标题
 * @prop { Array } chartData 图表数据
 * @prop { Boolean } smooth 开启平滑模式
 * @prop { Boolean } manual 手动设置 结合otherOptions
 * @prop { Object } otherOptions 手动设置一些其它的设置 结合manual
 * @prop { Function } legendFormatter 图例自定义显示函数
 * @date 2022/08/29
 */
interface LineChartProps {
  title?: string;
  xAxisData: any[];
  theme?: string;
  autotip?: boolean;
  autoAxis?: boolean;
  colors?: string[];
  /**
   * 图表数据
   */
  chartData: any[];
  /**
   * 是否开启平滑模式
   */
  smooth?: boolean;
  tooltipFormatter?:
    | string
    | ((params: any, ticket: any, callback: any) => string);
  /**
   * 格式化图例显示函数 用于需要显示图例名称之外内容的时候
   */
  legendFormatter?: string | ((name: string) => string);
  /**
   * 是否需要手动设置一些其它的设置，需要结合otherOptions才能起作用
   */
  manual?: boolean;
  /**
   * 手动设置一些其它的设置，需要结合manual才能起作用
   */
  otherOptions?: EChartsOption;
  areaGradientColor?: any[];
  autoXAxis?: boolean;
  autoStartValue?: number;
  autoEndValue?: number;
  xInterval?: number;
  xFontSize?: number;
  xAxisAxisLineShow?: boolean;
  xAxisSplitLineShow?: boolean;
  yAxisAxisLineShow?: boolean;
  yAxisSplitLineShow?: boolean;
  showSymbol?: boolean;
  gridTop?: number | string;
  gridBottom?: number | string;
  gridLeft?: number | string;
  gridRight?: number | string;
  tooltipValueFormatter?: any;
  isShowSide?: boolean;
  boundaryGap?: boolean;
}

const {
  xAxisData = [],
  title = "",
  chartData = [],
  legendFormatter = (name) => name,
  smooth = false,
  manual = false,
  otherOptions = {},
  tooltipFormatter = "",
  areaGradientColor = [],
  theme = "light",
  colors = [],
  autoXAxis = false,
  autoStartValue = 0,
  autoEndValue = 6,
  xInterval = 0,
  xFontSize = 10,
  autotip = false,
  autoAxis = false,
  xAxisAxisLineShow = true,
  xAxisSplitLineShow = false,
  yAxisAxisLineShow = false,
  yAxisSplitLineShow = true,
  showSymbol = true,
  gridTop = 55,
  gridBottom = "15%",
  gridLeft = 44,
  gridRight = 24,
  isShowSide = false,
  boundaryGap = false,
  tooltipValueFormatter = (val) => val,
} = defineProps<LineChartProps>();

const currentTheme = computed(() => {
  return getLineChartThemeColor(unref(theme));
}) as any;

const commonChartTheme = computed(() => {
  return getCommonTheme(unref(theme));
}) as any;

let options: EChartsOption = {
  title: {
    show: true,
    text: unref(title),
    top: 16,
    left: 24,
    textStyle: {
      fontSize: 12,
      color: unref(currentTheme).titleColor,
      fontWeight: 400,
    },
  },

  tooltip: {
    trigger: "axis",
    show: true,
    confine: true,
    textStyle: {
      color: unref(commonChartTheme).tooltip.textStyle.color,
    },
    backgroundColor: unref(commonChartTheme).tooltip.backgroundColor,
    borderColor: "transparent",
    extraCssText: "border-radius: 4px;",
    formatter: unref(tooltipFormatter) as any,
    valueFormatter: unref(tooltipValueFormatter),
  },

  color:
    unref(colors).length > 0 ? unref(colors) : unref(currentTheme).colorList,

  grid: {
    top: unref(gridTop),
    left: unref(gridLeft),
    right: unref(gridRight),
    bottom: unref(gridBottom),
  },

  legend: {
    top: 16, // 距离容器上边界的距离
    right: 24, // 距离容器右边界的距离
    itemWidth: 4, // 图例宽度
    itemHeight: 4, // 图例高度
    itemGap: 16, // 图例间距
    icon: "emptyCircle",
    // 图例文字的样式
    textStyle: {
      fontSize: 10,
      fontWeight: 400,
      color: unref(currentTheme).legendTextColor,
    },
    formatter: unref(legendFormatter),
  },

  xAxis: [
    {
      data: unref(xAxisData),
      axisLabel: {
        fontSize: xFontSize,
        fontWeight: 400,
        color: unref(currentTheme).axisLabelColor,
        interval: unref(xInterval),
      },
      axisTick: { show: false },
      splitLine: {
        show: unref(xAxisSplitLineShow),
        lineStyle: {
          color: unref(currentTheme).axisLineColor,
          width: 1,
        },
      },
      axisLine: {
        show: unref(xAxisAxisLineShow),
        lineStyle: {
          color: unref(currentTheme).axisLineColor,
          width: 1,
        },
      }, // 坐标轴轴线
      boundaryGap: unref(boundaryGap),
    },
  ],

  yAxis: [
    {
      type: "value",
      axisLabel: {
        fontSize: 10,
        fontWeight: 400,
        color: unref(currentTheme).axisLabelColor,
      },
      splitLine: {
        // 坐标轴分割线
        show: unref(yAxisSplitLineShow),
        lineStyle: { color: unref(currentTheme).axisLineColor }, // 分割线颜色
      },
      axisLine: {
        show: unref(yAxisAxisLineShow),
        lineStyle: { color: unref(currentTheme).axisLineColor },
      },
    },
  ],

  series: [],
};

const getSeriesData = function (list) {
  return list.map((item, index) => {
    const newItem = {
      type: "line",
      showSymbol: unref(showSymbol),
      smooth: unref(smooth),
      lineStyle: { width: 1.5 },
    } as any;

    if (unref(showSymbol)) {
      newItem.symbol = "emptyCircle";
      newItem.symbolSize = 4;
    }

    if (unref(areaGradientColor).length > 0) {
      const _isTowArray = isTowArray(unref(areaGradientColor));
      const _startColor = _isTowArray
        ? unref(areaGradientColor)[index][0]
        : unref(areaGradientColor)[0];
      const _endColor = _isTowArray
        ? unref(areaGradientColor)[index][1]
        : unref(areaGradientColor)[1];
      newItem.areaStyle = {
        color: {
          type: "linear",
          x: 0,
          y: 0,
          x2: 0,
          y2: 1,
          colorStops: [
            {
              offset: 0,
              color: _startColor, // 0% 处的颜色
            },
            {
              offset: 1,
              color: _endColor, // 100% 处的颜色
            },
          ],
          global: false,
        },
      };
    }
    return {
      ...newItem,
      ...item,
    };
  });
};

let stopAutoShowFun = null as any;
let stopAutoSwipeFun = null as any;

async function initChart() {
  options.series = getSeriesData(unref(chartData));
  options.xAxis![0].data = unref(xAxisData);
  options.xAxis![0].axisLabel!.interval = unref(xInterval);
  // @ts-ignore
  options.title!.text = unref(title);
  // @ts-ignore
  options.legend!.formatter = unref(legendFormatter);
  if (unref(tooltipFormatter)) {
    // @ts-ignore
    options.tooltip!.extraCssText = removeExtraCssText;
    // @ts-ignore
    options.tooltip!.formatter = unref(tooltipFormatter);
  } else {
    // @ts-ignore
    options.tooltip!.extraCssText = "border-radius: 4px;";
    // @ts-ignore
    options.tooltip!.borderColor = "transparent";
    // @ts-ignore
    options.tooltip!.textStyle.color =
      unref(commonChartTheme).tooltip.textStyle.color;
    // @ts-ignore
    options.tooltip!.textStyle.backgroundColor =
      unref(commonChartTheme).tooltip.backgroundColor;
  }
  // 如果是手动设置模式的话
  if (unref(manual) && isObject(unref(otherOptions))) {
    options = mergeOptions(options, unref(otherOptions));
  }
  initAutoXAxis();
  openAutoTooltip();
  setOptions(options);
  if (unref(isShowSide)) {
    initXside();
    delete options.xAxis[0].axisLabel.interval;
  }
}

// 初始化滑动手柄
const initXside = () => {
  options.dataZoom = {
    type: "slider",
    showDetail: false, //即拖拽时候滚动条两侧不显示信息 默认true
    realtime: true, //拖动滚动条时是否动态的更新图表数据
    height: 20, //滚动条高度
    start: unref(xAxisData).length, //滚动条开始位置（共100等份）
    end: 100, //结束位置（共100等份）
    handleSize: "100%", // 两侧手柄的大小
    // backgroundColor: "#32496D", // 滚动条背景色
    // borderColor: "#32496D", // 滚动条边框色
    bottom: 0, // 滚动条位置
    dataBackground: {
      lineStyle: {
        color: "rgba(84, 188, 255, 1)", // 滚动条内线颜色
      },
    },
    moveHandleSize: 0, // 移动手柄高度
  };
};

const initAutoXAxis = () => {
  if (unref(autotip)) return;
  if (
    unref(autoAxis) &&
    unref(chartData).length > 0 &&
    unref(xAxisData).length > 7
  ) {
    options.dataZoom = {
      type: "slider",
      show: false,
      xAxisIndex: 0,
      startValue: 0,
      endValue: 6,
    };
    if (stopAutoSwipeFun) {
      stopAutoSwipeFun();
    }
    const chartInstance = getInstance();
    const { stopAutoSwipe } = useLineXAxisAuto(
      chartInstance,
      options,
      unref(xAxisData)
    );
    stopAutoSwipeFun = stopAutoSwipe;
  }
};

function openAutoTooltip() {
  if (unref(autotip) && unref(chartData).length > 0) {
    if (stopAutoShowFun) {
      stopAutoShowFun();
    }
    const instance = getInstance();
    const { stopAutoShow } = useEchartsAutoTooltip(instance, options);
    stopAutoShowFun = stopAutoShow;
  }
}

onMounted(() => {
  initChart();
});

watchEffect(() => {
  initChart();
});
</script>

<template>
  <div
    class="chart"
    ref="chartRef"
    :style="{ width: '100%', height: '100%' }"
  ></div>
</template>

<style lang="scss">
.light-linechart-tooltip {
  padding: 6px 12px;
  box-sizing: border-box;
  background: rgba(255, 255, 255, 0.96);
  box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  display: flex;
  flex-direction: column;

  &-subtitle {
    font-size: 12px;
    font-weight: 600;
    color: rgba(0, 0, 0, 0.65);
    line-height: 1;
  }

  &-content {
    display: flex;
    max-width: 420px;
    flex-wrap: wrap;
    flex-shrink: 0;

    &-item {
      display: flex;
      align-items: center;
      margin-top: 8px;

      &-icon {
        width: 6px;
        height: 6px;
        border-radius: 6px;
        margin-right: 5px;
      }

      &-name {
        font-size: 12px;
        color: rgba(0, 0, 0, 0.65);
        margin-right: 8px;
      }

      &-value {
        width: 77px;
        font-size: 12px;
        color: rgba(0, 0, 0, 0.4);
      }
    }
  }
}

.light-linechart-tooltip-vertical {
  &-content {
    display: flex;
    flex-direction: column;
  }
}
</style>
