/**
 * 索引查找函数模块
 * 用于查找不同类型图表的当前数据索引
 */

// @ts-nocheck - 为了与原始 u-charts 代码保持兼容性，跳过类型检查
// 这些函数直接从 u-charts.ts 迁移，保持原有逻辑不变

import type { ChartOptions, UChartsConfig } from '../data-processing/index';
import type { PieData, RadarData, LegendData } from './types';
import { getPieDataPoints, getRoseDataPoints } from '../charts-data/pie-charts';
import { isInAngleRange } from '../utils/coordinate';
import {
  isInExactLegendArea,
  isInExactChartArea,
  isInExactPieChartArea,
} from './area-checkers';
import { pointToCoordinate, isPoiWithinPoly } from './coordinate-helpers';

/**
 * 查找当前数据索引
 * @param currentPoints 当前触摸点坐标
 * @param calPoints 计算后的数据点
 * @param opts 图表配置选项
 * @param config 图表配置
 * @param offset 偏移量
 * @returns 当前索引和分组信息
 */
export function findCurrentIndex(
  currentPoints: { x: number; y: number },
  calPoints: Array<Array<{ x: number; y: number }>>,
  opts: ChartOptions,
  config: UChartsConfig,
  offset: number = 0
): { index: number | number[]; group: number[] } {
  const current: { index: number | number[]; group: number[] } = {
    index: -1,
    group: [],
  };
  let spacing = opts.chartData.eachSpacing / 2;
  const xAxisPoints: number[] = [];

  if (calPoints && calPoints.length > 0) {
    if (!opts.categories) {
      spacing = 0;
    } else {
      for (let i = 1; i < opts.chartData.xAxisPoints.length; i++) {
        xAxisPoints.push(opts.chartData.xAxisPoints[i] - spacing);
      }
      if (
        (opts.type === 'line' || opts.type === 'area') &&
        opts.xAxis.boundaryGap === 'justify'
      ) {
        xAxisPoints.length = 0;
        opts.chartData.xAxisPoints.forEach((p: number) => xAxisPoints.push(p));
      }
    }

    if (isInExactChartArea(currentPoints, opts, config)) {
      if (!opts.categories) {
        const timePoints = Array(calPoints.length);
        for (let i = 0; i < calPoints.length; i++) {
          timePoints[i] = Array(calPoints[i].length);
          for (let j = 0; j < calPoints[i].length; j++) {
            timePoints[i][j] = Math.abs(calPoints[i][j].x - currentPoints.x);
          }
        }
        const pointValue = Array(timePoints.length);
        const pointIndex = Array(timePoints.length);
        for (let i = 0; i < timePoints.length; i++) {
          pointValue[i] = Math.min.apply(null, timePoints[i]);
          pointIndex[i] = timePoints[i].indexOf(pointValue[i] as number);
        }
        const minValue = Math.min.apply(null, pointValue);
        current.index = [];
        for (let i = 0; i < pointValue.length; i++) {
          if (pointValue[i] === minValue) {
            current.group.push(i);
            (current.index as number[]).push(pointIndex[i] as number);
          }
        }
      } else {
        xAxisPoints.forEach(function (item, index) {
          if (currentPoints.x + offset + spacing > item) {
            current.index = index;
          }
        });
      }
    }
  }
  return current;
}

/**
 * 查找柱状图当前索引
 * @param currentPoints 当前触摸点坐标
 * @param calPoints 计算后的数据点
 * @param opts 图表配置选项
 * @param config 图表配置
 * @param offset 偏移量
 * @returns 当前索引和分组信息
 */
export function findBarChartCurrentIndex(
  currentPoints: { x: number; y: number },
  calPoints: Array<Array<{ x: number; y: number }>>,
  opts: ChartOptions,
  config: UChartsConfig,
  offset: number = 0
): { index: number; group: number[] } {
  const current: { index: number; group: number[] } = { index: -1, group: [] };
  const spacing = opts.chartData.eachSpacing / 2;
  const yAxisPoints = opts.chartData.yAxisPoints;

  if (calPoints && calPoints.length > 0) {
    if (isInExactChartArea(currentPoints, opts, config)) {
      yAxisPoints.forEach(function (item, index) {
        if (currentPoints.y + offset + spacing > item) {
          current.index = index;
        }
      });
    }
  }
  return current;
}

