"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();
}

function UserAvatar({ user, className }: { user: User; className?: string }) {
  return (
    <span
      className={cn(
        "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-primary text-[0.78rem] font-semibold tracking-wide text-white",
        className,
      )}
      aria-hidden="true"
    >
      {initialsFromName(user.name)}
    </span>
  );
}

export function UserMenu({ compact = false }: { compact?: boolean }) {
  const router = useRouter();
  const { user, 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]);

  if (!user) {
    return null;
  }

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

    setIsLoggingOut(true);
    setOpen(false);

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

  return (
    <div ref={rootRef} className={cn("relative flex items-center", compact && "w-full flex-col")}>
      <div
        className={cn(
          "flex h-11 min-w-0 items-center rounded-pv text-primary",
          compact && "w-full border-[1.5px] border-line",
        )}
      >
        <Link
          href="/dashboard"
          prefetch
          className={cn(
            "flex min-w-0 flex-1 items-center gap-2.5 px-1.5 py-1 text-left focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
            compact && "px-3",
          )}
        >
          <UserAvatar user={user} />
          <span className="min-w-0 flex-1">
            <span className="block truncate text-[0.9rem] font-semibold leading-tight">{user.name}</span>
            <span className="block truncate text-[0.72rem] font-medium capitalize leading-tight text-ink-60">
              {user.account_type}
            </span>
          </span>
        </Link>
        <button
          type="button"
          id={buttonId}
          className="mr-1 inline-flex size-9 shrink-0 items-center justify-center rounded-pv text-ink-40 hover:text-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
          aria-haspopup="menu"
          aria-expanded={open}
          aria-controls={menuId}
          aria-label="Account menu"
          onClick={() => setOpen((value) => !value)}
        >
          <svg
            aria-hidden="true"
            className={cn("size-4 transition-transform", 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>
      </div>
      {open ? (
        <div
          id={menuId}
          role="menu"
          aria-labelledby={buttonId}
          className={cn(
            "z-70 min-w-[13.5rem] overflow-hidden rounded-pv border border-line bg-surface py-1.5 shadow-[0_18px_40px_-28px_rgba(23,37,84,0.55)]",
            compact ? "relative mt-2 w-full" : "absolute right-0 top-[calc(100%+8px)]",
          )}
        >
          <Link
            role="menuitem"
            href="/dashboard"
            prefetch
            className="block px-3.5 py-2.5 text-[0.9rem] font-medium text-primary hover:bg-bg"
            onClick={() => setOpen(false)}
          >
            Dashboard
          </Link>
          <Link
            role="menuitem"
            href="/dashboard/profile"
            className="block px-3.5 py-2.5 text-[0.9rem] 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>
  );
}
