import { describe, expect, it, vi } from 'vitest';
import type { SlashCommandPayload } from '@mosaicstack/types';
import { ChatGateway } from './chat.gateway.js';

const payload: SlashCommandPayload = {
  command: 'gc',
  conversationId: 'conversation-1',
  approvalId: 'approval-1',
};

function buildGateway(commandExecutor: {
  execute: ReturnType<typeof vi.fn>;
  createApproval: ReturnType<typeof vi.fn>;
}): ChatGateway {
  return new ChatGateway(
    {} as never,
    {} as never,
    {} as never,
    {} as never,
    commandExecutor as never,
    {} as never,
  );
}

describe('ChatGateway command approval ingress', () => {
  it('passes the client approval ID through to command execution while deriving the actor server-side', async (): Promise<void> => {
    const commandExecutor = {
      execute: vi.fn().mockResolvedValue({ ...payload, success: true }),
      createApproval: vi.fn(),
    };
    const gateway = buildGateway(commandExecutor);
    const client = { data: { user: { id: 'admin-1' } }, emit: vi.fn() };

    await gateway.handleCommandExecute(client as never, payload);

    expect(commandExecutor.execute).toHaveBeenCalledWith(payload, {
      userId: 'admin-1',
      tenantId: 'admin-1',
    });
    expect(client.emit).toHaveBeenCalledWith(
      'command:result',
      expect.objectContaining({ success: true }),
    );
  });

  it('issues a durable approval only for the authenticated actor', async (): Promise<void> => {
    const commandExecutor = {
      execute: vi.fn(),
      createApproval: vi.fn().mockResolvedValue({
        approvalId: 'approval-1',
        expiresAt: '2026-07-12T00:05:00.000Z',
      }),
    };
    const gateway = buildGateway(commandExecutor);
    const client = { data: { user: { id: 'admin-1' } }, emit: vi.fn() };

    await gateway.handleCommandApproval(client as never, {
      command: 'gc',
      conversationId: 'conversation-1',
    });

    expect(commandExecutor.createApproval).toHaveBeenCalledWith(
      { command: 'gc', conversationId: 'conversation-1' },
      { userId: 'admin-1', tenantId: 'admin-1' },
    );
    expect(client.emit).toHaveBeenCalledWith('command:approval', {
      command: 'gc',
      conversationId: 'conversation-1',
      success: true,
      approvalId: 'approval-1',
      expiresAt: '2026-07-12T00:05:00.000Z',
    });
  });
});
