"use strict";
var import_closestPointPlugin = require("../../../../closestPointPlugin.css");
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const _ = require("lodash");
const throttleDebounce = require("throttle-debounce");
const kit_internal_functions = require("../../functions.cjs");
const point = "closestPointPlugin_point_1c58e";
const tooltip = "closestPointPlugin_tooltip_1c58e";
const box = "closestPointPlugin_box_1c58e";
const top = "closestPointPlugin_top_1c58e";
const left = "closestPointPlugin_left_1c58e";
const css = {
  point,
  tooltip,
  box,
  top,
  left
};
const closestPointPlugin = ({
  distInPx = 30,
  getPointTooltipHTML,
  onPointClick,
  onPointFocus,
  pointSizeInPx = 7,
  yScale,
  checkpointsDict
}) => {
  let distValX;
  let distValY;
  let focusedPoint;
  let pointEl;
  let tooltipEl;
  const findClosestPoint = (uPlot2, cursorLeft, cursorTop) => {
    let closestDistance = Number.MAX_VALUE;
    let closestPoint;
    const shownData = uPlot2.data.slice(1).filter((_2, idx) => uPlot2.series[idx + 1].show);
    const cursorValX = uPlot2.posToVal(cursorLeft, "x");
    const idxMax = kit_internal_functions.findInsertionIndex(uPlot2.data[0], cursorValX + distValX) - 1;
    const idxMin = kit_internal_functions.findInsertionIndex(uPlot2.data[0], cursorValX - distValX);
    const cursorValY = uPlot2.posToVal(cursorTop, yScale);
    const yValMax = cursorValY + distValY;
    const yValMin = cursorValY - distValY;
    for (let idx = idxMin; idx <= idxMax; idx++) {
      const posX = uPlot2.valToPos(uPlot2.data[0][idx], "x");
      for (let seriesIdx = 0; seriesIdx < shownData.length; seriesIdx++) {
        const yVal = shownData[seriesIdx][idx];
        if (yVal && yVal >= yValMin && yVal <= yValMax) {
          const posY = uPlot2.valToPos(yVal, yScale);
          const yValDistance = kit_internal_functions.distance(posX, posY, cursorLeft, cursorTop);
          if (yValDistance < closestDistance) {
            closestDistance = yValDistance;
            closestPoint = { idx, seriesIdx };
          }
        }
      }
    }
    return closestPoint;
  };
  const focusPoint = (uPlot2, point2) => {
    focusedPoint = point2;
    if (typeof onPointFocus === "function") {
      onPointFocus(focusedPoint);
    }
    const series = point2 && uPlot2.series[point2.seriesIdx];
    const xVal = point2 && uPlot2.data[0][point2.idx];
    const yVal = point2 && uPlot2.data[point2.seriesIdx][point2.idx];
    const xPos = point2 && uPlot2.valToPos(uPlot2.data[0][point2.idx], "x");
    const yPos = yVal && uPlot2.valToPos(yVal, yScale);
    if (!point2 || !series || xVal == null || yVal == null || xPos == null || yPos == null || !!(checkpointsDict == null ? void 0 : checkpointsDict[xVal])) {
      pointEl.style.display = "none";
      tooltipEl.style.display = "none";
      return;
    }
    if (pointSizeInPx > 0) {
      pointEl.style.backgroundColor = typeof series.stroke === "function" ? series.stroke(uPlot2, point2.seriesIdx) : "rgba(0, 155, 222, 1)";
      pointEl.style.display = "block";
      pointEl.style.height = pointSizeInPx + "px";
      pointEl.style.left = xPos + "px";
      pointEl.style.top = yPos + "px";
      pointEl.style.width = pointSizeInPx + "px";
    }
    const tooltipHtml = typeof getPointTooltipHTML === "function" && getPointTooltipHTML(xVal, yVal, point2);
    if (tooltipHtml) {
      const classes = [css.tooltip];
      if (xPos > uPlot2.bbox.width / 2 / window.devicePixelRatio)
        classes.push(css.left);
      if (yPos > uPlot2.bbox.height / 2 / window.devicePixelRatio)
        classes.push(css.top);
      tooltipEl.className = classes.join(" ");
      tooltipEl.innerHTML = `<div class="${css.box}">${tooltipHtml}</div>`;
      tooltipEl.style.display = "block";
      tooltipEl.style.left = xPos + "px";
      tooltipEl.style.top = yPos + "px";
    } else {
      tooltipEl.style.display = "none";
    }
  };
  const handleCursorMove = throttleDebounce.throttle(50, (uPlot2) => {
    const { left: left2, idx, top: top2 } = uPlot2.cursor;
    if (!left2 || left2 < 0 || !top2 || top2 < 0 || idx == null) {
      if (focusedPoint)
        focusPoint(uPlot2, void 0);
      return;
    }
    const point2 = findClosestPoint(uPlot2, left2, top2);
    if (!point2) {
      if (focusedPoint)
        focusPoint(uPlot2, void 0);
      return;
    }
    if (!_.isEqual(point2, focusedPoint)) {
      focusPoint(uPlot2, point2);
    }
  });
  return {
    hooks: {
      ready: (uPlot2) => {
        const over = uPlot2.root.querySelector(".u-over");
        if (!over)
          return;
        pointEl = document.createElement("div");
        pointEl.className = css.point;
        over.appendChild(pointEl);
        tooltipEl = document.createElement("div");
        over.appendChild(tooltipEl);
        if (typeof onPointClick === "function") {
          let mousedownX;
          let mousedownY;
          over.addEventListener("mousedown", (e) => {
            mousedownX = e.clientX;
            mousedownY = e.clientY;
          });
          over.addEventListener("mouseup", (e) => {
            if (e.clientX !== mousedownX || e.clientY !== mousedownY || !focusedPoint)
              return;
            onPointClick(e, focusedPoint);
          });
        }
      },
      setCursor: (uPlot2) => handleCursorMove(uPlot2),
      setScale: (uPlot2) => {
        const xMax = uPlot2.scales.x.max ?? 100;
        const xMin = uPlot2.scales.x.min ?? 0;
        distValX = (xMax - xMin) / 20;
        distValY = uPlot2.posToVal(0, yScale) - uPlot2.posToVal(distInPx, yScale);
      }
    }
  };
};
exports.closestPointPlugin = closestPointPlugin;
