import { getColor } from "@/constants/config/colors";
import { set, cloneDeep, isArray, isFunction } from "lodash-es";
import {
  GROUPLINE,
  GROUPAREA,
  GROUPBAR,
  TRANGROUPBAR,
  SCATTER,
  LINEBAR,
  RINGPIE,
  PIE,
} from "@bdlite/chart-config/lib/chartTypes";
const baseLineSeriesPath = ["lineStyle.color", "itemStyle.color"];
const baseBarSeriesPath = ["itemStyle.color", "itemStyle.borderColor"];
const chartSeriesDiffConfig = {
  [GROUPLINE]: baseLineSeriesPath,
  [GROUPAREA]: [...baseLineSeriesPath, "areaStyle.color"],
  [GROUPBAR]: baseBarSeriesPath,
  [TRANGROUPBAR]: baseBarSeriesPath,
  [SCATTER]: {
    datasetIndex: (baseSeries, idx) => idx,
  },
  [LINEBAR]: {
    line: baseLineSeriesPath,
    bar: baseBarSeriesPath,
  },
};
export const TransLineBarOpt = ({
  chartType,
  dataResult = [],
  iconConfig: {
    options: { series },
  },
}) => {
  if (!dataResult) return { series, dataset: dataResult };
  const lineSeries = series[1];
  const barSeries = series[0];
  const [lineDataSet] = dataResult.filter(({ value }) => value.type === "line");
  const [barDataSet] = dataResult.filter(({ value }) => value.type === "bar");
  const { line, bar } = chartSeriesDiffConfig[chartType] || [];
  let l = [];
  let b = [];
  let dataset = [];
  if (lineDataSet?.value?.dimensions) {
    const { dimensions } = lineDataSet.value;
    l = dimensions.slice(1).map((item, idx) => {
      const cloneSeries = cloneDeep(lineSeries);
      line.forEach((path) => {
        set(cloneSeries, path, getColor(idx));
      });
      return cloneSeries;
    });
    // if (l.length) {
    //   l.push(lineSeries)
    // }
    dataset.push(lineDataSet.value);
  }
  if (barDataSet?.value?.dimensions) {
    const { dimensions } = barDataSet.value;
    b = dimensions.slice(1).map((item, idx) => {
      const cloneSeries = cloneDeep(barSeries);
      bar.forEach((path) => {
        set(cloneSeries, path, getColor(idx));
      });
      return cloneSeries;
    });
    // if (b.length) {
    //   b.push(barSeries)
    // }
    dataset.push(barDataSet.value);
  }
  console.log("TransLineBarOpt", l, b);
  return {
    series: [...l, ...b],
    dataset: dataset,
  };
};
const TransBaseSeries = (chartType, baseSeries, seriesLen) => {
  let nextSeries = [];
  for (let index = 0; index < seriesLen; index++) {
    const cloneSeries = cloneDeep(baseSeries);
    const seriesArr = chartSeriesDiffConfig[chartType] || [];
    if (isArray(seriesArr)) {
      seriesArr.forEach((path) => {
        set(cloneSeries, path, getColor(index));
      });
    } else {
      Object.keys(seriesArr).forEach((key) => {
        if (isFunction(seriesArr[key])) {
          set(cloneSeries, key, seriesArr[key](baseSeries, index));
        } else {
          set(cloneSeries, key, getColor(index));
        }
      });
    }

    nextSeries.push(cloneSeries);
  }
  return nextSeries.length ? nextSeries : [baseSeries];
};
export const TransBaseChartOpt = ({
  chartType,
  iconConfig: {
    options: { series },
  },
  dataResult,
}) => {
  const { dimensions } = dataResult || { dimensions: [] };
  return TransBaseSeries(chartType, series[0], dimensions.length - 1);
};
// 一些图表数据转换函数，返回整个series
export const TransSankeySeries = ({
  dataResult,
  iconConfig: {
    options: { series, seriesColor },
  },
}) => {
  if (!dataResult || !series) return { series };
  if (!dataResult.dimensions) {
    series[0].data = [];
    series[0].link = [];
    series[0].levels = [];
    return series;
  }
  let _arr = [];
  const maxLen = seriesColor.length;
  const [source, target, seriesName] = dataResult.dimensions;
  const dimensionNames = [];
  const flowDirectData = [];
  dataResult.source.forEach((item) => {
    dimensionNames.push(
      {
        name: item[source],
      },
      {
        name: item[target],
      }
    );
    flowDirectData.push({
      source: item[source],
      target: item[target],
      value: item[seriesName],
    });
  });
  dimensionNames.map((item, index) => {
    const color =
      index < maxLen ? seriesColor[index] : seriesColor[index % maxLen];
    if (!_arr.find((v) => v.name == item.name)) {
      _arr.push({
        ...item,
        itemStyle: {
          color: series[0]._color.startsWith("loop")
            ? color.node.color
            : undefined,
          borderColor: series[0]._color.startsWith("loop")
            ? color.node.color
            : undefined,
          borderWidth: color.node.borderWidth,
        },
      });
    }
  });
  series[0].data = [..._arr];
  series[0].links = flowDirectData.map((item, index) => {
    const color =
      index < maxLen ? seriesColor[index] : seriesColor[index % maxLen];
    return {
      ...item,
      lineStyle: {
        color:
          series[0]._color === "loopf"
            ? "source"
            : series[0]._color === "loopb"
            ? "target"
            : undefined,
        curveness: color.link.curveness,
      },
    };
  });
  if (series[0]._color.startsWith("loop")) {
    series[0].levels = [];
  } else {
    series[0].levels = seriesColor.map((c, index) => {
      return {
        depth: index,
        itemStyle: {
          color: c.node.color,
          borderColor: c.node.color,
          borderWidth: c.node.borderWidth,
        },
        lineStyle: {
          color: c.link.color,
          curveness: c.link.curveness,
        },
      };
    });
  }
  return {
    series,
    dataset: {
      source: [dimensionNames, flowDirectData],
    },
  };
};

