/**
 * 系列数据处理函数
 *
 * 从 u-charts 核心库搬迁的系列数据处理相关函数
 * 用于处理图表系列数据的填充、合并、颜色设置等操作
 */

// 类型定义
export interface SeriesItem {
  data: (number | null)[] | number[] | { value: number }[];
  name: string;
  color?: string;
  index?: number;
  linearIndex?: number;
  type?: string;
  show?: boolean;
  pointShape?: string;
  legendShape?: string;
  formatter?: (item: any, titleText: string, index: number, opts: ChartOptions) => string;
  style?: string;
  disableLegend?: boolean;
  connectNulls?: boolean;
  [key: string]: any;
}

export interface ChartOptions {
  type: string;
  categories?: string[];
  extra?: ChartExtraOptions;
  xAxis?: XAxisOptions;
  yAxis?: YAxisOptions;
  area: number[];
  width: number;
  height: number;
  pix: number;
  enableScroll?: boolean;
  chartData?: ChartData;
  background?: string;
  fontColor?: string;
  _scrollDistance_?: number;
  series?: any[];
  tooltip?: any;
  dataLabel?: boolean;
  title?: any;
  subtitle?: any;
  dataPointShapeType?: string;
  legend?: any;
  [key: string]: any;
}

export interface ChartExtraOptions {
  bar?: BarOptions;
  column?: ColumnOptions;
  tooltip?: TooltipOptions;
  mount?: MountOptions;
  [key: string]: any;
}

export interface BarOptions {
  type?: string;
  [key: string]: any;
}

export interface ColumnOptions {
  type?: 'group' | 'stack' | 'meter';
  width?: number;
  meterBorder?: number;
  meterFillColor?: string;
  barBorderCircle?: boolean;
  barBorderRadius?: number[];
  seriesGap?: number;
  linearType?: string;
  linearOpacity?: number;
  customColor?: string[];
  colorStop?: number;
  labelPosition?: string;
  borderWidth?: number;
  widthRatio?: number;
  [key: string]: any;
}

export interface TooltipOptions {
  legendShape?: string;
  [key: string]: any;
}

export interface MountOptions {
  widthRatio?: number;
  type?: 'bar' | 'triangle' | 'mount' | 'sharp';
  [key: string]: any;
}

export interface XAxisOptions {
  lineHeight?: number;
  marginTop?: number;
  fontSize?: number;
  disabled?: boolean;
  rotateLabel?: boolean;
  rotateAngle?: number;
  scrollShow?: boolean;
  boundaryGap?: string;
  itemCount?: number;
  splitNumber?: number;
  formatter?: (item: any, index: number, opts: ChartOptions) => string;
  [key: string]: any;
}

export interface YAxisOptions {
  fontSize?: number;
  disabled?: boolean;
  data?: YAxisDataItem[];
  formatter?: (val: number, index: number, opts: ChartOptions) => string;
  tofix?: number;
  unit?: string;
  min?: number;
  max?: number;
  [key: string]: any;
}

export interface YAxisDataItem {
  type?: string;
  disabled?: boolean;
  formatter?: (val: any, index: number, opts: ChartOptions) => string;
  categories?: string[];
  tofix?: number;
  unit?: string;
  min?: number;
  max?: number;
  position?: string;
  calibration?: boolean;
  fontSize?: number;
  textAlign?: string;
  axisLineColor?: string;
  fontColor?: string;
  axisLine?: boolean;
  titleFontSize?: number;
  title?: string;
  titleFontColor?: string;
  titleOffsetX?: number;
  titleOffsetY?: number;
}

export interface ChartData {
  calPoints?: any[][];
  xAxisPoints?: number[];
  eachSpacing?: number;
  [key: string]: any;
}

export interface UChartsConfig {
  version: string;
  color: string[];
  linearColor: string[];
  yAxisWidth: number;
  xAxisHeight: number;
  padding: number[];
  rotate: boolean;
  fontSize: number;
  fontColor: string;
  dataPointShape: string[];
  pieChartLinePadding: number;
  pieChartTextPadding: number;
  titleFontSize: number;
  subtitleFontSize: number;
  radarLabelTextMargin: number;
  toolTipBackground?: string;
  toolTipOpacity?: number;
  _pieTextMaxLength_?: number;
  _xAxisTextAngle_?: number;
}

export interface DataRange {
  minRange: number;
  maxRange: number;
}

/**
 * 修复饼图系列数据
 * 处理饼图的百分比和累计值
 *
 * @param series - 系列数据数组
 * @param opts - 图表配置选项
 * @param config - uCharts配置对象
 * @returns 修复后的系列数据数组
 */
export function fixPieSeries(
  series: SeriesItem[],
  opts: ChartOptions,
  config: UChartsConfig
): SeriesItem[] {
  const pieSeriesArr: SeriesItem[] = [];
  if (series.length > 0 && series[0].data.constructor.toString().indexOf('Array') > -1) {
    (opts as any)._pieSeries_ = series;
    const oldseries = series[0].data as any[];
    for (let i = 0; i < oldseries.length; i++) {
      oldseries[i].formatter = series[0].formatter;
      oldseries[i].data = oldseries[i].value;
      pieSeriesArr.push(oldseries[i]);
    }
    opts.series = pieSeriesArr;
  } else {
    return series;
  }
  return pieSeriesArr;
}

