import { describe, expect, it } from 'vitest';
import { getUndoRedoShortcut, isEditableShortcutTarget } from './keyboardShortcuts';

function keyboardEvent(init: KeyboardEventInit) {
  return new KeyboardEvent('keydown', init);
}

describe('keyboardShortcuts', () => {
  it('maps common undo and redo shortcuts', () => {
    expect(getUndoRedoShortcut(keyboardEvent({ key: 'z', ctrlKey: true }))).toBe('undo');
    expect(getUndoRedoShortcut(keyboardEvent({ key: 'Z', metaKey: true }))).toBe('undo');
    expect(getUndoRedoShortcut(keyboardEvent({ key: 'z', ctrlKey: true, shiftKey: true }))).toBe('redo');
    expect(getUndoRedoShortcut(keyboardEvent({ key: 'y', ctrlKey: true }))).toBe('redo');
    expect(getUndoRedoShortcut(keyboardEvent({ key: 'Y', metaKey: true }))).toBe('redo');
  });

  it('falls back to physical key codes when key labels are unavailable', () => {
    expect(getUndoRedoShortcut(keyboardEvent({ key: 'Process', code: 'KeyZ', ctrlKey: true }))).toBe('undo');
    expect(getUndoRedoShortcut(keyboardEvent({ key: 'Process', code: 'KeyZ', ctrlKey: true, shiftKey: true }))).toBe('redo');
    expect(getUndoRedoShortcut(keyboardEvent({ key: 'Process', code: 'KeyY', ctrlKey: true }))).toBe('redo');
  });

  it('ignores editable targets and alt-modified shortcuts', () => {
    const input = document.createElement('input');
    input.dispatchEvent(new Event('focus'));
    expect(isEditableShortcutTarget(input)).toBe(true);
    const event = keyboardEvent({ key: 'z', ctrlKey: true });
    Object.defineProperty(event, 'target', { value: input });
    expect(getUndoRedoShortcut(event)).toBeNull();
    expect(getUndoRedoShortcut(keyboardEvent({ key: 'z', ctrlKey: true, altKey: true }))).toBeNull();
  });
});