/**
 * 查找图例索引
 * @param currentPoints 当前触摸点坐标
 * @param legendData 图例数据
 * @param opts 图表配置选项
 * @returns 图例索引
 */
export function findLegendIndex(
  currentPoints: { x: number; y: number },
  legendData: LegendData,
  opts: ChartOptions
): number {
  let currentIndex = -1;
  const gap = 0;

  if (isInExactLegendArea(currentPoints, legendData.area)) {
    const points = legendData.points;
    let index = -1;
    for (let i = 0, len = points.length; i < len; i++) {
      const item = points[i];
      for (let j = 0; j < item.length; j++) {
        index += 1;
        const area = item[j]['area'];
        if (
          area &&
          currentPoints.x > area[0] - gap &&
          currentPoints.x < area[2] + gap &&
          currentPoints.y > area[1] - gap &&
          currentPoints.y < area[3] + gap
        ) {
          currentIndex = index;
          break;
        }
      }
    }
    return currentIndex;
  }
  return currentIndex;
}

/**
 * 查找雷达图当前索引
 * @param currentPoints 当前触摸点坐标
 * @param radarData 雷达图数据
 * @param count 数据数量
 * @returns 当前索引
 */
export function findRadarChartCurrentIndex(
  currentPoints: { x: number; y: number },
  radarData: RadarData,
  count: number
): number {
  const eachAngleArea = (2 * Math.PI) / count;
  let currentIndex = -1;

  if (
    isInExactPieChartArea(currentPoints, radarData.center, radarData.radius)
  ) {
    const fixAngle = function (angle: number): number {
      if (angle < 0) {
        angle += 2 * Math.PI;
      }
      if (angle > 2 * Math.PI) {
        angle -= 2 * Math.PI;
      }
      return angle;
    };

    let angle = Math.atan2(
      radarData.center.y - currentPoints.y,
      currentPoints.x - radarData.center.x
    );
    angle = -1 * angle;
    if (angle < 0) {
      angle += 2 * Math.PI;
    }

    const angleList = radarData.angleList.map(function (item) {
      return fixAngle(-1 * item);
    });

    angleList.forEach(function (item, index) {
      const rangeStart = fixAngle(item - eachAngleArea / 2);
      const rangeEnd = fixAngle(item + eachAngleArea / 2);
      let rangeEndAdjusted = rangeEnd;
      if (rangeEndAdjusted < rangeStart) {
        rangeEndAdjusted += 2 * Math.PI;
      }
      if (
        (angle >= rangeStart && angle <= rangeEndAdjusted) ||
        (angle + 2 * Math.PI >= rangeStart &&
          angle + 2 * Math.PI <= rangeEndAdjusted)
      ) {
        currentIndex = index;
      }
    });
  }
  return currentIndex;
}

/**
 * 查找漏斗图当前索引
 * @param currentPoints 当前触摸点坐标
 * @param funnelData 漏斗图数据
 * @returns 当前索引
 */
export function findFunnelChartCurrentIndex(
  currentPoints: { x: number; y: number },
  funnelData: { series: Array<{ funnelArea: number[] }> }
): number {
  let currentIndex = -1;
  for (let i = 0, len = funnelData.series.length; i < len; i++) {
    const item = funnelData.series[i];
    if (
      currentPoints.x > item.funnelArea[0] &&
      currentPoints.x < item.funnelArea[2] &&
      currentPoints.y > item.funnelArea[1] &&
      currentPoints.y < item.funnelArea[3]
    ) {
      currentIndex = i;
      break;
    }
  }
  return currentIndex;
}

/**
 * 查找词云图当前索引
 * @param currentPoints 当前触摸点坐标
 * @param wordData 词云图数据
 * @returns 当前索引
 */
