/**
 * Shared chart interaction helpers for Pro calculators.
 */

export function mapHoverClientXToScalar(clientX, overlayRect, maxValue) {
  if (!overlayRect || !Number.isFinite(maxValue) || maxValue <= 0) {
    return 0;
  }

  const overlayWidth = Number(overlayRect.width) || 0;
  if (overlayWidth <= 0) {
    return 0;
  }

  const mouseXOnOverlay = Math.max(
    0,
    Math.min(overlayWidth, clientX - overlayRect.left),
  );
  return (mouseXOnOverlay / overlayWidth) * maxValue;
}

export function findNearestPoint(points, target, getKey = (point) => point) {
  if (!Array.isArray(points) || points.length === 0 || !Number.isFinite(target)) {
    return null;
  }

  let nearest = points[0];
  let minDistance = Math.abs(Number(getKey(nearest)) - target);

  for (let index = 1; index < points.length; index += 1) {
    const point = points[index];
    const keyValue = Number(getKey(point));
    if (!Number.isFinite(keyValue)) {
      continue;
    }

    const distance = Math.abs(keyValue - target);
    if (distance < minDistance) {
      nearest = point;
      minDistance = distance;
    }
  }

  return nearest;
}

export function positionChartTooltip(tooltip, clientX, clientY, containerRect, options = {}) {
  if (!tooltip || !containerRect) {
    return null;
  }

  const offsetX = Number.isFinite(options.offsetX) ? options.offsetX : 12;
  const offsetY = Number.isFinite(options.offsetY) ? options.offsetY : 8;
  const minLeft = Number.isFinite(options.minLeft) ? options.minLeft : 4;
  const minTop = Number.isFinite(options.minTop) ? options.minTop : 0;
  const edgePadding = Number.isFinite(options.edgePadding) ? options.edgePadding : 4;

  const mouseXInContainer = clientX - containerRect.left;
  const mouseYInContainer = clientY - containerRect.top;
  const tooltipWidth = tooltip.offsetWidth || 0;
  const containerWidth = containerRect.width || 0;

  let left = mouseXInContainer + offsetX;
  if (left + tooltipWidth > containerWidth - edgePadding) {
    left = mouseXInContainer - tooltipWidth - offsetX;
  }
  left = Math.max(minLeft, left);

  const top = Math.max(minTop, mouseYInContainer - (tooltip.offsetHeight || 0) - offsetY);

  tooltip.style.left = `${left}px`;
  tooltip.style.top = `${top}px`;

  return { left, top };
}
