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

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

  const createService = createServiceFactory({
    service: PrintTolinoReturnReceiptService,
    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('printTolinoReturnReceipt', () => {
    it('should throw an error if no return receipt ID is provided', async () => {
      await expect(
        spectator.service.printTolinoReturnReceipt({
          returnReceiptId: undefined as unknown as number,
        }),
      ).rejects.toThrow('No return receipt ID provided');
    });

    it('should call the print service with the correct parameters', async () => {
      const mockReturnReceiptId = 42;

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

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

      await spectator.service.printTolinoReturnReceipt({
        returnReceiptId: mockReturnReceiptId,
      });

      expect(mockPrintService.print).toHaveBeenCalledWith(
        expect.objectContaining({
          printerType: PrinterType.OFFICE,
          printFn: expect.any(Function),
        }),
      );
      expect(
        mockOmsPrintService.OMSPrintTolinoRetourenschein,
      ).toHaveBeenCalledWith({
        printer: expect.any(String),
        data: mockReturnReceiptId,
      });
    });
  });
});
