import _ from 'lodash';
import moment from 'moment';
import { isArray } from './types';

/**
 * 转换echarts线性渐变方向 成 css渐变角度 css线性渐变方向为从上往下时为0deg。(0: 上 -> 下)。
 * 根据echarts渐变方向计算出角度，以水平方向为基准顺时针旋转的角度。（0: 左 -> 右） 所以需要多旋转90度，转为css角度。
 *
 * @param {any} x1 Echarts.graphic.LinearGradient.x
 * @param {any} y1 Echarts.graphic.LinearGradient.y
 * @param {any} x2 Echarts.graphic.LinearGradient.x2
 * @param {any} y2 Echarts.graphic.LinearGradient.y2
 * @returns Deg角度
 */
const toCssAngle = (x1, y1, x2, y2) => {
  const deltaX = x2 - x1;
  const deltaY = y2 - y1;
  return Math.atan2(deltaY, deltaX) * (180 / Math.PI) + 90;
};

/**
 * 获取系列真实值
 *
 * @param {Object} param Formatter 单个数据集
 * @returns 系列真实值
 */
const valueAccessor = (param) => {
  // 数据可能通过series配置，也可能通过dataset配置。
  const { value, encode, dimensionNames } = param;
  if (isArray(value)) {
    return value[encode.y[0]];
  } else if (_.isObject(value)) {
    return value[dimensionNames[encode.y[0]]];
  } else {
    return value;
  }
};

/**
 * 获取系列单位
 *
 * @param {Object} option 图表配置项
 * @param {Object} param Formatter 单个数据集
 * @returns 系列单位
 */
const unitAccessor = (option, param) => {
  const { yAxis, series } = option;
  const { seriesIndex } = param;
  // 规范 yAxis 和 series 都为数组, 方便通过下标访问
  const axisArr = isArray(yAxis) ? yAxis : !!yAxis ? [yAxis] : [];
  const serieArr = isArray(series) ? series : !!series ? [series] : [];
  const serie = serieArr[seriesIndex];

  // 构造单位
  let unit = '';
  if (serie && serie.showUnit !== false) {
    unit =
      serie.unit !== null && serie.unit !== undefined
        ? serie.unit
        : _.get(axisArr, [_.get(serie, 'yAxisIndex', 0), 'name'], ''); // 根据serie去yAxis配置找name属性当做单位
  }
  return unit;
};

/**
 * 获取可渐变背景颜色值
 *
 * @param {Object} param Formatter 单个数据集
 * @returns 系列背景颜色
 */
const bgcolorAccessor = (param) => {
  if (!param || !param.color) return null;
  const { color } = param;
  if (color.type === 'linear') {
    const { x, y, x2, y2, colorStops } = color;
    const angle = toCssAngle(x, y, x2, y2);
    const hint = colorStops.map((item) => {
      return `${item.color} ${item.offset * 100}%`;
    });
    return `linear-gradient(${angle}deg, ${hint.join(',')})`;
  } else if (color.type === 'radial') {
    const { x, y, r, colorStops } = color;
    const hint = colorStops.map((item) => {
      return `${item.color} ${item.offset * 100}%`;
    });
    return `radial-gradient(circle farthest-side at ${x} ${y}, ${hint.join(',')})`;
  } else {
    return color;
  }
};

/**
 * 获取文字颜色值
 *
 * @param {Object} param Formatter 单个数据集
 * @returns 系列文字颜色
 */
const colorAccessor = (param) => {
  if (!param || !param.color) return null;
  const { color } = param;
  if (color.type === 'linear' || color.type === 'radial') {
    const { colorStops } = color;
    return colorStops[0].color;
  } else {
    return color;
  }
};

// const xlabelAccessor = (option, param) => {
//   const { xAxis, series } = option;
//   const { name, seriesIndex, axisValueLabel } = param;
//   const axisArr = isArray(xAxis) ? xAxis : !!xAxis ? [xAxis] : [];
//   const serieArr = isArray(series) ? series : !!series ? [series] : [];
//   const serie = serieArr[seriesIndex];

//   const type = _.get(axisArr, [_.get(serie, 'xAxisIndex', 0), 'type'], 'category');
//   // const formatter = _.get(axisArr, [_.get(serie, 'xAxisIndex', 0), 'axisLabel', 'formatter'], '{yyyy}-{MM}-{dd}');
//   if (type === 'time') {
//     return axisValueLabel
//   } else {
//     return name;
//   }
// };

/**
 * Tooltip头部样式内容
 *
 * @param {Object} param Formatter 单个数据集
 * @returns
 */
const headTemplate = (option, param) => {
  if (!param) return '';
  const { name, axisValueLabel, axisType, axisValue } = param;
  const { tooltip } = option;
  const { timeFormat = 'YYYY-MM-DD HH:mm:ss' } = tooltip ?? {};
  const text =
    axisType === 'xAxis.time' ? moment(axisValue).format(timeFormat) : name || axisValueLabel;
  return `<div style="border-bottom: 1px solid #F0F0F0; color: #808080; margin-bottom: 5px; padding-bottom: 5px;">${text}</div>`;
};

/**
 * Tooltip每个系列样式内容
 *
 * @param {Object} option 图表配置项
 * @param {Object} param Formatter 单个数据集
 * @returns
 */
const seriesTemplate = (option, param) => {
  if (!param) return '';
  const value = valueAccessor(param);
  const unit = unitAccessor(option, param);
  const bgcolor = bgcolorAccessor(param);
  const color = colorAccessor(param);

  if (value === void 0 || value === null) return '';
  return `
    <div>
      <span style="display:inline-block;margin: 0 7px 2px 0;border-radius:5px;width:5px;height:5px;background:${bgcolor}"></span>
      <span>${param.seriesName}</span><span style="display:inline-block;">：</span><span style="color:${color};margin-left:10px">${value}</span>
      <span>${unit}</span>
    </div>  
  `;
};

// 默认tooltip配置
export const buildDefaultTooltip = (option) => {
  const cfg = {
    show: true,
    padding: [5, 10],
    trigger: 'axis', // 一般柱状图/曲线图都用axis，饼图/散点图等无类目的用item
    triggerOn: 'mousemove|click',
    renderMode: 'html',
    confine: true, // *是否限制在图表区域内
    appendToBody: false, // *不挂到body标签下，挂载到图表容器节点
    formatter: (params) => {
      let tooltipHeader = '',
        tooltipContent = '';
      if (isArray(params)) {
        tooltipHeader = headTemplate(option, params[0]);
        params.forEach((param) => {
          tooltipContent += seriesTemplate(option, param);
        });
      } else {
        tooltipHeader = headTemplate(option, params);
        tooltipContent += seriesTemplate(option, params);
      }

      return `
        <div>
          ${tooltipHeader}
          <div>${tooltipContent}</div>
        </div>
      `;
    },
  };
  return cfg;
};
