import hotkeys from 'hotkeys-js';

export interface KeybindsOptions {
  themeOptions: Array<{ value: string }>;
  setColorTheme: (t: any) => void;
  toggleMode: () => void;
  navigation: Array<{ path: string; external?: boolean }>;
  goto?: (path: string) => void;
  browser: boolean;
}

let lastToggleAt = 0;
let tHeld = false;
let tDigitUsed = false;

export function registerKeybinds(opts: KeybindsOptions) {
  const { themeOptions, setColorTheme, toggleMode, navigation, goto, browser } = opts;

  // alt/option + t: toggle mode (hold+digit to pick theme)
  // keydown: start hold
  hotkeys('alt+b', (e) => {
    if (e.repeat) return;
    tHeld = true;
    tDigitUsed = false;
    e.preventDefault();
  });

  // macOS alias: option
  hotkeys('option+b', (e) => {
    if (e.repeat) return;
    tHeld = true;
    tDigitUsed = false;
    e.preventDefault();
  });

  // keyup: toggle if no digit used
  hotkeys('alt+b', { keyup: true }, (e) => {
    if (!tDigitUsed && tHeld) {
      const now = Date.now();
      if (now - lastToggleAt > 400) {
        toggleMode();
        lastToggleAt = now;
      }
    }
    tHeld = false;
    tDigitUsed = false;
    e.preventDefault();
  });

  hotkeys('option+b', { keyup: true }, (e) => {
    if (!tDigitUsed && tHeld) {
      const now = Date.now();
      if (now - lastToggleAt > 400) {
        toggleMode();
        lastToggleAt = now;
      }
    }
    tHeld = false;
    tDigitUsed = false;
    e.preventDefault();
  });

  // alt/option + t + N => set theme
  const tThemeKeysAlt = Array.from({ length: 9 }, (_, i) => `alt+t+${i + 1}`).join(',');
  const tThemeKeysOption = Array.from({ length: 9 }, (_, i) => `option+t+${i + 1}`).join(',');
  hotkeys(`${tThemeKeysAlt},${tThemeKeysOption}`, (e, handler) => {
    const m = handler.key.match(/(?:alt|option)\+t\+(\d)/);
    if (!m) return;
    const idx = parseInt(m[1], 10) - 1;
    if (themeOptions[idx]) {
      setColorTheme(themeOptions[idx].value);
      tDigitUsed = true;
      e.preventDefault();
    }
  });

  // ctrl/cmd + N => navigate. Include numpad variants. Command (cmd) aliases on mac
  const ctrlKeys = Array.from({ length: 9 }, (_, i) => `ctrl+${i + 1}`).join(',');
  const ctrlNumKeys = Array.from({ length: 9 }, (_, i) => `ctrl+num_${i + 1}`).join(',');
  const cmdKeys = Array.from({ length: 9 }, (_, i) => `cmd+${i + 1}`).join(',');
  const cmdNumKeys = Array.from({ length: 9 }, (_, i) => `cmd+num_${i + 1}`).join(',');

  hotkeys(`${ctrlKeys},${ctrlNumKeys},${cmdKeys},${cmdNumKeys}`, (e, handler) => {
    const digitMatch = handler.key.match(/(\d)/);
    if (!digitMatch) return;
    const digit = parseInt(digitMatch[1], 10);
    if (isNaN(digit)) return;
    const idx = digit - 1;
    if (navigation && navigation[idx]) {
      const { path, external } = navigation[idx] as any;
      if (browser) {
        if (external) window.location.href = path;
        else if (typeof goto === 'function') goto?.(path);
      }
      e.preventDefault();
    }
  });
}

export function unregisterKeybinds() {
  // Unbind all key patterns we registered
  hotkeys.unbind('alt+b');
  hotkeys.unbind('option+b');
  const tThemeKeys = Array.from({ length: 9 }, (_, i) => `alt+t+${i + 1}`).join(',');
  const tThemeKeysOption = Array.from({ length: 9 }, (_, i) => `option+t+${i + 1}`).join(',');
  hotkeys.unbind(`${tThemeKeys},${tThemeKeysOption}`);

  const ctrlKeys = Array.from({ length: 9 }, (_, i) => `ctrl+${i + 1}`).join(',');
  const ctrlNumKeys = Array.from({ length: 9 }, (_, i) => `ctrl+num_${i + 1}`).join(',');
  const cmdKeys = Array.from({ length: 9 }, (_, i) => `cmd+${i + 1}`).join(',');
  const cmdNumKeys = Array.from({ length: 9 }, (_, i) => `cmd+num_${i + 1}`).join(',');
  hotkeys.unbind(`${ctrlKeys},${ctrlNumKeys},${cmdKeys},${cmdNumKeys}`);
}
