import { describe, it, expect, vi, beforeEach } from 'vitest';

// Track ipcMain.handle and ipcMain.on calls
const { handleCalls, onCalls } = vi.hoisted(() => ({
  handleCalls: [] as string[],
  onCalls: [] as string[]
}));

vi.mock('electron', () => ({
  default: {
    ipcMain: {
      handle: (ch: string, _fn: unknown) => { handleCalls.push(ch); },
      on: (ch: string, _fn: unknown) => { onCalls.push(ch); }
    },
    dialog: {},
    shell: {}
  }
}));

import { registerInboxApi } from '../../src/main/ipc/inboxApi.js';
import type { InboxIpcDeps } from '../../src/main/ipc/inboxApi.js';

function makeDeps(): InboxIpcDeps {
  return {
    repo: {} as never,
    continuity: {} as never,
    capture: {
      emitRecallShown: vi.fn(async () => {}),
      emitRecallSnoozed: vi.fn(async () => {})
    } as never,
    health: {} as never,
    intent: {} as never,
    getInboxWindow: () => null,
    settings: {} as never,
    providerHolder: {} as never,
    paths: { profileDir: '/profile' }
  };
}

describe('recall IPC channels (fire-and-forget)', () => {
  beforeEach(() => {
    handleCalls.length = 0;
    onCalls.length = 0;
  });

  it('inbox:emitRecallShown is registered with ipcMain.on (not handle)', () => {
    registerInboxApi(makeDeps());
    expect(onCalls).toContain('inbox:emitRecallShown');
    expect(handleCalls).not.toContain('inbox:emitRecallShown');
  });

  it('inbox:emitRecallSnoozed is registered with ipcMain.on (not handle)', () => {
    registerInboxApi(makeDeps());
    expect(onCalls).toContain('inbox:emitRecallSnoozed');
    expect(handleCalls).not.toContain('inbox:emitRecallSnoozed');
  });

  it('each recall channel is registered exactly once with ipcMain.on', () => {
    registerInboxApi(makeDeps());
    const shownCount = onCalls.filter((ch) => ch === 'inbox:emitRecallShown').length;
    const snoozedCount = onCalls.filter((ch) => ch === 'inbox:emitRecallSnoozed').length;
    expect(shownCount).toBe(1);
    expect(snoozedCount).toBe(1);
  });
});
