import {
  formatDocsShortcutBinding,
  matchesDocsShortcutBinding,
  normalizeDocsShortcutBinding,
} from "@/lib/drive/docs-keyboard-shortcut"
import {
  DOCS_KEYBOARD_SHORTCUT_DEFINITIONS,
  DOCS_KEYBOARD_SHORTCUTS_BY_ID,
  type DocsKeyboardShortcutsUserConfig,
  type DocsShortcutBinding,
  type DocsShortcutDefinition,
  type DocsShortcutId,
} from "@/lib/drive/docs-keyboard-shortcuts-config"

export function getDocsShortcutDefinition(id: DocsShortcutId): DocsShortcutDefinition {
  return DOCS_KEYBOARD_SHORTCUTS_BY_ID[id]
}

export function resolveDocsShortcutBinding(
  id: DocsShortcutId,
  overrides: DocsKeyboardShortcutsUserConfig = {}
): DocsShortcutBinding {
  return overrides[id] ?? DOCS_KEYBOARD_SHORTCUTS_BY_ID[id].defaultBinding
}

export function resolveDocsShortcutBindings(
  id: DocsShortcutId,
  overrides: DocsKeyboardShortcutsUserConfig = {}
): DocsShortcutBinding[] {
  const definition = DOCS_KEYBOARD_SHORTCUTS_BY_ID[id]
  const primary = resolveDocsShortcutBinding(id, overrides)
  const alt = overrides[id] ? [] : (definition.altBindings ?? [])
  return [primary, ...alt]
}

export function formatDocsShortcutId(
  id: DocsShortcutId,
  overrides: DocsKeyboardShortcutsUserConfig = {}
): string {
  return formatDocsShortcutBinding(resolveDocsShortcutBinding(id, overrides))
}

export function matchDocsShortcutEvent(
  event: KeyboardEvent,
  overrides: DocsKeyboardShortcutsUserConfig = {},
  filter?: (definition: DocsShortcutDefinition) => boolean
): DocsShortcutId | null {
  for (const definition of DOCS_KEYBOARD_SHORTCUT_DEFINITIONS) {
    if (filter && !filter(definition)) continue
    const bindings = resolveDocsShortcutBindings(definition.id, overrides)
    if (bindings.some((binding) => matchesDocsShortcutBinding(event, binding))) {
      return definition.id
    }
  }
  return null
}

export function isValidDocsShortcutBinding(value: unknown): value is DocsShortcutBinding {
  if (!value || typeof value !== "object") return false
  const binding = value as DocsShortcutBinding
  if (typeof binding.key !== "string" || binding.key.length === 0) return false
  if (binding.mod != null && typeof binding.mod !== "boolean") return false
  if (binding.shift != null && typeof binding.shift !== "boolean") return false
  if (binding.alt != null && typeof binding.alt !== "boolean") return false
  return true
}

export function sanitizeDocsKeyboardShortcutsUserConfig(
  raw: unknown
): DocsKeyboardShortcutsUserConfig {
  if (!raw || typeof raw !== "object") return {}
  const input = raw as Record<string, unknown>
  const output: DocsKeyboardShortcutsUserConfig = {}

  for (const definition of DOCS_KEYBOARD_SHORTCUT_DEFINITIONS) {
    const candidate = input[definition.id]
    if (isValidDocsShortcutBinding(candidate)) {
      output[definition.id] = normalizeDocsShortcutBinding(candidate)
    }
  }

  return output
}

/** Catalog for a future keyboard-shortcuts settings screen. */
export function listDocsKeyboardShortcutCatalog(
  overrides: DocsKeyboardShortcutsUserConfig = {}
) {
  return DOCS_KEYBOARD_SHORTCUT_DEFINITIONS.map((definition) => ({
    ...definition,
    binding: resolveDocsShortcutBinding(definition.id, overrides),
    display: formatDocsShortcutId(definition.id, overrides),
    isCustomized: Boolean(overrides[definition.id]),
  }))
}
