import { xpayShadowRoot } from "@src/config";
import { FC, RefObject, useEffect, useState } from "react";
import { createPortal } from "react-dom";

type Position = "TOP" | "BOTTOM" | "LEFT" | "RIGHT";

const positionToClass: Record<Position, string> = {
  TOP: "-translate-x-1/2 -translate-y-full",
  BOTTOM: "-translate-x-1/2",
  LEFT: "-translate-x-full -translate-y-1/2",
  RIGHT: "-translate-y-1/2",
};

export const Tooltip: FC<{
  id: string;
  position: Position;
  text: string;
  triggerRef: RefObject<Element>;
}> = ({ id, position, text, triggerRef }) => {
  const [positionPx, setPositionPx] = useState({ top: 0, left: 0 });
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const trigger = triggerRef.current;

    const updatePosition = () => {
      if (!trigger) {
        return;
      }

      const rect = trigger.getBoundingClientRect();
      switch (position) {
        case "TOP": {
          setPositionPx({
            top: rect.top,
            left: rect.left + rect.width / 2,
          });
          break;
        }
        case "BOTTOM": {
          setPositionPx({
            top: rect.top + rect.height,
            left: rect.left + rect.width / 2,
          });
          break;
        }
        case "LEFT": {
          setPositionPx({
            top: rect.top + rect.height / 2,
            left: rect.left,
          });
          break;
        }
        case "RIGHT": {
          setPositionPx({
            top: rect.top + rect.height / 2,
            left: rect.left + rect.width,
          });
          break;
        }
      }
    };

    const handleMouseEnter = () => {
      updatePosition();
      setVisible(true);
    };

    const handleMouseLeave = () => {
      setVisible(false);
    };

    if (trigger) {
      trigger.addEventListener("mouseenter", handleMouseEnter);
      trigger.addEventListener("mouseleave", handleMouseLeave);
    }

    window.addEventListener("scroll", updatePosition, true);
    window.addEventListener("resize", updatePosition, true);

    return () => {
      if (trigger) {
        trigger.removeEventListener("mouseenter", handleMouseEnter);
        trigger.removeEventListener("mouseleave", handleMouseLeave);
      }

      window.removeEventListener("scroll", updatePosition, true);
      window.removeEventListener("resize", updatePosition, true);
    };
  }, [triggerRef, position]);

  return createPortal(
    visible && (
      <div
        id={id}
        className={`fixed z-50 x-border rounded-xl shadow-lg py-2 px-4 bg-t_bg_primary text-sm text-t_text_primary text-opacity-50 max-w-80 ${positionToClass[position]}`}
        style={{
          top: positionPx.top,
          left: positionPx.left,
        }}
      >
        {text}
      </div>
    ),
    xpayShadowRoot!,
    id,
  );
};
