/* eslint-disable react-hooks/exhaustive-deps */
import clsx from "clsx";
import PopupHeader from "./PopupHeader";
import { useEffect, useState } from "react";
import { useRef } from "react";
import usePopupStore from "../store/popupStore";

interface PopupWrapperProps {
  children: React.ReactNode;
  className?: string;
  title?: string;
  leftButton?: React.ReactNode;
  draggable?: boolean;
}

function PopupWrapper({
  children,
  className,
  title,
  leftButton,
  draggable,
}: PopupWrapperProps) {
  const { position, setPosition } = usePopupStore();
  const [mouseDown, setMouseDown] = useState(false);
  const [mouseDownPosition, setMouseDownPosition] = useState(position);

  const wrapperRef = useRef<HTMLDivElement>(null);
  const headerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    addEventListener("mouseup", () => setMouseDown(false));
    addEventListener("touchend", () => setMouseDown(false));
    return () => {
      removeEventListener("mouseup", () => setMouseDown(false));
      removeEventListener("touchend", () => setMouseDown(false));
    };
  }, []);

  function handleMove(e: MouseEvent | TouchEvent) {
    if (draggable && mouseDown && wrapperRef.current) {
      e.preventDefault();
      const x = "clientX" in e ? e.clientX : e.touches[0].clientX;
      const y = "clientY" in e ? e.clientY : e.touches[0].clientY;
      setPosition({
        x: Math.min(
          Math.max(0, position.x + x - mouseDownPosition.x),
          window.innerWidth - wrapperRef.current.clientWidth
        ),
        y: Math.min(
          Math.max(0, position.y + y - mouseDownPosition.y),
          window.innerHeight - wrapperRef.current.clientHeight
        ),
      });
      setMouseDownPosition({ x, y });
    }
  }

  useEffect(() => {
    addEventListener("mousemove", handleMove);
    addEventListener("touchmove", handleMove);
    return () => {
      removeEventListener("mousemove", handleMove);
      removeEventListener("touchmove", handleMove);
    };
  }, [handleMove]);

  useEffect(() => {
    if (headerRef.current) {
      headerRef.current.addEventListener("mousedown", (e) => {
        setMouseDown(true);
        setMouseDownPosition({ x: e.clientX, y: e.clientY });
      });
      headerRef.current.addEventListener("touchstart", (e) => {
        setMouseDown(true);
        setMouseDownPosition({
          x: e.touches[0].clientX,
          y: e.touches[0].clientY,
        });
      });
    }
    return () => {
      if (headerRef.current) {
        headerRef.current.removeEventListener("mousedown", (e) => {
          setMouseDown(true);
          setMouseDownPosition({ x: e.clientX, y: e.clientY });
        });
        headerRef.current.removeEventListener("touchstart", (e) => {
          setMouseDown(true);
          setMouseDownPosition({
            x: e.touches[0].clientX,
            y: e.touches[0].clientY,
          });
        });
      }
    };
  }, []);

  return (
    <div
      ref={wrapperRef}
      className={clsx(
        "2xl:rounded-[2.222vw] rounded-[32px] relative bg-white shadow-[0_4px_40px_0_rgba(15,16,17,0.1)]",
        className
      )}
    >
      <PopupHeader
        headerRef={headerRef}
        title={title}
        leftButton={leftButton}
        draggable={draggable}
      />
      <div className="2xl:p-[1.389vw] p-5">{children}</div>
    </div>
  );
}

export default PopupWrapper;
