/**
 * Full-screen navigation sheet for the web client (ticket #90): a mobile-first
 * menu — never a desktop dropdown — reused by both the "Panneaux" menu
 * ({@link WebWorkspace}) and the "Paramètres" menu ({@link WebApp}). Same shell
 * as {@link WebTicketPickerSheet}: fixed header with a close action, an optional
 * shared note, and a scrollable list of entries. The active entry is marked with
 * "●"; a disabled entry stays visible (never removed) so its reason is
 * discoverable, via `hint` (title tooltip) and/or `secondaryLabel` (always-visible
 * text — the only way to communicate "why" on a touch device with no hover).
 */

import { useEffect, useRef } from "react";

import { Button, cn, zIndex } from "@/shared";

export interface WebMenuEntry {
  id: string;
  label: string;
  active: boolean;
  disabled?: boolean;
  /** Tooltip shown on hover/focus (desktop browsers); not relied on for touch. */
  hint?: string;
  /** Always-visible secondary text, e.g. "Desktop uniquement". */
  secondaryLabel?: string;
  onSelect: () => void;
}

export interface WebMenuSheetProps {
  title: string;
  entries: WebMenuEntry[];
  /** Shared note shown once above the list (e.g. why some entries are disabled). */
  note?: string;
  onClose: () => void;
}

export function WebMenuSheet({ title, entries, note, onClose }: WebMenuSheetProps) {
  const closeRef = useRef<HTMLButtonElement>(null);

  useEffect(() => {
    closeRef.current?.focus();
  }, []);

  useEffect(() => {
    function onKeyDown(e: KeyboardEvent) {
      if (e.key === "Escape") onClose();
    }
    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  }, [onClose]);

  return (
    <div
      className="fixed inset-0 flex flex-col bg-canvas"
      role="dialog"
      aria-modal="true"
      aria-label={title}
      style={{ zIndex: zIndex.floatingWindowNested }}
    >
      <header className="flex shrink-0 items-center justify-between gap-3 border-b border-border px-4 py-3 pt-[max(0.75rem,env(safe-area-inset-top))]">
        <span className="min-w-0 truncate text-sm font-medium text-content">{title}</span>
        <Button ref={closeRef} size="sm" variant="ghost" onClick={onClose}>
          Fermer
        </Button>
      </header>

      {note && (
        <p className="shrink-0 border-b border-border px-4 py-2 text-xs text-muted">{note}</p>
      )}

      <ul className="min-h-0 flex-1 overflow-auto px-2 py-2 pb-[max(0.5rem,env(safe-area-inset-bottom))]">
        {entries.map((entry) => (
          <li key={entry.id}>
            <button
              type="button"
              disabled={entry.disabled}
              title={entry.hint}
              aria-current={entry.active ? "true" : undefined}
              onClick={() => {
                if (entry.disabled) return;
                entry.onSelect();
              }}
              className={cn(
                "flex min-h-[44px] w-full items-center gap-2 rounded-md px-3 py-2 text-left text-sm transition-colors",
                "hover:bg-raised focus:bg-raised focus:outline-none disabled:opacity-50 disabled:hover:bg-transparent",
                entry.active && "bg-raised font-medium text-content",
              )}
            >
              <span aria-hidden="true" className="w-3 shrink-0 text-primary">
                {entry.active ? "●" : ""}
              </span>
              <span className="min-w-0 flex-1 truncate">{entry.label}</span>
              {entry.secondaryLabel && (
                <span className="shrink-0 text-xs text-muted">{entry.secondaryLabel}</span>
              )}
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}
