"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { Ellipsis, LogOut, Settings } from "lucide-react";
import { useEffect, useRef, useState } from "react";

import { Button } from "@/components/ui/button";
import type { Permission, PublicAccount } from "@/modules/core/types";
import { UserAvatar } from "@/modules/shared/components/UserAvatar";

type AccountMenuProps = {
  account: PublicAccount;
  permissions: Permission[];
};

export function AccountMenu({ account, permissions }: AccountMenuProps): React.ReactElement {
  const router = useRouter();
  const menuRef = useRef<HTMLDivElement>(null);
  const [isOpen, setIsOpen] = useState(false);
  const [isPending, setIsPending] = useState(false);
  const canReadAccounts = permissions.includes("account:read");
  const settingsHref = canReadAccounts ? `/app/settings/users?q=${encodeURIComponent(account.email)}` : "/app/settings/global";

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

    function handlePointerDown(event: PointerEvent): void {
      const target = event.target;
      if (target instanceof Node && !menuRef.current?.contains(target)) {
        setIsOpen(false);
      }
    }

    function handleKeyDown(event: KeyboardEvent): void {
      if (event.key === "Escape") {
        setIsOpen(false);
      }
    }

    document.addEventListener("pointerdown", handlePointerDown);
    document.addEventListener("keydown", handleKeyDown);

    return () => {
      document.removeEventListener("pointerdown", handlePointerDown);
      document.removeEventListener("keydown", handleKeyDown);
    };
  }, [isOpen]);

  async function handleSignOut(): Promise<void> {
    setIsPending(true);
    await fetch("/api/auth/logout", { method: "POST" });
    router.refresh();
    router.replace("/login");
  }

  return (
    <div className="relative" ref={menuRef}>
      <div className="flex min-w-0 items-center gap-3 rounded-md bg-secondary/55 p-2">
        <UserAvatar avatarUrl={account.avatarUrl} name={account.name} size="sm" />
        <div className="min-w-0 flex-1">
          <p className="truncate text-sm font-medium leading-tight">{account.name}</p>
          <p className="truncate text-xs leading-tight text-muted-foreground">{account.email}</p>
        </div>
        <Button
          aria-expanded={isOpen}
          aria-haspopup="menu"
          aria-label="打开账号菜单"
          onClick={() => setIsOpen((current) => !current)}
          size="icon"
          type="button"
          variant="ghost"
          className="size-9 shrink-0"
        >
          <Ellipsis className="size-4" aria-hidden="true" />
        </Button>
      </div>

      {isOpen ? (
        <div
          className="absolute bottom-full right-0 z-30 mb-2 w-52 rounded-md border bg-popover p-1 text-popover-foreground shadow-lg"
          role="menu"
        >
          <Link
            className="flex min-h-10 items-center gap-2 rounded-sm px-3 text-sm font-medium hover:bg-secondary"
            href={settingsHref}
            onClick={() => setIsOpen(false)}
            role="menuitem"
          >
            <Settings className="size-4 text-muted-foreground" aria-hidden="true" />
            用户设置
          </Link>
          <button
            className="flex min-h-10 w-full items-center gap-2 rounded-sm px-3 text-left text-sm font-medium hover:bg-secondary disabled:opacity-55"
            disabled={isPending}
            onClick={handleSignOut}
            role="menuitem"
            type="button"
          >
            <LogOut className="size-4 text-muted-foreground" aria-hidden="true" />
            退出登录
          </button>
        </div>
      ) : null}
    </div>
  );
}
