import { useState } from 'react';

const TOOLTIP_OFFSET = 10;
const MIN_VISIBLE_HEIGHT = 100;

interface ITooltipPosition {
  x: number;
  y: number;
}

interface ITooltipState<T> {
  item: T | null;
  position: ITooltipPosition;
}

export const useTooltipPosition = <T>() => {
  // Dynamically calculate tooltip width based on screen size
  const getTooltipWidth = (): number => {
    const viewportWidth = window.innerWidth;
    if (viewportWidth < 360) {
      return Math.min(280, viewportWidth - 20);
    }
    if (viewportWidth < 480) {
      return 300;
    }
    return 320;
  };

  const TOOLTIP_WIDTH = getTooltipWidth();

  const [tooltipState, setTooltipState] = useState<ITooltipState<T> | null>(
    null
  );

  const calculateTooltipPosition = (rect: DOMRect): ITooltipPosition => {
    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;
    const tooltipWidth = getTooltipWidth();

    // Try to position to the right first
    let x = rect.right + TOOLTIP_OFFSET;

    // If it would overflow right, try positioning to the left
    if (x + tooltipWidth > viewportWidth - TOOLTIP_OFFSET) {
      x = rect.left - tooltipWidth - TOOLTIP_OFFSET;
    }

    // If left positioning would go off screen, center it or position relative to viewport
    if (x < TOOLTIP_OFFSET) {
      if (viewportWidth < 400) {
        // For very small screens, center the tooltip
        x = Math.max(TOOLTIP_OFFSET, (viewportWidth - tooltipWidth) / 2);
      } else {
        x = TOOLTIP_OFFSET;
      }
    }

    // Position vertically aligned with the top of the element
    let y = rect.top;

    // Ensure tooltip doesn't go above viewport
    if (y < TOOLTIP_OFFSET) {
      y = TOOLTIP_OFFSET;
    }

    // Ensure some part of tooltip is always visible if element is near bottom
    if (y > viewportHeight - MIN_VISIBLE_HEIGHT) {
      y = viewportHeight - MIN_VISIBLE_HEIGHT;
    }

    return { x, y };
  };

  const handleMouseEnter = (item: T, event: React.MouseEvent) => {
    const rect = event.currentTarget.getBoundingClientRect();
    setTooltipState({
      item,
      position: calculateTooltipPosition(rect),
    });
  };

  const handleMouseLeave = () => {
    setTooltipState(null);
  };

  return {
    tooltipState,
    handleMouseEnter,
    handleMouseLeave,
    TOOLTIP_WIDTH,
  };
};
