import { Inject, InternalServerErrorException } from '@nestjs/common';
import { QueryHandler, type IQueryHandler } from '@nestjs/cqrs';
import { DomainException, CacheService, CachePrefix, CacheTTL, LoggerService } from '@modules/shared';
import {
  AVM_SERVICE,
  type IAVMService,
  type ValuationResult,
} from '../../../domain/services/avm-service';
import { GetValuationQuery } from './get-valuation.query';

export type ValuationDto = ValuationResult;

@QueryHandler(GetValuationQuery)
export class GetValuationHandler implements IQueryHandler<GetValuationQuery> {
  constructor(
    @Inject(AVM_SERVICE) private readonly avmService: IAVMService,
    private readonly cache: CacheService,
    private readonly logger: LoggerService,
  ) {}

  async execute(query: GetValuationQuery): Promise<ValuationDto> {
    try {
      const cacheKey = CacheService.buildKey(
        CachePrefix.VALUATION,
        query.propertyId ?? '',
        query.latitude?.toString(),
        query.longitude?.toString(),
        query.areaM2?.toString(),
        query.propertyType,
      );

      return this.cache.getOrSet(
        cacheKey,
        async () => {
          return this.avmService.estimateValue({
            propertyId: query.propertyId,
            latitude: query.latitude,
            longitude: query.longitude,
            areaM2: query.areaM2,
            propertyType: query.propertyType,
          });
        },
        CacheTTL.MARKET_DATA,
        'valuation',
      );
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Failed to định giá bất động sản: ${error instanceof Error ? error.message : error}`,
        error instanceof Error ? error.stack : undefined,
        this.constructor.name,
      );
      throw new InternalServerErrorException('Không thể định giá bất động sản. Vui lòng thử lại sau.');
    }
  }
}
