import { SpectatorService, createServiceFactory } from '@ngneat/spectator/jest';
import { PrintReceiptsService } from './print-receipts.service';
import { Printer, PrinterType, PrintService } from '@isa/common/print';
import { OMSPrintService } from '@generated/swagger/print-api';
import { of } from 'rxjs';

describe('PrintReceiptsService', () => {
  let spectator: SpectatorService<PrintReceiptsService>;

  const createService = createServiceFactory({
    service: PrintReceiptsService,
    mocks: [OMSPrintService, PrintService],
  });

  let mockPrintService: jest.Mocked<PrintService>;
  let mockOmsPrintService: jest.Mocked<OMSPrintService>;

  beforeEach(() => {
    spectator = createService();
    mockPrintService = spectator.inject(PrintService);
    mockOmsPrintService = spectator.inject(OMSPrintService);
  });

  it('should be created', () => {
    expect(spectator.service).toBeTruthy();
  });

  describe('printReturnReceipts', () => {
    it('should throw an error if no return receipt IDs are provided', async () => {
      await expect(
        spectator.service.printReturnReceipts({ returnReceiptIds: [] }),
      ).rejects.toThrow('No return receipt IDs provided');
    });

    it('should call the print service with the correct parameters', async () => {
      const mockReturnReceiptIds = [1, 2, 3];

      mockPrintService.print.mockImplementation(
        async ({ printerType, printFn }) => {
          expect(printerType).toBe(PrinterType.LABEL);
          const mockPrinter: Printer = {
            key: 'mockPrinterKey',
            value: 'Mock Printer',
            selected: true,
            enabled: true,
            description: 'Mock printer description',
          };
          return printFn(mockPrinter).then(() => ({ printer: mockPrinter }));
        },
      );

      mockOmsPrintService.OMSPrintReturnReceipt.mockReturnValue(
        of({ error: false }),
      );

      await spectator.service.printReturnReceipts({
        returnReceiptIds: mockReturnReceiptIds,
      });

      expect(mockPrintService.print).toHaveBeenCalledWith(
        expect.objectContaining({
          printerType: PrinterType.LABEL,
          printFn: expect.any(Function),
        }),
      );
      expect(mockOmsPrintService.OMSPrintReturnReceipt).toHaveBeenCalledWith({
        printer: expect.any(String),
        data: mockReturnReceiptIds,
      });
    });
  });
});
