import { type CacheService } from '@modules/shared/infrastructure/cache.service';
import { type IMarketIndexRepository, type HeatmapDataPoint } from '../../domain/repositories/market-index.repository';
import { GetHeatmapHandler } from '../queries/get-heatmap/get-heatmap.handler';
import { GetHeatmapQuery } from '../queries/get-heatmap/get-heatmap.query';

describe('GetHeatmapHandler', () => {
  let handler: GetHeatmapHandler;
  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(),
      getHeatmapWard: vi.fn(),
      getListingVolumeByWard: vi.fn(),
      getPriceTrend: vi.fn(),
      getDistrictStats: vi.fn(),
    };
    const mockCache = { getOrSet: vi.fn((_key: string, loader: () => Promise<unknown>) => loader()) } as unknown as CacheService;
    handler = new GetHeatmapHandler(mockRepo as any, mockCache, { log: vi.fn(), error: vi.fn(), warn: vi.fn() } as any);
  });

  it('returns heatmap data for a city and period', async () => {
    const dataPoints: HeatmapDataPoint[] = [
      { district: 'Quận 1', city: 'Hồ Chí Minh', avgPriceM2: 120000000, totalListings: 200, medianPrice: '6000000000' },
      { district: 'Quận 7', city: 'Hồ Chí Minh', avgPriceM2: 80000000, totalListings: 350, medianPrice: '4000000000' },
    ];
    mockRepo.getHeatmap.mockResolvedValue(dataPoints);

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

    expect(result.city).toBe('Hồ Chí Minh');
    expect(result.period).toBe('2026-Q1');
    expect(result.level).toBe('district');
    expect(result.dataPoints).toEqual(dataPoints);
    expect(mockRepo.getHeatmap).toHaveBeenCalledWith('Hồ Chí Minh', '2026-Q1');
  });

  it('returns empty dataPoints when no data available', async () => {
    mockRepo.getHeatmap.mockResolvedValue([]);

    const query = new GetHeatmapQuery('Đà Nẵng', '2025-Q4');
    const result = await handler.execute(query);

    expect(result.dataPoints).toEqual([]);
  });
});