export const TransWordCloudsSeries = ({
  dataResult,
  iconConfig: {
    options: { series, seriesColor },
  },
}) => {
  if (!dataResult || !series) return series;
  const [source, target] = dataResult.dimensions;
  const nextDataSet = dataResult.source.map((item) => {
    return {
      name: item[source],
      value: item[target],
    };
  });
  series[0].data = nextDataSet.map((item) => {
    return {
      ...item,
      textStyle: {
        // color: seriesColor[i]
        color: seriesColor[0],
      },
    };
  });
  return series;
};

export const TransWaveInstrumentSeries = ({
  dataResult,
  iconConfig: {
    options: { series },
  },
}) => {
  if (!dataResult) return series;
  const [name] = dataResult.dimensions;
  const value = dataResult.source[0][name];
  series[0].data = [
    {
      name,
      value,
    },
  ];
  return series;
};

export const TransRadarData = (
  {
    dataResult,
    iconConfig: {
      options: { radar, series, grid, legend },
    },
  },
  chartInstance
) => {
  if (!radar || !dataResult)
    return {
      radar,
      series,
      legend,
    };
  const [dimensionKey, valueKey] = dataResult.dimensions;
  let indicator = [];
  let data = [
    {
      value: [],
      name: valueKey,
    },
  ];
  dataResult.source.forEach((item) => {
    data[0].value.push(item[valueKey]);
  });
  let maxValue = Math.max.apply(null, data[0].value);
  dataResult.source.forEach((item) => {
    indicator.push({
      name: item[dimensionKey],
      max: maxValue,
    });
  });
  radar.radius = computedRadioAngle(chartInstance, grid);

  radar.indicator = indicator || radar.indicator;

  legend.data = [valueKey];
  series[0].data = data;

  return { radar, legend, series };
};
export const TransTranDoubleBarData = ({
  dataResult,
  iconConfig: {
    options: { dataset },
  },
}) => {
  console.log(dataResult);

  if (!dataResult) return [{ source: [[]] }];
  let _data = dataResult[0];
  const { source } = _data;
  dataset[0] = { source };
  return dataset;
};
export const TransDiagramData = ({
  dataResult,
  iconConfig: {
    options: { series },
  },
}) => {
  if (!dataResult) return { series };
  let _data = dataResult[0];
  const { nodes, links } = _data;
  series[0].nodes = nodes;
  series[0].links = links;
  return { series };
};
export const TransGaugeData = ({
  dataResult,
  iconConfig: {
    options: { series },
  },
}) => {
  if (!dataResult) return { series };
  series[0].data = dataResult;
  return { series };
};

