/* eslint-disable no-restricted-syntax,no-shadow */
import { percentageFormat, keepDecimals, numberOfDigit, getLetterByNumber, tooltipMarkColor } from '@/utils';
import { isObject } from 'lodash-es';

function getNoAlphaColor(color) {
  if (!color) return '';
  if (color.startsWith('#')) return color;
  const arr = color.match(/(\d+)/gi);
  return `rgba(${arr[0]},${arr[1]},${arr[2]},1)`;
}

export function getAxisFormatter(type) {
  return value => {
    if (type === 'rate') {
      return percentageFormat(value);
    }
    const numberVal = Number(value);
    let result = numberVal;
    const numberCount = numberOfDigit(numberVal);
    if (!Number.isNaN(numberVal)) {
      if (numberCount > 6) {
        result = `${numberVal / 1000000}M`;
      } else if (numberCount > 3) {
        result = `${numberVal / 1000}K`;
      }
    }
    return result;
  };
}

function getTooltipSortFn(valueType) {
  return (a, b) => {
    if (valueType === 'rate') {
      return parseFloat(b.value) - parseFloat(a.value);
    }
    return b.value - a.value;
  };
}

function getIndexData(params, valueType, digit, indexMap) {
  const indexes = indexMap ? [...indexMap.keys()] : [];
  const map = new Map();
  for (const param of params) {
    const { color, value, seriesName, dimensionNames, encode } = param;
    const dimensionName = dimensionNames[encode.y];
    let indexLetter = '';
    let indexLabel = '';
    const curIndexName = indexes.find(x => seriesName.startsWith(`${x}_`));
    let showName = seriesName;
    if (curIndexName) {
      const obj = indexMap.get(curIndexName);
      indexLetter = obj.indexLetter;
      indexLabel = obj.indexLabel;
      // eslint-disable-next-line prefer-destructuring
      showName = seriesName.split(`${curIndexName}_`)[1];
    }
    let curValue = value;
    if (typeof value === 'object') {
      if (Array.isArray(value)) {
        curValue = value[encode.y];
      } else {
        curValue = value[dimensionName];
      }
    }
    if (valueType === 'rate') {
      curValue = percentageFormat(curValue);
    } else if (valueType === 'normal') {
      curValue = keepDecimals(curValue, digit);
    }
    const seriesObj = {
      seriesName: showName,
      color,
      value: curValue,
    };
    const indexObj = map.get(indexLetter);
    if (!indexObj) {
      map.set(indexLetter, { indexLabel, seriesArr: [seriesObj] });
    } else {
      indexObj.seriesArr.push(seriesObj);
    }
  }
  const arr = [];
  let slicedSeriesNames = [];
  const indexArr = [...map];
  for (let i = 0; i < indexArr.length; i += 1) {
    const [indexName, { indexLabel, seriesArr }] = indexArr[i];
    let slicedArr = [];
    if (i === 0) {
      slicedArr = seriesArr.sort(getTooltipSortFn(valueType)).slice(0, 10);
      slicedSeriesNames = slicedArr.map(x => x.seriesName);
    } else {
      slicedArr = slicedSeriesNames.map(x => seriesArr.find(p => p.seriesName === x));
    }
    arr.push([indexName, indexLabel, slicedArr]);
  }
  return arr;
}

const getPieTooltipHtml = (indexMap, params) => {
  const { value, percent, seriesName, name } = params;
  const color = getNoAlphaColor(params.color);
  let str = '<div class="dc-chart-tooltip">';
  str += `<div class="pie-item">
                <span class="left-side">
                    ${
                      indexMap.size > 1
                        ? `<span class="letter-text" style="background-color: ${color}">
                            ${indexMap.get(seriesName).indexLetter}
                          </span>`
                        : `<span class="letter-text empty" style="background-color: ${color}"></span>`
                    }
                    <span class="series-name">${name}</span>
                </span>
                <span class="series-value">${keepDecimals(value)} (${keepDecimals(percent)}%)</span>
              </div>`;
  str += '</div>';
  return str;
};

const getTooltipContentHtml = ({ name, value, color }) => {
  const colorStyle = `color: ${getNoAlphaColor(color)};`;
  return `<p class="tooltip-content">
                    <span class="tooltip-text" style="${colorStyle}">${name}: </span>
                    <span class="tooltip-text" style="${colorStyle}">${value}</span>
                </p>`;
};

const getOthersContentHtml = params => {
  let str = '';
  const others = params.length - 10;
  if (others > 0) {
    str += `<p class="rest-text">以及其他${others}项</p>`;
  }
  return str;
};

