import { Inject, InternalServerErrorException } from '@nestjs/common';
import { QueryHandler, type IQueryHandler } from '@nestjs/cqrs';
import { DomainException, CacheService, CachePrefix, CacheTTL, LoggerService } from '@modules/shared';
import {
  MARKET_INDEX_REPOSITORY,
  type IMarketIndexRepository,
  type PriceTrendPoint,
} from '../../../domain/repositories/market-index.repository';
import { GetPriceTrendQuery } from './get-price-trend.query';

export interface PriceTrendDto {
  district: string;
  city: string;
  propertyType: string;
  trend: PriceTrendPoint[];
}

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

  async execute(query: GetPriceTrendQuery): Promise<PriceTrendDto> {
    try {
      const cacheKey = CacheService.buildKey(
        CachePrefix.MARKET_TREND,
        query.district,
        query.city,
        query.propertyType,
        query.periods?.join(','),
      );

      return this.cache.getOrSet(
        cacheKey,
        async () => {
          const trend = await this.marketIndexRepo.getPriceTrend(
            query.district,
            query.city,
            query.propertyType,
            query.periods,
          );
          return { district: query.district, city: query.city, propertyType: query.propertyType, trend };
        },
        CacheTTL.MARKET_DATA,
        'price_trend',
      );
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Failed to truy vấn xu hướng giá: ${error instanceof Error ? error.message : error}`,
        error instanceof Error ? error.stack : undefined,
        this.constructor.name,
      );
      throw new InternalServerErrorException('Không thể truy vấn xu hướng giá. Vui lòng thử lại sau.');
    }
  }
}
