import { Inject, InternalServerErrorException } from '@nestjs/common';
import { QueryHandler, type IQueryHandler } from '@nestjs/cqrs';
import { DomainException, CacheService, CachePrefix, CacheTTL, Cacheable, LoggerService } from '@modules/shared';
import {
  MARKET_INDEX_REPOSITORY,
  type IMarketIndexRepository,
  type DistrictStatsResult,
} from '../../../domain/repositories/market-index.repository';
import { GetDistrictStatsQuery } from './get-district-stats.query';

export interface DistrictStatsDto {
  city: string;
  period: string;
  districts: DistrictStatsResult[];
}

@QueryHandler(GetDistrictStatsQuery)
export class GetDistrictStatsHandler implements IQueryHandler<GetDistrictStatsQuery> {
  constructor(
    @Inject(MARKET_INDEX_REPOSITORY) private readonly marketIndexRepo: IMarketIndexRepository,
    private readonly cacheService: CacheService,
    private readonly logger: LoggerService,
  ) {}

  @Cacheable({
    prefix: CachePrefix.MARKET_DISTRICT,
    ttl: CacheTTL.DISTRICT_STATS,
    resource: 'district_stats',
    keyFrom: (query: unknown) => {
      const q = query as GetDistrictStatsQuery;
      return [q.city, q.period];
    },
  })
  async execute(query: GetDistrictStatsQuery): Promise<DistrictStatsDto> {
    try {
      const districts = await this.marketIndexRepo.getDistrictStats(query.city, query.period);
      return { city: query.city, period: query.period, districts };
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Failed to truy vấn thống kê quận/huyện: ${error instanceof Error ? error.message : error}`,
        error instanceof Error ? error.stack : undefined,
        this.constructor.name,
      );
      throw new InternalServerErrorException('Không thể truy vấn thống kê quận/huyện. Vui lòng thử lại sau.');
    }
  }
}