export const TransLineAndBarOptions = ({ xAxis, dataset, grid }, instance) => {
  if (!dataset?.source || !instance || !instance.getWidth) {
    return { xAxis, grid };
  }
  const maxWdth = instance.getWidth();
  const dimensionName = dataset.dimensions[0];
  const maxTextWdith = dataset.source.reduce((totalLen, current) => {
    return totalLen + current[dimensionName].length * xAxis.axisLabel.fontSize;
  }, 0);
  let lastText = dataset.source[dataset.source.length - 1][dimensionName];
  let rotate = "0";
  let align = "center";
  if (maxTextWdith >= maxWdth * 0.7 && maxTextWdith < maxWdth * 1.5) {
    rotate = "-30";
    align = "left";
    grid.right = grid.right + lastText.length * xAxis.axisLabel.fontSize;
  } else if (maxTextWdith > maxWdth * 1.5) {
    rotate = "-90";
    align = "left";
  }
  xAxis.axisLabel.rotate = rotate;
  xAxis.axisLabel.align = align;
  return { xAxis, grid };
};
const pieRadioAngle = (chartInstance, grid, chartType) => {
  const radius = computedRadioAngle(chartInstance, grid);
  if (chartType === PIE) {
    return radius;
  }
  if (chartType === RINGPIE) {
    return [(radius / 0.8) * 0.5, radius];
  }
};
export const computedRadioAngle = (chartInstance, grid) => {
  const { width, height } = chartInstance._dom.getBoundingClientRect();
  const nextWidth = width - grid.left - grid.right;
  const nextHeight = height - grid.top - grid.bottom;
  const nextSize = nextWidth > nextHeight ? nextHeight : nextWidth;
  return nextSize / 2 - 40;
};

export const ComputedGroupBarWidth = (series, dataset = { source: [] }) => {
  const maxBarWidth = dataset.source.length > 5 ? "40%" : "10%";
  return series.map((item) => {
    item.barWidth = maxBarWidth;
    return item;
  });
};

export const TransPieConfig = (
  {
    chartType,
    dataResult,
    iconConfig: {
      options: { series, grid, mergeData },
    },
  },
  chartInstance
) => {
  if (!dataResult)
    return {
      dataResult,
      series,
    };
  const { show, value } = mergeData || {
    show: true,
    value: 1,
  };
  series[0].radius = pieRadioAngle(chartInstance, grid, chartType);
  if (show === false) {
    return {
      dataResult,
      series,
    };
  }
  const newDataResult = cloneDeep(dataResult);
  const [dimensionKey, valueKey] = newDataResult.dimensions;
  const startSource = [];
  let otherValue = 0;
  // const otherSource = startSource.splice(20, startSource.length)
  const totalValue = dataResult.source.reduce((preValue, curVal) => {
    return preValue + (curVal[valueKey] || 0);
  }, 0);
  const limitValue = (value / 100) * totalValue;
  dataResult.source.forEach((item) => {
    if (item[valueKey] > limitValue) {
      startSource.push({
        [dimensionKey]: item[dimensionKey],
        [valueKey]: item[valueKey],
      });
    } else {
      otherValue = otherValue + item[valueKey];
    }
  });
  startSource.push({
    [dimensionKey]: "其它",
    [valueKey]: otherValue,
  });
  newDataResult.source = startSource;
  return { dataResult: newDataResult, series };
};
