import { type IAdminQueryRepository } from '../../domain/repositories/admin-query.repository';
import { GetRevenueStatsHandler } from '../queries/get-revenue-stats/get-revenue-stats.handler';
import { GetRevenueStatsQuery } from '../queries/get-revenue-stats/get-revenue-stats.query';

describe('GetRevenueStatsHandler', () => {
  let handler: GetRevenueStatsHandler;
  let mockRepo: { [K in keyof IAdminQueryRepository]: ReturnType<typeof vi.fn> };

  beforeEach(() => {
    mockRepo = {
      getModerationQueue: vi.fn(),
      getDashboardStats: vi.fn(),
      getRevenueStats: vi.fn(),
      getUsers: vi.fn(),
      getUserDetail: vi.fn(),
      getKycQueue: vi.fn(),
    };

    handler = new GetRevenueStatsHandler(mockRepo as any);
  });

  it('returns revenue stats grouped by month', async () => {
    const mockStats = [
      {
        period: '2026-01',
        totalRevenue: 100_000_000n,
        subscriptionRevenue: 60_000_000n,
        listingFeeRevenue: 30_000_000n,
        featuredListingRevenue: 10_000_000n,
        transactionCount: 42,
      },
      {
        period: '2026-02',
        totalRevenue: 150_000_000n,
        subscriptionRevenue: 80_000_000n,
        listingFeeRevenue: 50_000_000n,
        featuredListingRevenue: 20_000_000n,
        transactionCount: 58,
      },
    ];

    mockRepo.getRevenueStats.mockResolvedValue(mockStats);

    const startDate = new Date('2026-01-01');
    const endDate = new Date('2026-02-28');
    const query = new GetRevenueStatsQuery(startDate, endDate, 'month');
    const result = await handler.execute(query);

    expect(result).toEqual(mockStats);
    expect(result).toHaveLength(2);
    expect(mockRepo.getRevenueStats).toHaveBeenCalledWith(startDate, endDate, 'month');
  });

  it('returns revenue stats grouped by day', async () => {
    const mockStats = [
      {
        period: '2026-03-01',
        totalRevenue: 5_000_000n,
        subscriptionRevenue: 3_000_000n,
        listingFeeRevenue: 1_500_000n,
        featuredListingRevenue: 500_000n,
        transactionCount: 3,
      },
    ];

    mockRepo.getRevenueStats.mockResolvedValue(mockStats);

    const startDate = new Date('2026-03-01');
    const endDate = new Date('2026-03-01');
    const query = new GetRevenueStatsQuery(startDate, endDate, 'day');
    const result = await handler.execute(query);

    expect(result).toEqual(mockStats);
    expect(mockRepo.getRevenueStats).toHaveBeenCalledWith(startDate, endDate, 'day');
  });

  it('returns empty array when no revenue data', async () => {
    mockRepo.getRevenueStats.mockResolvedValue([]);

    const query = new GetRevenueStatsQuery(
      new Date('2020-01-01'),
      new Date('2020-12-31'),
      'month',
    );
    const result = await handler.execute(query);

    expect(result).toEqual([]);
    expect(result).toHaveLength(0);
  });

  it('uses default groupBy of month in query', () => {
    const query = new GetRevenueStatsQuery(
      new Date('2026-01-01'),
      new Date('2026-12-31'),
    );

    expect(query.groupBy).toBe('month');
  });
});
