import { useEffect, useState } from "react";
import { AnimatePresence, motion } from "motion/react";
import clsx from "clsx";

interface PopoverProps {
  isOpened: boolean;
  parentElRef: React.RefObject<HTMLButtonElement | HTMLDivElement | null>;
  children: React.ReactNode;
  className?: string;
  position?: "side" | "center" | "vertical"; // side - сбоку от элемента, center - по центру экрана, vertical - сверху/снизу
}

function PopoverWrapper({
  isOpened,
  parentElRef,
  children,
  className,
  position = "side",
}: PopoverProps) {
  const [openUpwards, setOpenUpwards] = useState(false);
  const [menuHeight, setMenuHeight] = useState(0);
  const [, forceUpdate] = useState(0);

  useEffect(() => {
    if (
      isOpened &&
      parentElRef.current &&
      (position === "side" || position === "vertical")
    ) {
      const buttonRect = parentElRef.current.getBoundingClientRect();
      const spaceBelow = window.innerHeight - buttonRect.bottom;
      const spaceAbove = buttonRect.top;
      setOpenUpwards(spaceBelow < menuHeight && spaceAbove > menuHeight);
    }
  }, [parentElRef, isOpened, menuHeight, position]);

  // Обновляем позицию при изменении положения родительского элемента
  useEffect(() => {
    if (!isOpened) return;

    let animationFrameId: number;

    const updatePosition = () => {
      forceUpdate((prev) => prev + 1);
      animationFrameId = requestAnimationFrame(updatePosition);
    };

    animationFrameId = requestAnimationFrame(updatePosition);

    return () => {
      if (animationFrameId) {
        cancelAnimationFrame(animationFrameId);
      }
    };
  }, [isOpened]);

  const getPositionStyles = () => {
    if (!parentElRef.current) return {};

    const buttonRect = parentElRef.current.getBoundingClientRect();

    if (position === "center") {
      // Позиционирование по центру экрана
      return {
        left: "50%",
        bottom: buttonRect.height + 16, // 16px отступ от кнопки
        transform: "translateX(-50%)",
      };
    }

    if (position === "vertical") {
      // Позиционирование сверху или снизу от элемента, выравнивание по правому краю
      return {
        left: buttonRect.right,
        top: openUpwards
          ? buttonRect.top - menuHeight - 4
          : buttonRect.bottom + 4,
      };
    }

    // Позиционирование сбоку (существующая логика)
    return {
      left: buttonRect.left + buttonRect.width,
      top: openUpwards
        ? buttonRect.top - menuHeight - 4
        : buttonRect.bottom + 4,
    };
  };

  return (
    <AnimatePresence>
      {isOpened && (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          ref={(el) => {
            if (el) setMenuHeight(el.offsetHeight);
          }}
          style={getPositionStyles()}
          className={clsx(
            "fixed z-[99999] shadow-[0_4px_40px_0_rgba(15,16,17,0.1)] overflow-hidden bg-white 2xl:rounded-[1.111vw] rounded-2xl",
            position === "side" && "-translate-x-full",
            position === "vertical" && "-translate-x-full",
            className
          )}
        >
          <div className="2xl:p-[0.278vw] p-1">{children}</div>
        </motion.div>
      )}
    </AnimatePresence>
  );
}

export default PopoverWrapper;
