"use client";

import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { clsx } from "clsx";
import { Button } from "@/components/ui";

/*
 * Every action this page can take, behind one control.
 *
 * The header used to carry up to six buttons — a Connect per console protocol,
 * OS updates, Generate key, Remove — and which of them appeared depended on the
 * server, so the row an operator reached for moved between machines. One button
 * in one place is worth more than a shortcut that is sometimes there.
 *
 * An action the licence or the host does not allow is rendered disabled with a
 * reason rather than hidden: a customer cannot buy what they cannot see, and a
 * control that vanishes reads as a bug.
 */

export interface ServerAction {
    /** Grouping heading. Items sharing one carry it once, on the first. */
    group?: string;
    label: string;
    icon: React.ReactNode;
    onSelect?: () => void;
    href?: string;
    disabled?: boolean;
    /** Why it is disabled, or what it will do. Shown as the native tooltip. */
    title?: string;
    danger?: boolean;
    /** Draws a rule above this item. */
    separated?: boolean;
}

export function ServerActionsMenu({ actions }: { actions: ServerAction[] }) {
    const [open, setOpen] = useState(false);
    const wrapRef = useRef<HTMLDivElement>(null);
    const buttonRef = useRef<HTMLButtonElement>(null);
    const menuRef = useRef<HTMLDivElement>(null);
    const router = useRouter();

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

        function onPointerDown(e: MouseEvent) {
            if (!wrapRef.current?.contains(e.target as Node)) setOpen(false);
        }
        function onKey(e: KeyboardEvent) {
            if (e.key === "Escape") {
                setOpen(false);
                buttonRef.current?.focus();
            }
        }
        document.addEventListener("mousedown", onPointerDown);
        document.addEventListener("keydown", onKey);

        menuRef.current?.querySelector<HTMLElement>("[role=menuitem]:not([aria-disabled=true])")?.focus();

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

    function onMenuKeyDown(e: React.KeyboardEvent) {
        if (e.key !== "ArrowDown" && e.key !== "ArrowUp") return;
        e.preventDefault();
        const items = [...(menuRef.current?.querySelectorAll<HTMLElement>("[role=menuitem]:not([aria-disabled=true])") ?? [])];
        const i = items.indexOf(document.activeElement as HTMLElement);
        items[(i + (e.key === "ArrowDown" ? 1 : -1) + items.length) % items.length]?.focus();
    }

    function run(action: ServerAction) {
        if (action.disabled) return;
        setOpen(false);
        buttonRef.current?.focus();
        if (action.href) router.push(action.href);
        action.onSelect?.();
    }

    return (
        <div ref={wrapRef} className="relative">
            <Button ref={buttonRef} variant="primary" aria-haspopup="menu" aria-expanded={open} onClick={() => setOpen((v) => !v)}>
                Actions
                <svg className={clsx("h-4 w-4 transition-transform", open && "rotate-180")} fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                    <path strokeLinecap="round" strokeLinejoin="round" d="M6 9l6 6 6-6" />
                </svg>
            </Button>

            {open && (
                <div
                    ref={menuRef}
                    role="menu"
                    aria-label="Server actions"
                    onKeyDown={onMenuKeyDown}
                    className="absolute right-0 z-50 mt-1.5 w-60 rounded border border-border bg-surface p-1 shadow-panel"
                >
                    {actions.map((action, i) => (
                        <div key={action.label}>
                            {action.separated && i > 0 && <div className="my-1 h-px bg-border-soft" />}
                            {action.group && <p className="px-2 pb-1 pt-1.5 font-mono text-[0.62rem] uppercase tracking-[0.16em] text-text-tertiary">{action.group}</p>}
                            <button
                                type="button"
                                role="menuitem"
                                aria-disabled={action.disabled}
                                disabled={action.disabled}
                                title={action.title}
                                onClick={() => run(action)}
                                className={clsx(
                                    "flex w-full items-center gap-2.5 rounded px-2 py-2 text-left text-sm font-medium transition-colors",
                                    action.disabled
                                        ? "cursor-not-allowed text-text-tertiary"
                                        : action.danger
                                          ? "text-danger hover:bg-danger/10"
                                          : "text-text-primary hover:bg-surface-2 [&>svg]:hover:text-accent",
                                    !action.disabled && !action.danger && "[&>svg]:text-text-tertiary",
                                    action.danger && "[&>svg]:text-danger",
                                    action.disabled && "[&>svg]:text-text-tertiary",
                                )}
                            >
                                {action.icon}
                                {action.label}
                            </button>
                        </div>
                    ))}
                </div>
            )}
        </div>
    );
}
