"use client";

import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { MdMoreVert } from "react-icons/md";
import { useRouter } from "next/navigation";
import { AdminUser } from "../../../../../hooks/features/admin/users/useUsersFetch";
import { useModal } from "../../../../../lib/modal-system/ModalContext";

interface UserActionsMenuProps {
  user: AdminUser;
  onViewProfile?: (user: AdminUser) => void;
  onAddCredits?: (user: AdminUser) => void;
  onDeductCredits?: (user: AdminUser) => void;
  onDelete?: (userId: string | number) => void;
  onChangeStatus?: (userId: string | number, status: string) => void;
}

type MenuPosition = {
  top: number;
  left: number;
  origin: "top" | "bottom";
};

const MENU_WIDTH = 160;
const GAP = 8;
const SCREEN_PADDING = 12;
// Only used as a fallback before the menu has ever been measured
const FALLBACK_MENU_HEIGHT = 96;

export function UserActionsMenu({ user }: UserActionsMenuProps) {
  const [open, setOpen] = useState(false);
  const [ready, setReady] = useState(false);
  const [position, setPosition] = useState<MenuPosition>({
    top: 0,
    left: 0,
    origin: "top",
  });
  const router = useRouter();
  const buttonRef = useRef<HTMLButtonElement>(null);
  const menuRef = useRef<HTMLDivElement>(null);
  const { openModal } = useModal();

  const updatePosition = useCallback(() => {
    const button = buttonRef.current;
    if (!button) return;

    const rect = button.getBoundingClientRect();

    // Measure the REAL rendered size instead of assuming a fixed height
    const menuHeight = menuRef.current?.offsetHeight || FALLBACK_MENU_HEIGHT;
    const menuWidth = menuRef.current?.offsetWidth || MENU_WIDTH;

    const spaceBottom = window.innerHeight - rect.bottom;
    const spaceTop = rect.top;

    const openUp = spaceBottom < menuHeight + GAP && spaceTop > spaceBottom;

    const top = openUp
      ? Math.max(SCREEN_PADDING, rect.top - menuHeight - GAP)
      : Math.min(
          rect.bottom + GAP,
          window.innerHeight - menuHeight - SCREEN_PADDING,
        );

    let left = rect.right - menuWidth;
    left = Math.max(SCREEN_PADDING, left);
    left = Math.min(left, window.innerWidth - menuWidth - SCREEN_PADDING);

    setPosition({
      top,
      left,
      origin: openUp ? "bottom" : "top",
    });
  }, []);

  const handleOpen = () => {
    setReady(false);
    setOpen((prev) => !prev);
  };

  // Runs synchronously right after the (invisible) menu mounts, so we can
  // measure its real height/width before the browser paints it.
  useLayoutEffect(() => {
    if (!open) return;
    updatePosition();
    setReady(true);
  }, [open, updatePosition]);

  useEffect(() => {
    if (!open) return;

    const handleOutsideClick = (event: MouseEvent) => {
      const target = event.target as Node;

      if (
        buttonRef.current?.contains(target) ||
        menuRef.current?.contains(target)
      ) {
        return;
      }

      setOpen(false);
    };

    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === "Escape") setOpen(false);
    };

    window.addEventListener("resize", updatePosition);
    window.addEventListener("scroll", updatePosition, true);
    document.addEventListener("mousedown", handleOutsideClick);
    document.addEventListener("keydown", handleKeyDown);

    return () => {
      window.removeEventListener("resize", updatePosition);
      window.removeEventListener("scroll", updatePosition, true);
      document.removeEventListener("mousedown", handleOutsideClick);
      document.removeEventListener("keydown", handleKeyDown);
    };
  }, [open, updatePosition]);

  const closeMenu = () => setOpen(false);

  const isActive = user.isActive;

  const menuItems = [
    {
      label: "View",
      onClick: () => {
        router.push(`/admin/users/${user.uuid}`);
        closeMenu();
      },
      className: "text-link-1",
    },
    {
      label: isActive ? "Deactivate" : "Activate",
      onClick: () => {
        if (isActive) {
          openModal("DEACTIVATE_USER", { userId: user.uuid });
        } else {
          openModal("ACTIVATE_USER", { userId: user.uuid });
        }
        closeMenu();
      },
      className: "text-text",
    },
  ];

  return (
    <>
      <button
        ref={buttonRef}
        type="button"
        onClick={handleOpen}
        aria-label="User actions"
        aria-haspopup="menu"
        aria-expanded={open}
        className="
          inline-flex h-8 w-8 items-center justify-center cursor-pointer
          rounded-full text-link-1 transition
          hover:bg-link-1/10 focus:outline-none
          focus:ring-2 focus:ring-link-1/30
        "
      >
        <MdMoreVert size={22} />
      </button>

      {open &&
        typeof document !== "undefined" &&
        createPortal(
          <div
            ref={menuRef}
            role="menu"
            style={{
              top: position.top,
              left: position.left,
              width: MENU_WIDTH,
              visibility: ready ? "visible" : "hidden",
              transformOrigin:
                position.origin === "top" ? "top right" : "bottom right",
            }}
            className="
              fixed z-9 overflow-hidden rounded-xl
              border border-black/5 bg-white py-1.5
              shadow-[0_12px_40px_rgba(15,23,42,0.18)]
              ring-1 ring-black/5
            "
          >
            {menuItems.map((item) => (
              <button
                key={item.label}
                type="button"
                role="menuitem"
                onClick={item.onClick}
                className={`
                  block w-full px-4 py-2.5 text-left cursor-pointer
                  font-body text-sm font-medium
                  transition-colors hover:bg-link-1/5
                  ${item.className}
                `}
              >
                {item.label}
              </button>
            ))}
          </div>,
          document.body,
        )}
    </>
  );
}