import { type IMarketIndexRepository, type MarketReportResult } from '../../domain/repositories/market-index.repository';
import { GenerateReportCommand } from '../commands/generate-report/generate-report.command';
import { GenerateReportHandler } from '../commands/generate-report/generate-report.handler';

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

  beforeEach(() => {
    mockRepo = {
      findById: vi.fn(),
      findByKey: vi.fn(),
      save: vi.fn(),
      update: vi.fn(),
      getMarketReport: vi.fn(),
      getHeatmap: vi.fn(),
      getPriceTrend: vi.fn(),
      getDistrictStats: vi.fn(),
    };
    handler = new GenerateReportHandler(mockRepo as any);
  });

  it('generates a market report for a city and period', async () => {
    const reportData: MarketReportResult[] = [
      {
        district: 'Quận 1',
        city: 'Hồ Chí Minh',
        propertyType: 'APARTMENT',
        period: '2026-Q1',
        medianPrice: '5000000000',
        avgPriceM2: 80000000,
        totalListings: 150,
        daysOnMarket: 45,
        inventoryLevel: 3.2,
        absorptionRate: 0.65,
        yoyChange: 0.08,
      },
    ];
    mockRepo.getMarketReport.mockResolvedValue(reportData);

    const command = new GenerateReportCommand('Hồ Chí Minh', '2026-Q1', 'APARTMENT');
    const result = await handler.execute(command);

    expect(result.city).toBe('Hồ Chí Minh');
    expect(result.period).toBe('2026-Q1');
    expect(result.data).toEqual(reportData);
    expect(result.generatedAt).toBeDefined();
    expect(mockRepo.getMarketReport).toHaveBeenCalledWith('Hồ Chí Minh', '2026-Q1', 'APARTMENT');
  });

  it('generates report without propertyType filter', async () => {
    mockRepo.getMarketReport.mockResolvedValue([]);

    const command = new GenerateReportCommand('Hà Nội', '2026-Q1');
    const result = await handler.execute(command);

    expect(result.city).toBe('Hà Nội');
    expect(result.data).toEqual([]);
    expect(mockRepo.getMarketReport).toHaveBeenCalledWith('Hà Nội', '2026-Q1', undefined);
  });
});