export function findWordChartCurrentIndex(
  currentPoints: { x: number; y: number },
  wordData: Array<{ area: number[] }>
): number {
  let currentIndex = -1;
  for (let i = 0, len = wordData.length; i < len; i++) {
    const item = wordData[i];
    if (
      currentPoints.x > item.area[0] &&
      currentPoints.x < item.area[2] &&
      currentPoints.y > item.area[1] &&
      currentPoints.y < item.area[3]
    ) {
      currentIndex = i;
      break;
    }
  }
  return currentIndex;
}

/**
 * 查找地图当前索引
 * @param currentPoints 当前触摸点坐标
 * @param opts 图表配置选项
 * @returns 当前索引
 */
export function findMapChartCurrentIndex(
  currentPoints: { x: number; y: number },
  opts: ChartOptions
): number {
  let currentIndex = -1;
  const cData = opts.chartData.mapData;
  const data = opts.series;
  const tmp = pointToCoordinate(
    currentPoints.y,
    currentPoints.x,
    cData.bounds,
    cData.scale,
    cData.xoffset,
    cData.yoffset
  );
  const poi = [tmp.x, tmp.y];

  for (let i = 0, len = data.length; i < len; i++) {
    const item = data[i].geometry.coordinates;
    if (isPoiWithinPoly(poi, item, opts.chartData.mapData.mercator)) {
      currentIndex = i;
      break;
    }
  }
  return currentIndex;
}

/**
 * 查找玫瑰图当前索引
 * @param currentPoints 当前触摸点坐标
 * @param pieData 饼图数据
 * @param opts 图表配置选项
 * @returns 当前索引
 */
export function findRoseChartCurrentIndex(
  currentPoints: { x: number; y: number },
  pieData: PieData,
  opts: ChartOptions
): number {
  let currentIndex = -1;
  const series = getRoseDataPoints(
    opts._series_,
    opts.extra.rose?.type || 'area',
    pieData.radius,
    pieData.radius
  );

  if (
    pieData &&
    pieData.center &&
    isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)
  ) {
    let angle = Math.atan2(
      pieData.center.y - currentPoints.y,
      currentPoints.x - pieData.center.x
    );
    angle = -angle;
    if (opts.extra.rose && opts.extra.rose.offsetAngle) {
      angle = angle - (opts.extra.rose.offsetAngle * Math.PI) / 180;
    }
    for (let i = 0, len = series.length; i < len; i++) {
      if (
        isInAngleRange(
          angle,
          series[i]._start_,
          series[i]._start_ + series[i]._rose_proportion_ * 2 * Math.PI
        )
      ) {
        currentIndex = i;
        break;
      }
    }
  }
  return currentIndex;
}

/**
 * 查找饼图当前索引
 * @param currentPoints 当前触摸点坐标
 * @param pieData 饼图数据
 * @param opts 图表配置选项
 * @returns 当前索引
 */
export function findPieChartCurrentIndex(
  currentPoints: { x: number; y: number },
  pieData: PieData,
  opts: ChartOptions
): number {
  let currentIndex = -1;
  const series = getPieDataPoints(pieData.series);

  if (
    pieData &&
    pieData.center &&
    isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)
  ) {
    let angle = Math.atan2(
      pieData.center.y - currentPoints.y,
      currentPoints.x - pieData.center.x
    );
    angle = -angle;
    if (opts.extra.pie && opts.extra.pie.offsetAngle) {
      angle = angle - (opts.extra.pie.offsetAngle * Math.PI) / 180;
    }
    if (opts.extra.ring && opts.extra.ring.offsetAngle) {
      angle = angle - (opts.extra.ring.offsetAngle * Math.PI) / 180;
    }
    for (let i = 0, len = series.length; i < len; i++) {
      if (
        isInAngleRange(
          angle,
          series[i]._start_,
          series[i]._start_ + series[i]._proportion_ * 2 * Math.PI
        )
      ) {
        currentIndex = i;
        break;
      }
    }
  }
  return currentIndex;
}
