/**
 * 图例相关函数模块
 * 用于计算图例数据和饼图相关文本长度
 */

// @ts-nocheck - 为了与原始 u-charts 代码保持兼容性，跳过类型检查

import type { ChartOptions, UChartsConfig, SeriesItem } from '../data-processing/index';
import { measureText } from '../utils/text';
import { getPieDataPoints } from '../charts-data/pie-charts';
import type { LegendData, LegendArea } from './types';
import { util } from '../config';

// 使用 any 类型来简化与原始 u-charts 代码的兼容性
type AnyChartOptions = any;

/**
 * 计算图例数据
 * @param series 数据系列
 * @param opts 图表配置选项
 * @param config 图表配置
 * @param chartData 图表数据
 * @param context Canvas上下文
 * @returns 图例数据
 */
export function calLegendData(
  series: SeriesItem[],
  opts: AnyChartOptions,
  config: UChartsConfig,
  chartData: any,
  context: any
): LegendData {
  const legendData: LegendData = {
    area: {
      start: { x: 0, y: 0 },
      end: { x: 0, y: 0 },
    } as LegendArea,
    points: [],
    widthArr: [],
    heightArr: [],
  };

  if (opts.legend.show === false) {
    chartData.legendData = legendData;
    return legendData;
  }

  const padding = opts.legend.padding * opts.pix;
  const margin = opts.legend.margin * opts.pix;
  const fontSize = opts.legend.fontSize
    ? opts.legend.fontSize * opts.pix
    : config.fontSize;
  const shapeWidth = 15 * opts.pix;
  const shapeRight = 5 * opts.pix;
  const lineHeight = Math.max(opts.legend.lineHeight * opts.pix, fontSize);

  if (opts.legend.position === 'top' || opts.legend.position === 'bottom') {
    const legendList: SeriesItem[][] = [];
    let widthCount = 0;
    const widthCountArr: number[] = [];
    const currentRow: SeriesItem[] = [];

    for (let i = 0; i < series.length; i++) {
      const item = series[i];
      const legendText = item.legendText ? item.legendText : item.name;
      const itemWidth =
        shapeWidth +
        shapeRight +
        measureText(legendText || 'undefined', fontSize, context) +
        opts.legend.itemGap * opts.pix;

      if (widthCount + itemWidth > opts.width - opts.area[1] - opts.area[3]) {
        legendList.push(currentRow.slice());
        widthCountArr.push(widthCount - opts.legend.itemGap * opts.pix);
        widthCount = itemWidth;
        currentRow.length = 0;
        currentRow.push(item);
      } else {
        widthCount += itemWidth;
        currentRow.push(item);
      }
    }

    if (currentRow.length) {
      legendList.push(currentRow.slice());
      widthCountArr.push(widthCount - opts.legend.itemGap * opts.pix);
      legendData.widthArr = widthCountArr;
      const legendWidth = Math.max.apply(null, widthCountArr);

      switch (opts.legend.float) {
        case 'left':
          legendData.area.start.x = opts.area[3];
          legendData.area.end.x = opts.area[3] + legendWidth + 2 * padding;
          break;
        case 'right':
          legendData.area.start.x =
            opts.width - opts.area[1] - legendWidth - 2 * padding;
          legendData.area.end.x = opts.width - opts.area[1];
          break;
        default:
          legendData.area.start.x = opts.width / 2 - legendWidth / 2 - padding;
          legendData.area.end.x = opts.width / 2 + legendWidth / 2 + padding;
      }

      legendData.area.width = legendWidth + 2 * padding;
      legendData.area.wholeWidth = legendWidth + 2 * padding;
      legendData.area.height = legendList.length * lineHeight + 2 * padding;
      legendData.area.wholeHeight =
        legendList.length * lineHeight + 2 * padding + 2 * margin;
      legendData.points = legendList;
    }
  } else {
    const len = series.length;
    const maxHeight =
      opts.height - opts.area[0] - opts.area[2] - 2 * margin - 2 * padding;
    const maxLength = Math.min(Math.floor(maxHeight / lineHeight), len);
    legendData.area.height = maxLength * lineHeight + padding * 2;
    legendData.area.wholeHeight = maxLength * lineHeight + padding * 2;

    switch (opts.legend.float) {
      case 'top':
        legendData.area.start.y = opts.area[0] + margin;
        legendData.area.end.y =
          opts.area[0] + margin + legendData.area.height;
        break;
      case 'bottom':
        legendData.area.start.y =
          opts.height - opts.area[2] - margin - legendData.area.height;
        legendData.area.end.y = opts.height - opts.area[2] - margin;
        break;
      default:
        legendData.area.start.y =
          (opts.height - legendData.area.height) / 2;
        legendData.area.end.y =
          (opts.height + legendData.area.height) / 2;
    }

    const lineNum =
      len % maxLength === 0
        ? len / maxLength
        : Math.floor(len / maxLength + 1);
    const currentRow: SeriesItem[][] = [];

    for (let i = 0; i < lineNum; i++) {
      const temp = series.slice(i * maxLength, i * maxLength + maxLength);
      currentRow.push(temp);
    }

    legendData.points = currentRow;

    if (currentRow.length) {
      for (let i = 0; i < currentRow.length; i++) {
        const item = currentRow[i];
        let maxWidth = 0;
        for (let j = 0; j < item.length; j++) {
          const itemWidth =
            shapeWidth +
            shapeRight +
            measureText(item[j].name || 'undefined', fontSize, context) +
            opts.legend.itemGap * opts.pix;
          if (itemWidth > maxWidth) {
            maxWidth = itemWidth;
          }
        }
        legendData.widthArr.push(maxWidth);
        legendData.heightArr.push(item.length * lineHeight + padding * 2);
      }

      let legendWidth = 0;
      for (let i = 0; i < legendData.widthArr.length; i++) {
        legendWidth += legendData.widthArr[i];
      }
      legendData.area.width =
        legendWidth - opts.legend.itemGap * opts.pix + 2 * padding;
      legendData.area.wholeWidth = legendData.area.width + padding;
    }
  }

  switch (opts.legend.position) {
    case 'top':
      legendData.area.start.y = opts.area[0] + margin;
      legendData.area.end.y = opts.area[0] + margin + legendData.area.height;
      break;
    case 'bottom':
      legendData.area.start.y =
        opts.height - opts.area[2] - legendData.area.height - margin;
      legendData.area.end.y = opts.height - opts.area[2] - margin;
      break;
    case 'left':
      legendData.area.start.x = opts.area[3];
      legendData.area.end.x = opts.area[3] + legendData.area.width;
      break;
    case 'right':
      legendData.area.start.x =
        opts.width - opts.area[1] - legendData.area.width;
      legendData.area.end.x = opts.width - opts.area[1];
      break;
  }

  chartData.legendData = legendData;
  return legendData;
}

/**
 * 获取饼图文本最大长度
 * @param series 数据系列
 * @param config 图表配置
 * @param context Canvas上下文
 * @param opts 图表配置选项
 * @returns 最大长度
 */
export function getPieTextMaxLength(
  series: SeriesItem[],
  config: UChartsConfig,
  context: any,
  opts: AnyChartOptions
): number {
  const processedSeries = getPieDataPoints(series);
  let maxLength = 0;
  for (let i = 0; i < processedSeries.length; i++) {
    const item = processedSeries[i];
    const text = item.formatter
      ? item.formatter(+item._proportion_.toFixed(2))
      : util.toFixed(item._proportion_ * 100) + '%';
    maxLength = Math.max(
      maxLength,
      measureText(text, item.textSize * opts.pix || config.fontSize, context)
    );
  }
  return maxLength;
}
