// ---------------------------------------------------------------------------
// Keyboard shortcuts – OS-aware key resolution
//
// Design:
//   - SHORTCUT_DEFINITIONS: abstract schema using modifier tokens
//   - resolveKeys(): pure function, safe to call anywhere (including tests)
//   - useOs(): client-only React hook that detects Mac vs other after hydration
//
// Modifier tokens:
//   "mod"   → ⌘ (Mac) | Ctrl (other)
//   "shift" → ⇧ (Mac) | Shift (other)
//   "alt"   → ⌥ (Mac) | Alt (other)
//   "enter" → ↵ (Mac) | Enter (other)
//   "esc"   → Esc (both)
//   anything else passes through as-is (plain letter keys like "A")
// ---------------------------------------------------------------------------

export type Os = "mac" | "other" | "unknown";
export type Modifier = string; // "mod" | "shift" | "alt" | "enter" | "esc" | plain key

export interface ShortcutDefinition {
	modifiers: readonly Modifier[];
	label: string;
}

// ─── Abstract shortcut definitions ───────────────────────────────────────────

export const SHORTCUT_DEFINITIONS: ShortcutDefinition[] = [
	{ modifiers: ["mod", "enter"], label: "Generate event" },
	{ modifiers: ["mod", "shift", "A"], label: "Attach image" },
	{ modifiers: ["mod", "V"], label: "Paste image" },
	{ modifiers: ["esc"], label: "Clear prompt" },
];

// ─── Key resolution ───────────────────────────────────────────────────────────

const MAC_MAP: Record<string, string> = {
	mod: "⌘",
	shift: "⇧",
	alt: "⌥",
	enter: "↵",
	esc: "Esc",
};

const OTHER_MAP: Record<string, string> = {
	mod: "Ctrl",
	shift: "Shift",
	alt: "Alt",
	enter: "Enter",
	esc: "Esc",
};

/**
 * Pure function — maps abstract modifier tokens to display glyphs.
 * "unknown" falls back to Mac (most common dev/user base).
 */
export function resolveKeys(modifiers: readonly Modifier[], os: Os): string[] {
	const map = os === "other" ? OTHER_MAP : MAC_MAP;
	return modifiers.map((m) => map[m] ?? m);
}

// ─── OS detection hook (client-only) ─────────────────────────────────────────

/**
 * Detects the user's OS after hydration.
 * Returns "unknown" on the server or before the effect runs.
 *
 * Detection order (most → least reliable):
 *   1. navigator.userAgentData.platform  (modern browsers, Chromium)
 *   2. navigator.platform                (legacy, still widely supported)
 *   3. navigator.userAgent string match  (last resort)
 */
export function detectOs(): Os {
	if (typeof navigator === "undefined") return "unknown";

	// Modern API — Chromium 90+
	const uaData = (
		navigator as Navigator & { userAgentData?: { platform: string } }
	).userAgentData;
	if (uaData?.platform) {
		return uaData.platform.toLowerCase().includes("mac") ? "mac" : "other";
	}

	// Legacy API — still reliable on Safari and Firefox
	if (navigator.platform) {
		return navigator.platform.toLowerCase().startsWith("mac") ? "mac" : "other";
	}

	// Last resort — UA string
	return /mac/i.test(navigator.userAgent) ? "mac" : "other";
}
