import { Test, TestingModule } from '@nestjs/testing';
import { WhatsAppService } from './whatsapp.service';
import { PrismaService } from '../../../prisma/prisma.service';
import { EncryptionService } from '../../../common/services/encryption.service';

describe('WhatsAppService', () => {
  let service: WhatsAppService;
  let prisma: PrismaService;

  const mockPrisma = {
    messageLog: {
      create: jest.fn().mockResolvedValue({ id: 'log-1' }),
      update: jest.fn().mockResolvedValue({ id: 'log-1' }),
      findFirst: jest.fn().mockResolvedValue(null),
      findMany: jest.fn().mockResolvedValue([]),
    },
    businessIntegration: {
      findFirst: jest.fn().mockResolvedValue(null),
      findMany: jest.fn().mockResolvedValue([]),
    },
    customer: {
      findFirst: jest.fn().mockResolvedValue({ id: 'cust-1' }),
      create: jest.fn().mockResolvedValue({ id: 'cust-1' }),
    },
  };

  const mockEncryption = {
    encryptJson: jest.fn().mockReturnValue('encrypted-creds'),
    decryptJson: jest.fn().mockReturnValue({ phoneNumberId: '12345', accessToken: 'meta-token' }),
  };

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        WhatsAppService,
        { provide: PrismaService, useValue: mockPrisma },
        { provide: EncryptionService, useValue: mockEncryption },
      ],
    }).compile();

    service = module.get<WhatsAppService>(WhatsAppService);
    prisma = module.get<PrismaService>(PrismaService);
    jest.clearAllMocks();
  });

  describe('sendMessage', () => {
    it('should create message log and handle simulated mode cleanly', async () => {
      const sent = await service.sendMessage(
        'biz-1',
        '+263771234567',
        'Hello from Bot',
        { simulated: true },
      );

      expect(sent).toBe(true);
      expect(mockPrisma.messageLog.create).toHaveBeenCalledWith({
        data: expect.objectContaining({
          businessId: 'biz-1',
          whatsappNumber: '263771234567',
          direction: 'outbound',
          messageBody: 'Hello from Bot',
          status: 'SENT',
        }),
      });
    });
  });

  describe('logIncomingMessage', () => {
    it('should find or create customer and record inbound message log', async () => {
      const logged = await service.logIncomingMessage(
        'biz-1',
        '+263771234567',
        'Hi, I want to buy shoes',
      );

      expect(logged).toBeDefined();
      expect(mockPrisma.customer.findFirst).toHaveBeenCalled();
      expect(mockPrisma.messageLog.create).toHaveBeenCalledWith({
        data: expect.objectContaining({
          businessId: 'biz-1',
          whatsappNumber: '263771234567',
          direction: 'inbound',
          messageBody: 'Hi, I want to buy shoes',
          status: 'RECEIVED',
        }),
      });
    });
  });
});
