import { type ConfigService } from '@nestjs/config';
import { describe, it, expect, vi } from 'vitest';
import { BankTransferService } from '../services/bank-transfer.service';
import { MomoService } from '../services/momo.service';
import { PaymentGatewayFactory } from '../services/payment-gateway.factory';
import { VnpayService } from '../services/vnpay.service';
import { ZalopayService } from '../services/zalopay.service';

describe('PaymentGatewayFactory', () => {
  const mockConfig = {
    get: vi.fn((key: string, defaultValue?: string) => defaultValue ?? 'test'),
    getOrThrow: vi.fn(() => 'test-value'),
  } as unknown as ConfigService;
  const mockLogger = { log: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn(), verbose: vi.fn() };

  const vnpay = new VnpayService(mockConfig, mockLogger as any);
  const momo = new MomoService(mockConfig, mockLogger as any);
  const zalopay = new ZalopayService(mockConfig, mockLogger as any);
  const bankTransfer = new BankTransferService(mockConfig, mockLogger as any);

  const factory = new PaymentGatewayFactory(vnpay, momo, zalopay, bankTransfer);

  it('should return VNPay gateway', () => {
    const gateway = factory.getGateway('VNPAY');
    expect(gateway).toBe(vnpay);
    expect(gateway.provider).toBe('VNPAY');
  });

  it('should return MoMo gateway', () => {
    const gateway = factory.getGateway('MOMO');
    expect(gateway).toBe(momo);
    expect(gateway.provider).toBe('MOMO');
  });

  it('should return ZaloPay gateway', () => {
    const gateway = factory.getGateway('ZALOPAY');
    expect(gateway).toBe(zalopay);
    expect(gateway.provider).toBe('ZALOPAY');
  });

  it('should return BankTransfer gateway', () => {
    const gateway = factory.getGateway('BANK_TRANSFER');
    expect(gateway).toBe(bankTransfer);
    expect(gateway.provider).toBe('BANK_TRANSFER');
  });

  it('should throw for unsupported provider', () => {
    expect(() => factory.getGateway('UNKNOWN' as any)).toThrow(
      'Nhà cung cấp thanh toán không được hỗ trợ',
    );
  });
});
