import { afterEach, beforeEach, describe, expect, test } from 'vitest';
import { createSnippet } from '@core/snippet';
import { useAppStore } from '../stores/AppStore';
import { useSnippetStore } from '../stores/SnippetStore';
import { startEventRouter, stopEventRouter } from './EventRouter';

const T = new Date('2026-06-01T00:00:00Z');
const active = () => useSnippetStore.getState();

/** Dispatch a global keydown with both modifiers set so it fires on any platform. */
function press(key: string, opts: Partial<KeyboardEventInit> = {}): void {
  window.dispatchEvent(
    new KeyboardEvent('keydown', {
      key,
      bubbles: true,
      cancelable: true,
      ctrlKey: true,
      metaKey: true,
      ...opts,
    }),
  );
}

beforeEach(() => {
  useSnippetStore.getState().reset();
  useAppStore.getState().setActiveModal(null);
  document.body.innerHTML = '';
  window.location.hash = '';
  useSnippetStore.getState().hydrate([createSnippet({ id: 'a', now: T })], 'a');
  startEventRouter();
});

afterEach(() => {
  stopEventRouter();
});

describe('shortcut dispatch (spec §01D)', () => {
  test('Cmd/Ctrl+Shift+N creates and activates a new snippet', () => {
    expect(active().snippets).toHaveLength(1);
    press('n', { shiftKey: true });
    expect(active().snippets).toHaveLength(2);
    expect(active().activeSnippetId).not.toBe('a');
  });

  test('Cmd/Ctrl+K toggles the Datasets manager open then closed', async () => {
    press('k');
    expect(useAppStore.getState().activeModal).toBe('datasets');
    press('k');
    await Promise.resolve(); // closeModal is async (no unsaved changes → no prompt)
    expect(useAppStore.getState().activeModal).toBeNull();
  });

  test('Cmd/Ctrl+S publishes the active draft', () => {
    active().updateDraft('{"published":1}');
    press('s');
    expect(active().snippets.find((s) => s.id === 'a')?.spec).toBe('{"published":1}');
  });

  test('Escape closes the active modal', async () => {
    useAppStore.getState().setActiveModal('datasets');
    press('Escape');
    await Promise.resolve();
    expect(useAppStore.getState().activeModal).toBeNull();
  });

  test('Escape with no modal open does nothing', () => {
    expect(useAppStore.getState().activeModal).toBeNull();
    press('Escape'); // must not throw or change state
    expect(useAppStore.getState().activeModal).toBeNull();
  });
});

describe('interactive-context gating', () => {
  test('N is suppressed while an input is focused', () => {
    const input = document.createElement('input');
    document.body.appendChild(input);
    input.focus();

    press('n', { shiftKey: true });

    expect(active().snippets).toHaveLength(1); // no new snippet
  });

  test('Cmd/Ctrl+S still publishes while the editor/input is focused (deliberate divergence)', () => {
    const input = document.createElement('input');
    document.body.appendChild(input);
    input.focus();
    active().updateDraft('{"saved-while-typing":1}');

    press('s');

    expect(active().snippets.find((s) => s.id === 'a')?.spec).toBe('{"saved-while-typing":1}');
  });
});
