import { useState, useRef, useCallback, useEffect, useId, type ReactNode } from 'react';
import styles from './tooltip.module.css';

type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';

interface TooltipProps {
  readonly content: string;
  readonly position?: TooltipPosition;
  readonly delay?: number;
  readonly children: ReactNode;
}

export function Tooltip({
  content,
  position = 'top',
  delay = 300,
  children,
}: TooltipProps) {
  const [visible, setVisible] = useState(false);
  const [adjustedPosition, setAdjustedPosition] = useState<TooltipPosition>(position);
  const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const wrapperRef = useRef<HTMLDivElement>(null);
  const tooltipId = useId();

  const clearTimer = useCallback(() => {
    if (timerRef.current !== null) {
      clearTimeout(timerRef.current);
      timerRef.current = null;
    }
  }, []);

  const show = useCallback(() => {
    clearTimer();
    timerRef.current = setTimeout(() => {
      // Adjust position if element is near viewport edge
      if (wrapperRef.current) {
        const rect = wrapperRef.current.getBoundingClientRect();
        let resolved = position;
        if (position === 'top' && rect.top < 40) {
          resolved = 'bottom';
        } else if (position === 'bottom' && rect.bottom > window.innerHeight - 40) {
          resolved = 'top';
        } else if (position === 'left' && rect.left < 100) {
          resolved = 'right';
        } else if (position === 'right' && rect.right > window.innerWidth - 100) {
          resolved = 'left';
        }
        setAdjustedPosition(resolved);
      }
      setVisible(true);
    }, delay);
  }, [clearTimer, delay, position]);

  const hide = useCallback(() => {
    clearTimer();
    setVisible(false);
  }, [clearTimer]);

  useEffect(() => {
    return clearTimer;
  }, [clearTimer]);

  return (
    <div
      ref={wrapperRef}
      className={styles.wrapper}
      onMouseEnter={show}
      onMouseLeave={hide}
      onFocus={show}
      onBlur={hide}
    >
      <span aria-describedby={visible ? tooltipId : undefined}>
        {children}
      </span>
      {visible && (
        <div
          id={tooltipId}
          role="tooltip"
          className={`${styles.tooltip} ${styles[adjustedPosition]}`}
        >
          {content}
        </div>
      )}
    </div>
  );
}
