import { type QueryBus } from '@nestjs/cqrs';
import { GetDistrictStatsQuery } from '../../application/queries/get-district-stats/get-district-stats.query';
import { GetHeatmapQuery } from '../../application/queries/get-heatmap/get-heatmap.query';
import { GetMarketReportQuery } from '../../application/queries/get-market-report/get-market-report.query';
import { GetPriceTrendQuery } from '../../application/queries/get-price-trend/get-price-trend.query';
import { AnalyticsController } from '../controllers/analytics.controller';

describe('AnalyticsController', () => {
  let controller: AnalyticsController;
  let mockQueryBus: { execute: ReturnType<typeof vi.fn> };

  beforeEach(() => {
    mockQueryBus = { execute: vi.fn() };
    controller = new AnalyticsController(mockQueryBus as unknown as QueryBus);
  });

  it('getMarketReport executes GetMarketReportQuery with correct params', async () => {
    const expected = { city: 'Hồ Chí Minh', period: '2026-Q1', districts: [] };
    mockQueryBus.execute.mockResolvedValue(expected);

    const result = await controller.getMarketReport({
      city: 'Hồ Chí Minh',
      period: '2026-Q1',
      propertyType: 'APARTMENT',
    } as any);

    expect(mockQueryBus.execute).toHaveBeenCalledWith(
      new GetMarketReportQuery('Hồ Chí Minh', '2026-Q1', 'APARTMENT'),
    );
    expect(result).toBe(expected);
  });

  it('getPriceTrend executes GetPriceTrendQuery with correct params', async () => {
    const expected = { district: 'Quận 1', city: 'Hồ Chí Minh', trend: [] };
    mockQueryBus.execute.mockResolvedValue(expected);

    const result = await controller.getPriceTrend({
      district: 'Quận 1',
      city: 'Hồ Chí Minh',
      propertyType: 'APARTMENT',
      periods: ['2025-Q4', '2026-Q1'],
    } as any);

    expect(mockQueryBus.execute).toHaveBeenCalledWith(
      new GetPriceTrendQuery('Quận 1', 'Hồ Chí Minh', 'APARTMENT', ['2025-Q4', '2026-Q1']),
    );
    expect(result).toBe(expected);
  });

  it('getHeatmap executes GetHeatmapQuery with correct params', async () => {
    const expected = { city: 'Hồ Chí Minh', data: [] };
    mockQueryBus.execute.mockResolvedValue(expected);

    const result = await controller.getHeatmap({
      city: 'Hồ Chí Minh',
      period: '2026-Q1',
    } as any);

    expect(mockQueryBus.execute).toHaveBeenCalledWith(
      new GetHeatmapQuery('Hồ Chí Minh', '2026-Q1'),
    );
    expect(result).toBe(expected);
  });

  it('getDistrictStats executes GetDistrictStatsQuery with correct params', async () => {
    const expected = { city: 'Hà Nội', stats: [] };
    mockQueryBus.execute.mockResolvedValue(expected);

    const result = await controller.getDistrictStats({
      city: 'Hà Nội',
      period: '2026-Q1',
    } as any);

    expect(mockQueryBus.execute).toHaveBeenCalledWith(
      new GetDistrictStatsQuery('Hà Nội', '2026-Q1'),
    );
    expect(result).toBe(expected);
  });
});