const getMarkContentHtml = (markData, params) => {
  let str = '';
  const xAxis = params[0].name;
  const curMark = markData.find(x => x.xAxis === xAxis);
  if (curMark) {
    str += `<div class="tooltip-mark-content">
                <h4 class="mark-title">标注：</h4>
                <p class="mark-text" style="color: ${tooltipMarkColor};">${curMark.content}</p>
            <div>`;
  }
  return str;
};

export function getTooltipFormatter({ type = 'normal', digit = 2, showOthers, markData } = {}) {
  return (indexMap, params) => {
    // console.log(indexMap, params);
    // params不是数组时，为饼图
    if (!Array.isArray(params)) {
      return getPieTooltipHtml(indexMap, params);
    }
    const { name } = params[0];
    let str = `<div class="dc-chart-tooltip">
                      <h4 class="tooltip-title">${name}:</h4>`;
    const indexData = getIndexData(params, type, digit, indexMap);
    // 多指标
    if (indexData.length > 1) {
      const noDimension = indexData[0][2][0].seriesName === 'total';
      // 维度为总计
      if (noDimension) {
        indexData.sort((a, b) => {
          if (type === 'rate') {
            return parseFloat(b[2][0].value) - parseFloat(a[2][0].value);
          }
          return b[2][0].value - a[2][0].value;
        });
        for (let i = 0; i < indexData.length; i += 1) {
          const [indexLetter, indexLabel, seriesArr] = indexData[i];
          const { value, color } = seriesArr[0];
          str += getTooltipContentHtml({ name: indexLabel, value, color });
        }
      } else {
        str += `<div class="index-list">`;
        for (let i = 0; i < indexData.length; i += 1) {
          const [indexLetter, indexLabel, seriesArr] = indexData[i];
          str += `<div class="index-item">
                 <div class="series-list">`;
          for (const { color, seriesName, value } of seriesArr) {
            str += `<div class="series-item">
								<span class="left-side">
										<span class="letter-text" style="background-color: ${getNoAlphaColor(color)}">${indexLetter}</span>
										<span class="series-name">${seriesName}</span>
								</span>
								<span class="series-value">${value}</span>
							</div>`;
          }
          str += '</div></div>';
        }
        str += '</div>';
      }
    } else {
      const [indexLetter, indexLabel, seriesArr] = indexData[0];
      for (const { seriesName, value, color } of seriesArr) {
        const newName = seriesName === 'total' ? indexLabel : seriesName;
        str += getTooltipContentHtml({ name: newName, value, color });
      }
    }
    if (showOthers) {
      str += getOthersContentHtml(params);
    }
    if (markData) {
      str += getMarkContentHtml(markData, params);
    }
    str += '</div>';
    return str;
  };
}

export function getSimpleTooltipFormatter({ type = 'normal', digit = 2, showOthers, markData, tooltipShowTotal } = {}) {
  return params => {
    const { name } = params[0];
    let str = `<div class="dc-chart-tooltip">
                      <h4 class="tooltip-title">${name}:</h4>`;
    let totalValue = 0;

    const contentArr = [];
    for (let i = 0; i < params.length; i += 1) {
      const { seriesName, value, color, encode, dimensionNames } = params[i];
      let val = value;
      if (Array.isArray(value)) {
        val = value[encode.y[0]];
      } else if (isObject(value)) {
        val = value[dimensionNames[encode.y[0]]];
      }
      totalValue += val;
      let curValueType = type;
      let curValueDigit = digit;
      if (Array.isArray(type)) {
        curValueType = type[i];
      }
      if (Array.isArray(digit)) {
        curValueDigit = digit[i];
      }
      if (curValueType === 'rate') {
        val = percentageFormat(val);
      } else if (curValueType === 'normal') {
        val = keepDecimals(val, curValueDigit);
      }
      contentArr.push({ name: seriesName, value: val, color });
    }

    if (tooltipShowTotal) {
      str += getTooltipContentHtml({ name: '总计', value: keepDecimals(totalValue), color: '#202444' });
    }

    contentArr.sort(getTooltipSortFn(type[0] ?? type));
    contentArr.slice(0, 10).forEach(item => {
      str += getTooltipContentHtml(item);
    });

    if (showOthers) {
      str += getOthersContentHtml(params);
    }
    if (markData) {
      str += getMarkContentHtml(markData, params);
    }
    str += '</div>';
    return str;
  };
}
