import { Test, TestingModule } from '@nestjs/testing';
import { PaymentsWebhookController } from './payments-webhook.controller';
import { OrdersService } from '../commerce/services/orders.service';
import { PrismaService } from '../../prisma/prisma.service';
import { SubscriptionEngineService } from '../subscription/subscription-engine.service';

describe('PaymentsWebhookController', () => {
  let controller: PaymentsWebhookController;
  let ordersService: OrdersService;
  let subscriptionEngine: SubscriptionEngineService;

  const mockOrdersService = {
    confirmPayment: jest.fn().mockResolvedValue({ id: 'ord-1', status: 'PROCESSING' }),
    verifyAndConfirmPayment: jest.fn().mockResolvedValue({ id: 'ord-1', status: 'PROCESSING' }),
  };

  const mockSubscriptionEngine = {
    confirmSubscription: jest.fn().mockResolvedValue({ success: true }),
  };

  const mockPrisma = {};

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [PaymentsWebhookController],
      providers: [
        { provide: OrdersService, useValue: mockOrdersService },
        { provide: PrismaService, useValue: mockPrisma },
        { provide: SubscriptionEngineService, useValue: mockSubscriptionEngine },
      ],
    }).compile();

    controller = module.get<PaymentsWebhookController>(PaymentsWebhookController);
    ordersService = module.get<OrdersService>(OrdersService);
    subscriptionEngine = module.get<SubscriptionEngineService>(SubscriptionEngineService);
    jest.clearAllMocks();
  });

  describe('handleMockWebhook', () => {
    it('should process mock webhook and confirm payment', async () => {
      const res = await controller.handleMockWebhook({
        reference: 'PAY-123456',
        status: 'SUCCESS',
        gatewayReference: 'GW-MOCK-999',
      });

      expect(res.success).toBe(true);
      expect(res.orderId).toBe('ord-1');
      expect(mockOrdersService.confirmPayment).toHaveBeenCalledWith(
        'PAY-123456',
        'SUCCESS',
        'GW-MOCK-999',
      );
    });
  });

  describe('handlePesepayWebhook', () => {
    it('should route subscription payments to subscriptionEngine', async () => {
      const res = await controller.handlePesepayWebhook({
        referenceNumber: 'SUB-987654',
        transactionId: 'TX-PESE-123',
      });

      expect(res).toEqual({ success: true });
      expect(mockSubscriptionEngine.confirmSubscription).toHaveBeenCalledWith(
        'SUB-987654',
        'TX-PESE-123',
      );
      expect(mockOrdersService.verifyAndConfirmPayment).not.toHaveBeenCalled();
    });

    it('should route order payments to ordersService', async () => {
      const res = await controller.handlePesepayWebhook({
        referenceNumber: 'ORD-REF-777',
      });

      expect(res).toEqual({ success: true });
      expect(mockOrdersService.verifyAndConfirmPayment).toHaveBeenCalledWith('ORD-REF-777');
    });
  });
});
