/**
 * Single source of truth for keyboard shortcuts. Each entry declares both how
 * to MATCH a real keyboard event (lowercase `key` + modifiers) and how to
 * DISPLAY it to the user. The display side branches on platform so macOS sees
 * the ⌘ glyph while everyone else sees `Ctrl`.
 */

import { isMacOS } from "@/lib/platform";

export type ShortcutGroup =
  | "navigation"
  | "actions"
  | "view"
  | "profiles"
  | "groups";

export interface ShortcutDef {
  /** Stable identifier — used by the global listener to dispatch to handlers. */
  id: ShortcutId;
  /** Translation key for the displayed label in the shortcuts page / palette. */
  labelKey: string;
  group: ShortcutGroup;
  /** Lowercased `KeyboardEvent.key`, e.g. "k", ",", "/". */
  key: string;
  /** Require the primary modifier (Cmd on mac, Ctrl elsewhere). */
  mod?: boolean;
  shift?: boolean;
  alt?: boolean;
}

export type ShortcutId =
  | "openPalette"
  | "openShortcuts"
  | "importProfile"
  | "goProfiles"
  | "goProxies"
  | "goExtensions"
  | "goGroups"
  | "goCookieBot"
  | "goIntegrations"
  | "goAccount"
  | "goSettings";

export const SHORTCUTS: ShortcutDef[] = [
  // Actions
  {
    id: "openPalette",
    labelKey: "shortcuts.openPalette",
    group: "actions",
    key: "k",
    mod: true,
  },
  {
    id: "openShortcuts",
    labelKey: "shortcuts.openShortcuts",
    group: "actions",
    key: "/",
    mod: true,
  },
  {
    id: "importProfile",
    labelKey: "shortcuts.importProfile",
    group: "actions",
    key: "o",
    mod: true,
  },
  // Navigation
  {
    id: "goProfiles",
    labelKey: "shortcuts.goProfiles",
    group: "navigation",
    key: "p",
    mod: true,
  },
  {
    id: "goProxies",
    labelKey: "shortcuts.goProxies",
    group: "navigation",
    key: "n",
    mod: true,
  },
  {
    id: "goExtensions",
    labelKey: "shortcuts.goExtensions",
    group: "navigation",
    key: "e",
    mod: true,
  },
  {
    id: "goGroups",
    labelKey: "shortcuts.goGroups",
    group: "navigation",
    key: "g",
    mod: true,
  },
  {
    // Mod+B: "bot". Every other letter in the navigation group was taken.
    id: "goCookieBot",
    labelKey: "shortcuts.goCookieBot",
    group: "navigation",
    key: "b",
    mod: true,
  },
  {
    id: "goIntegrations",
    labelKey: "shortcuts.goIntegrations",
    group: "navigation",
    key: "i",
    mod: true,
  },
  {
    // Mod+Shift+A (not Mod+A): plain Mod+A must stay select-all in any
    // focused text field or table context.
    id: "goAccount",
    labelKey: "shortcuts.goAccount",
    group: "navigation",
    key: "a",
    mod: true,
    shift: true,
  },
  {
    id: "goSettings",
    labelKey: "shortcuts.goSettings",
    group: "navigation",
    key: ",",
    mod: true,
  },
];

/**
 * Match Mod+1..9 to the group at that index (1-based). Returns the digit
 * pressed, or null. Used by the global keydown handler before falling back to
 * the static SHORTCUTS table.
 */
export function matchesGroupDigit(e: KeyboardEvent): number | null {
  if (e.key < "1" || e.key > "9") return null;
  const mod = isMac() ? e.metaKey : e.ctrlKey;
  const oppositeMod = isMac() ? e.ctrlKey : e.metaKey;
  if (!mod || oppositeMod || e.shiftKey || e.altKey) return null;
  return Number(e.key);
}

/**
 * Build display tokens for a Mod+digit group shortcut. Mirrors `formatShortcut`.
 */
export function formatGroupShortcut(digit: number): string[] {
  const mac = isMac();
  return [mac ? "⌘" : "Ctrl", String(digit)];
}

function isMac(): boolean {
  return isMacOS();
}

/**
 * Render a shortcut as the platform-correct token list. The shortcuts page and
 * the command palette both consume this so the glyphs stay in sync.
 *
 * On macOS: ["⌘", "⇧", "⌥", "K"]
 * Elsewhere: ["Ctrl", "Shift", "Alt", "K"]
 */
export function formatShortcut(s: ShortcutDef): string[] {
  const mac = isMac();
  const tokens: string[] = [];
  if (s.mod) tokens.push(mac ? "⌘" : "Ctrl");
  if (s.shift) tokens.push(mac ? "⇧" : "Shift");
  if (s.alt) tokens.push(mac ? "⌥" : "Alt");
  tokens.push(prettyKey(s.key));
  return tokens;
}

function prettyKey(key: string): string {
  if (key.length === 1) return key.toUpperCase();
  // Named keys like "Enter", "Escape", etc. would already be capitalized.
  return key;
}

/**
 * Match a real `KeyboardEvent` against a shortcut definition. Returns true
 * only when modifiers are an exact match (so Ctrl+Shift+K doesn't fire
 * Ctrl+K).
 */
export function matchesShortcut(s: ShortcutDef, e: KeyboardEvent): boolean {
  if (e.key.toLowerCase() !== s.key.toLowerCase()) return false;
  const mod = isMac() ? e.metaKey : e.ctrlKey;
  const oppositeMod = isMac() ? e.ctrlKey : e.metaKey;
  if (Boolean(s.mod) !== mod) return false;
  // Reject the wrong-platform modifier so Ctrl+K on macOS doesn't accidentally
  // trigger something that only expects ⌘+K.
  if (oppositeMod) return false;
  if (Boolean(s.shift) !== e.shiftKey) return false;
  if (Boolean(s.alt) !== e.altKey) return false;
  return true;
}
