import type { ILeadRepository } from '../../domain/repositories/lead.repository';
import { GetLeadStatsHandler } from '../queries/get-lead-stats/get-lead-stats.handler';
import { GetLeadStatsQuery } from '../queries/get-lead-stats/get-lead-stats.query';

describe('GetLeadStatsHandler', () => {
  let handler: GetLeadStatsHandler;
  let mockLeadRepo: { [K in keyof ILeadRepository]: ReturnType<typeof vi.fn> };
  let mockPrisma: {
    agent: { findUnique: ReturnType<typeof vi.fn> };
  };

  beforeEach(() => {
    mockLeadRepo = {
      findById: vi.fn(),
      save: vi.fn(),
      update: vi.fn(),
      delete: vi.fn(),
      findByAgent: vi.fn(),
      getStatsByAgent: vi.fn(),
    };

    mockPrisma = {
      agent: { findUnique: vi.fn() },
    };

    handler = new GetLeadStatsHandler(
      mockLeadRepo as any,
      mockPrisma as any,
    );
  });

  it('returns stats for the agent', async () => {
    mockPrisma.agent.findUnique.mockResolvedValue({ id: 'agent-1' });

    const mockStats = {
      totalLeads: 25,
      byStatus: {
        NEW: 5,
        CONTACTED: 8,
        QUALIFIED: 4,
        NEGOTIATING: 3,
        CONVERTED: 3,
        LOST: 2,
      },
      conversionRate: 0.12,
      avgScore: 65.5,
    };
    mockLeadRepo.getStatsByAgent.mockResolvedValue(mockStats);

    const query = new GetLeadStatsQuery('user-1');
    const result = await handler.execute(query);

    expect(result).toEqual(mockStats);
    expect(result.totalLeads).toBe(25);
    expect(result.conversionRate).toBe(0.12);
    expect(mockLeadRepo.getStatsByAgent).toHaveBeenCalledWith('agent-1');
  });

  it('throws NotFoundException when agent not found', async () => {
    mockPrisma.agent.findUnique.mockResolvedValue(null);

    const query = new GetLeadStatsQuery('not-an-agent');

    await expect(handler.execute(query)).rejects.toThrow(
      "Agent with id 'not-an-agent' not found",
    );
    expect(mockLeadRepo.getStatsByAgent).not.toHaveBeenCalled();
  });
});
