import { AnimatePresence, motion } from "motion/react";
import { usePopupStore } from "../../stores/usePopupStore";
import clsx from "clsx";
import Button from "./Button";
import CloseIcon from "../icons/CloseIcon";
import { useEffect, useRef } from "react";
import { isMobile } from "react-device-detect";

function PopupContainer() {
  const {
    parentBoundingClientRect,
    popup,
    side,
    setPopup,
    setSide,
    align,
    setAlign,
  } = usePopupStore();

  const rootRef = useRef<HTMLDivElement>(null);

  function getPopupPosition() {
    if (parentBoundingClientRect && innerWidth >= 768) {
      const parent = parentBoundingClientRect;

      switch (side) {
        case "right":
          if (align === "start")
            return {
              top: parent.top,
              left: parent.right,
            };
          else if (align === "end")
            return {
              bottom: parent.bottom,
              left: parent.right,
            };
          return {
            top: parent.top + parent.height / 2,
            left: parent.right,
          };
        case "left":
          if (align === "start")
            return {
              top: parent.top,
              left: parent.left,
            };
          else if (align === "end")
            return {
              top: parent.top + parent.height,
              left: parent.left,
            };
          return {
            top: parent.top + parent.height / 2,
            left: parent.left,
          };
        case "top":
          if (align === "start")
            return {
              left: parent.left,
              top: parent.top,
            };
          else if (align === "end")
            return {
              right: parent.right,
              top: parent.top,
            };
          else
            return {
              left: parent.left + parent.width / 2,
              top: parent.top,
            };
        case "bottom":
          if (align === "start")
            return {
              left: parent.left,
              top: parent.top + parent.height,
            };
          else if (align === "end")
            return {
              right: parent.right,
              top: parent.top + parent.height,
            };
          else
            return {
              left: parent.left + parent.width / 2,
              top: parent.top + parent.height,
            };
        default:
          return { bottom: 0, left: 0 };
      }
    }

    return { bottom: 0, left: 0 };
  }

  useEffect(() => {
    if (!rootRef.current || !popup || !parentBoundingClientRect) return;

    const popupRect = rootRef.current.getBoundingClientRect();

    if (popupRect.top + popupRect.height > innerHeight) setSide("top");
    if (popupRect.top < 0) setSide("bottom");
    if (popupRect.left < 0) setSide("right");
    if (popupRect.left + popupRect.width > innerWidth) setSide("left");
  }, [popup, parentBoundingClientRect, setSide, setAlign]);

  const popupPosition = getPopupPosition();

  return (
    <AnimatePresence>
      {popup && (
        <motion.div
          ref={rootRef}
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          style={popupPosition}
          className={clsx(
            "fixed md:absolute z-20",
            side === "left" &&
              "2xl:-translate-x-[calc(100%+0.521vw)] md:max-2xl:-translate-x-[calc(100%+10px)]",
            side === "right" &&
              "2xl:translate-x-[0.521vw] md:max-2xl:translate-x-2.5",
            side === "top" &&
              "2xl:-translate-y-[calc(100%+0.521vw)] md:max-2xl:-translate-y-[calc(100%+10px)]",
            side === "bottom" &&
              "2xl:translate-y-[0.521vw] md:max-2xl:translate-y-2.5",
            align === "center"
              ? side === "left" || side === "right"
                ? "md:-translate-y-1/2"
                : "md:-translate-x-1/2"
              : ""
          )}
        >
          {popup}
          <Button
            variant="secondary"
            className={clsx("absolute top-1 right-1", !isMobile && "md:hidden")}
            onClick={() => setPopup(null)}
          >
            <span className="size-4">
              <CloseIcon />
            </span>
          </Button>
        </motion.div>
      )}
    </AnimatePresence>
  );
}

export default PopupContainer;
