import { isUndefined } from '../../../internal/type-checks.mjs';

function Interpolate(chart, e, options) {
  const items = [];
  for (let datasetIndex = 0; datasetIndex < chart.data.datasets.length; datasetIndex++) {
    chart.data.datasets[datasetIndex].interpolatedXValue = void 0;
    chart.data.datasets[datasetIndex].interpolatedYValue = void 0;
    const meta = chart.getDatasetMeta(datasetIndex);
    if (meta.hidden) {
      continue;
    }
    if (!meta.xAxisID || !meta.yAxisID) {
      continue;
    }
    const xScale = chart.scales[meta.xAxisID];
    const yScale = chart.scales[meta.yAxisID];
    const xValue = xScale.getValueForPixel(e.x);
    const yValue = yScale.getValueForPixel(e.y);
    if (xScale.type !== "linear" && yScale.type !== "time") {
      continue;
    }
    if (isUndefined(xValue) || isUndefined(yValue)) {
      continue;
    }
    if (xValue > xScale.max || xValue < xScale.min || yValue > yScale.max || yValue < yScale.min) {
      continue;
    }
    const data = chart.data.datasets[datasetIndex].data;
    const index = data.findIndex((d) => d.x >= xValue);
    if (index === -1) {
      continue;
    }
    const prev = data[index - 1];
    const next = data[index];
    let interpolatedValue = NaN;
    if (prev && next) {
      const slope = (next.y - prev.y) / (next.x - prev.x);
      interpolatedValue = prev.y + (xValue - prev.x) * slope;
    }
    if (chart.data.datasets[datasetIndex].steppedLine && prev) {
      interpolatedValue = prev.y;
    }
    if (isNaN(interpolatedValue)) {
      continue;
    }
    const yPosition = yScale.getPixelForValue(interpolatedValue);
    if (isNaN(yPosition)) {
      continue;
    }
    const fakePoint = {
      hasValue: function() {
        return true;
      },
      tooltipPosition: function() {
        return this._model;
      },
      getCenterPoint: function() {
        return this._model;
      },
      inRange(mouseX, mouseY) {
        return Math.pow(mouseX - this._model.x, 2) + Math.pow(mouseY - this._model.y, 2) < Math.pow(20, 2);
      },
      _model: { x: e.x, y: yPosition },
      skip: false,
      stop: false,
      options: { hitRadius: 20 },
      x: xValue,
      y: interpolatedValue
    };
    if (options.intersect && !fakePoint.inRange(e.x, e.y)) {
      continue;
    }
    chart.data.datasets[datasetIndex].interpolatedXValue = xValue;
    chart.data.datasets[datasetIndex].interpolatedYValue = interpolatedValue;
    items.push({ datasetIndex, element: fakePoint, index: 0 });
  }
  return items;
}

export { Interpolate as default };
