import { useEffect } from "react";
import { Keyboard, X } from "lucide-react";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { cn } from "@/lib/utils";

type KeyboardCheatsheetProps = {
  open: boolean;
  onClose: () => void;
};

/**
 * Shortcut rows. Each row may have multiple key chips (e.g. "j" and
 * "↓" both navigate to the next claim) so the `keys` array renders one
 * `<kbd>` per entry. The order here is the order rendered top→bottom
 * and is the project's canonical "drawer shortcuts" reference.
 */
const SHORTCUTS = [
  { keys: ["j", "↓"], description: "Next claim" },
  { keys: ["k", "↑"], description: "Previous claim" },
  { keys: ["Esc"], description: "Close drawer" },
  { keys: ["?"], description: "Toggle this help" },
] as const;

/**
 * Stable id used to wire the dialog's `aria-labelledby` and the close
 * button's `aria-describedby` to the visible `<h2>` heading. Exposed
 * as a constant so tests can assert against the same string the
 * component renders.
 */
const CHEATSHEET_TITLE_ID = "keyboard-cheatsheet-title";

/**
 * Keyboard help overlay (SP4).
 *
 * Centered modal-style overlay (per spec: "centered modal-style
 * overlay") built on the project's `Dialog` primitive — the only
 * modal primitive in the codebase. It reuses Radix's focus
 * management, ESC-to-close, and overlay-click-to-dismiss for free;
 * the dialog's `onOpenChange(false)` is wired straight to the
 * consumer's `onClose`.
 *
 * Dismissal rules (per spec §3.7):
 *
 *  1. Overlay click       → Radix fires `onOpenChange(false)`.
 *  2. Escape key          → Radix fires `onOpenChange(false)`.
 *  3. Any other key       → The window-level `keydown` listener below
 *                           fires `onClose` directly.
 *
 * The `?` key is intentionally NOT a dismiss trigger: it's the
 * toggle key the *parent* owns. The parent flips `open` to false
 * (and back to true, if it's a toggle) without the cheatsheet
 * pre-empting it — otherwise the "press ? to toggle" gesture would
 * silently no-op on the close half of the cycle.
 *
 * `aria-describedby={undefined}` suppresses the Radix warning about
 * a missing description; the cheatsheet's content (key list + helper
 * text) is its own description and there's no separate description
 * element worth pointing at.
 */
export function KeyboardCheatsheet({ open, onClose }: KeyboardCheatsheetProps) {
  // Dismiss on any key while open (except `?`, which the parent owns).
  // The listener is only attached when `open` is true — a closed
  // cheatsheet shouldn't be intercepting keystrokes for the rest of
  // the app.
  useEffect(() => {
    if (!open) return;
    const handler = (e: KeyboardEvent) => {
      if (e.key === "?") return;
      onClose();
    };
    window.addEventListener("keydown", handler);
    return () => window.removeEventListener("keydown", handler);
  }, [open, onClose]);

  return (
    <Dialog
      open={open}
      onOpenChange={(o) => {
        // Radix fires `false` on overlay click, Escape, and the
        // dialog's own close button. Forward all three as a single
        // `onClose` to the parent.
        if (!o) onClose();
      }}
    >
      <DialogContent
        // Centered modal (DialogContent's default positioning is
        // `left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2`).
        // We narrow it to max-w-md and apply the warm-paper palette so
        // it sits on the same surface as the rest of the detail surfaces.
        //
        // a11y wiring:
        //  - `aria-labelledby` points at the visible <h2> below so
        //    screen readers announce "Keyboard, dialog" instead of an
        //    unlabeled region (Radix logs a warning otherwise).
        //  - `aria-describedby={undefined}` suppresses Radix's
        //    missing-description warning; the cheatsheet's content
        //    (key list + helper text) is its own description.
        className={cn(
          "max-w-md p-5",
          "bg-[color:var(--m-surface)] text-[color:var(--m-ink-primary)]",
          "border border-[color:var(--m-border-heavy)]/20",
          "shadow-[0_24px_64px_-12px_rgb(0_0_0_/_0.5),inset_0_1px_0_0_rgb(255_255_255_/_0.6)]"
        )}
        aria-labelledby={CHEATSHEET_TITLE_ID}
        aria-describedby={undefined}
        data-testid="keyboard-cheatsheet"
      >
        <header className="flex items-center justify-between gap-2 mb-4 pr-10 pb-3 border-b border-[color:var(--m-border-heavy)]/15">
          <div className="flex items-center gap-2">
            <span
              aria-hidden
              className="inline-flex h-5 w-5 items-center justify-center rounded-[5px] bg-[color:var(--m-ink-primary)]/8 text-[color:var(--m-ink-secondary)]"
            >
              <Keyboard className="h-3 w-3" strokeWidth={2} />
            </span>
            <h2
              id={CHEATSHEET_TITLE_ID}
              className="eyebrow text-[color:var(--m-ink-secondary)]"
            >
              Keyboard
            </h2>
          </div>
          {/*
            Explicit close button with a cheatsheet-specific label.
            The shared DialogContent primitive renders its own X in
            the top-right corner with a generic "Close dialog" label
            (out of scope here), so this one carries the specific
            aria-label and an aria-describedby pointer back to the
            heading for screen-reader context. `pr-10` on the header
            keeps the visible title text clear of the primitive's
            absolute-positioned X in the corner.
          */}
          <button
            type="button"
            aria-label="Close keyboard cheatsheet"
            aria-describedby={CHEATSHEET_TITLE_ID}
            onClick={onClose}
            className="rounded-md p-1 text-[color:var(--m-ink-secondary)] opacity-70 transition-opacity hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
          >
            <X className="h-4 w-4" aria-hidden />
          </button>
        </header>

        <ul className="flex flex-col gap-1">
          {SHORTCUTS.map((s) => (
            <li
              key={s.description}
              className="flex items-center justify-between gap-3 rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-[color:var(--m-ink-primary)]/[0.04]"
            >
              <div className="flex items-center gap-1.5">
                {s.keys.map((k) => (
                  <kbd key={k} className="kbd">
                    {k}
                  </kbd>
                ))}
              </div>
              <span className="text-[13px] text-[color:var(--m-ink-primary)]">
                {s.description}
              </span>
            </li>
          ))}
        </ul>

        <p className="mt-4 pt-3 border-t border-[color:var(--m-border-heavy)]/15 eyebrow text-[color:var(--m-ink-tertiary)]">
          Press any other key to dismiss
        </p>
      </DialogContent>
    </Dialog>
  );
}
