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

const { handlers, mockApp, mockCollectAutostartState } = vi.hoisted(() => ({
  handlers: {} as Record<string, (...args: unknown[]) => unknown>,
  mockApp: {
    getLoginItemSettings: vi.fn(),
    setLoginItemSettings: vi.fn(),
    getVersion: vi.fn(() => '0.2.7'),
    getPath: vi.fn(() => '/profile')
  },
  mockCollectAutostartState: vi.fn()
}));

vi.mock('electron', () => ({
  default: {
    ipcMain: {
      handle: (ch: string, fn: (...args: unknown[]) => unknown) => {
        handlers[ch] = fn;
      }
    },
    app: mockApp,
    dialog: {},
    Notification: vi.fn(function (this: unknown) {
      Object.assign(this as object, { show: vi.fn() });
    }),
    shell: { openPath: vi.fn() },
    clipboard: { writeText: vi.fn() }
  }
}));

vi.mock('../../src/main/services/AutostartDiagnostic', () => ({
  collectAutostartState: mockCollectAutostartState
}));

vi.mock('../../src/main/windows/inboxWindow.js', () => ({
  getInboxWindow: vi.fn(() => null)
}));

import { registerSettingsApi } from '../../src/main/ipc/settingsApi';

describe('settingsApi — autostart IPC', () => {
  beforeEach(() => {
    Object.keys(handlers).forEach((k) => delete handlers[k]);
    mockApp.getLoginItemSettings.mockReset();
    mockApp.setLoginItemSettings.mockReset();
    mockCollectAutostartState.mockReset();
  });

  it('settings:autostart-state returns AutostartState wrapped with openAtLogin', async () => {
    mockCollectAutostartState.mockResolvedValue({
      withArgs: { openAtLogin: true, executableWillLaunchAtLogin: true },
      noArgs: { openAtLogin: false, executableWillLaunchAtLogin: true },
      execPath: '/path/to/exe'
    });

    registerSettingsApi();

    const r = await handlers['settings:autostart-state']!() as {
      openAtLogin: boolean;
      diagnostic: { withArgs: { openAtLogin: boolean } };
    };

    expect(r.openAtLogin).toBe(true);
    expect(r.diagnostic.withArgs.openAtLogin).toBe(true);
    expect(r.diagnostic).toHaveProperty('noArgs');
    expect(r.diagnostic).toHaveProperty('execPath');
  });

  it('settings:autostart-set calls setLoginItemSettings + returns diagnostic', async () => {
    mockCollectAutostartState.mockResolvedValue({
      withArgs: { openAtLogin: false, executableWillLaunchAtLogin: false },
      noArgs: { openAtLogin: false, executableWillLaunchAtLogin: false },
      execPath: '/path/to/exe'
    });

    registerSettingsApi();

    const r = await handlers['settings:autostart-set']!({}, false) as {
      openAtLogin: boolean;
      diagnostic: { withArgs: { openAtLogin: boolean } };
    };

    expect(mockApp.setLoginItemSettings).toHaveBeenCalledWith({ openAtLogin: false, args: ['--hidden'] });
    expect(r.openAtLogin).toBe(false);
    expect(r.diagnostic.withArgs.openAtLogin).toBe(false);
  });

  it('Task 22 — old channels removed', async () => {
    mockCollectAutostartState.mockResolvedValue({
      withArgs: { openAtLogin: false, executableWillLaunchAtLogin: false },
      noArgs: { openAtLogin: false, executableWillLaunchAtLogin: false },
      execPath: '/path/to/exe'
    });
    registerSettingsApi();
    expect(handlers['settings:get-autostart']).toBeUndefined();
    expect(handlers['settings:set-autostart']).toBeUndefined();
  });
});