/**
 * 填充系列数据
 * 确保所有系列数据都有完整的属性配置
 *
 * @param series - 系列数据数组
 * @param opts - 图表配置选项
 * @param config - uCharts配置对象
 * @returns 填充后的系列数据数组
 */
export function fillSeries(
  series: SeriesItem[],
  opts: ChartOptions,
  config: UChartsConfig
): SeriesItem[] {
  let index = 0;
  for (let i = 0; i < series.length; i++) {
    const item = series[i];
    if (!item.color) {
      item.color = config.color[index];
      index = (index + 1) % config.color.length;
    }
    if (!item.linearIndex) {
      item.linearIndex = i;
    }
    if (!item.index) {
      item.index = 0;
    }
    if (!item.type) {
      item.type = opts.type;
    }
    if (typeof item.show === "undefined") {
      item.show = true;
    }
    if (!item.type) {
      item.type = opts.type;
    }
    if (!item.pointShape) {
      item.pointShape = "circle";
    }
    if (!item.legendShape) {
      switch (item.type) {
        case 'line':
          item.legendShape = "line";
          break;
        case 'column':
        case 'bar':
          item.legendShape = "rect";
          break;
        case 'area':
        case 'mount':
          item.legendShape = "triangle";
          break;
        default:
          item.legendShape = "circle";
      }
    }
  }
  return series;
}

/**
 * 填充自定义颜色
 * 为系列数据设置自定义颜色或使用默认渐变色
 *
 * @param linearType - 线性类型 ('custom' 或其他)
 * @param customColor - 自定义颜色数组
 * @param series - 系列数据数组
 * @param config - uCharts配置对象
 * @returns 颜色数组
 */
export function fillCustomColor(
  linearType: string,
  customColor: string[],
  series: SeriesItem[],
  config: UChartsConfig
): string[] {
  let newcolor = customColor || [];
  if (linearType == 'custom' && newcolor.length == 0) {
    newcolor = config.linearColor;
  }
  if (linearType == 'custom' && newcolor.length < series.length) {
    const chazhi = series.length - newcolor.length;
    for (let i = 0; i < chazhi; i++) {
      newcolor.push(config.linearColor[(i + 1) % config.linearColor.length]);
    }
  }
  return newcolor;
}

/**
 * 获取数据范围
 * 计算最小值和最大值的范围
 *
 * @param minData - 最小数据值
 * @param maxData - 最大数据值
 * @returns 数据范围对象
 */
export function getDataRange(minData: number, maxData: number): DataRange {
  let limit = 0;
  const range = maxData - minData;
  if (range >= 10000) {
    limit = 1000;
  } else if (range >= 1000) {
    limit = 100;
  } else if (range >= 100) {
    limit = 10;
  } else if (range >= 10) {
    limit = 5;
  } else if (range >= 1) {
    limit = 1;
  } else if (range >= 0.1) {
    limit = 0.1;
  } else if (range >= 0.01) {
    limit = 0.01;
  } else if (range >= 0.001) {
    limit = 0.001;
  } else if (range >= 0.0001) {
    limit = 0.0001;
  } else if (range >= 0.00001) {
    limit = 0.00001;
  } else {
    limit = 0.000001;
  }
  return {
    minRange: findRange(minData, 'lower', limit),
    maxRange: findRange(maxData, 'upper', limit)
  };
}

/**
 * 查找范围边界
 * 根据类型和限制查找合适的边界值
 *
 * @param num - 数值
 * @param type - 类型 ('upper' 或 'lower')
 * @param limit - 限制值
 * @returns 边界值
 */
function findRange(num: number, type: 'upper' | 'lower', limit: number): number {
  if (isNaN(num)) {
    throw new Error('[uCharts] series数据需为Number格式');
  }
  limit = limit || 10;
  type = type ? type : 'upper';
  let multiple = 1;
  while (limit < 1) {
    limit *= 10;
    multiple *= 10;
  }
  if (type === 'upper') {
    num = Math.ceil(num * multiple);
  } else {
    num = Math.floor(num * multiple);
  }
  while (num % limit !== 0) {
    if (type === 'upper') {
      if (num == num + 1) {
        break;
      }
      num++;
    } else {
      num--;
    }
  }
  return num / multiple;
}

/**
 * 数据合并
 * 合并多个系列的数据
 *
 * @param series - 系列数据数组
 * @returns 合并后的数据数组
 */
export function dataCombine(series: SeriesItem[]): (number | null)[] {
  return series.reduce(function(a, b) {
    return (a.data ? a.data : a).concat(b.data);
  }, [] as any);
}

/**
 * 堆叠数据合并
 * 处理堆叠图表的数据合并
 *
 * @param series - 系列数据数组
 * @param len - 数据长度
 * @returns 合并后的数据数组
 */
export function dataCombineStack(
  series: SeriesItem[],
  len: number
): (number | null)[] {
  const sum = new Array(len);
  for (let j = 0; j < sum.length; j++) {
    sum[j] = 0;
  }
  for (let i = 0; i < series.length; i++) {
    for (let j = 0; j < sum.length; j++) {
      sum[j] += (series[i].data as number[])[j];
    }
  }
  return series.reduce(function(a, b) {
    return (a.data ? a.data : a).concat(b.data).concat(sum);
  }, [] as any);
}
