"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { useEffect, useId, useRef, useState } from "react";
import { useAuth } from "@/components/auth/AuthProvider";
import { cn } from "@/lib/cn";
import type { User } from "@/types/auth";

function initialsFromName(name: string): string {
  const parts = name.trim().split(/\s+/).filter(Boolean);

  if (parts.length === 0) {
    return "P";
  }

  if (parts.length === 1) {
    return parts[0].slice(0, 2).toUpperCase();
  }

  return `${parts[0][0] ?? ""}${parts[1][0] ?? ""}`.toUpperCase();
}

export function DashboardUserMenu({ user }: { user: User }) {
  const router = useRouter();
  const { logout } = useAuth();
  const [open, setOpen] = useState(false);
  const [isLoggingOut, setIsLoggingOut] = useState(false);
  const rootRef = useRef<HTMLDivElement>(null);
  const menuId = useId();
  const buttonId = useId();

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

    function onPointerDown(event: MouseEvent) {
      if (!rootRef.current?.contains(event.target as Node)) {
        setOpen(false);
      }
    }

    function onKeyDown(event: KeyboardEvent) {
      if (event.key === "Escape") {
        setOpen(false);
      }
    }

    document.addEventListener("mousedown", onPointerDown);
    document.addEventListener("keydown", onKeyDown);

    return () => {
      document.removeEventListener("mousedown", onPointerDown);
      document.removeEventListener("keydown", onKeyDown);
    };
  }, [open]);

  async function handleLogout() {
    if (isLoggingOut) {
      return;
    }

    setIsLoggingOut(true);
    setOpen(false);

    try {
      await logout();
    } finally {
      router.replace("/signin");
      setIsLoggingOut(false);
    }
  }

  return (
    <div ref={rootRef} className="relative flex min-w-0 items-center">
      <button
        type="button"
        id={buttonId}
        className="flex min-w-0 max-w-full items-center gap-2 rounded-pv py-1 pl-1 pr-1.5 text-left text-primary hover:bg-surface"
        aria-haspopup="menu"
        aria-expanded={open}
        aria-controls={menuId}
        aria-label="Account menu"
        onClick={() => setOpen((value) => !value)}
      >
        <span
          className="inline-flex size-8 shrink-0 items-center justify-center rounded-full bg-primary text-[0.6875rem] font-semibold tracking-wide text-white"
          aria-hidden="true"
        >
          {initialsFromName(user.name)}
        </span>
        <span className="hidden min-w-0 sm:block">
          <span className="block truncate text-[0.8125rem] font-semibold leading-tight">{user.name}</span>
          <span className="block truncate text-[0.6875rem] font-medium capitalize leading-tight text-ink-60">
            {user.account_type}
          </span>
        </span>
        <svg
          aria-hidden="true"
          className={cn("hidden size-4 shrink-0 text-ink-40 sm:block", open && "rotate-180")}
          xmlns="http://www.w3.org/2000/svg"
          fill="none"
          viewBox="0 0 24 24"
          strokeWidth="1.8"
          stroke="currentColor"
        >
          <path strokeLinecap="round" strokeLinejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
        </svg>
      </button>
      {open ? (
        <div
          id={menuId}
          role="menu"
          aria-labelledby={buttonId}
          className="absolute right-0 top-[calc(100%+6px)] z-70 min-w-[12rem] overflow-hidden rounded-pv border border-line bg-surface py-1 shadow-pv"
        >
          <Link
            role="menuitem"
            href="/dashboard/profile"
            className="block px-3 py-2 text-[0.8125rem] font-medium text-primary hover:bg-bg"
            onClick={() => setOpen(false)}
          >
            Profile
          </Link>
          <button
            type="button"
            role="menuitem"
            className="block w-full px-3.5 py-2.5 text-left text-[0.9rem] font-medium text-primary hover:bg-bg disabled:opacity-70"
            disabled={isLoggingOut}
            onClick={() => {
              void handleLogout();
            }}
          >
            {isLoggingOut ? "Logging out…" : "Log out"}
          </button>
        </div>
      ) : null}
    </div>
  );
}
