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

export type PredictValuationDto = ValuationResult;

@QueryHandler(PredictValuationQuery)
export class PredictValuationHandler implements IQueryHandler<PredictValuationQuery> {
  constructor(
    @Inject(AVM_SERVICE) private readonly avmService: IAVMService,
    private readonly logger: LoggerService,
  ) {}

  async execute(query: PredictValuationQuery): Promise<PredictValuationDto> {
    try {
      return await this.avmService.estimateValue({
        propertyId: undefined,
        propertyType: query.propertyType,
        areaM2: query.area,
        district: query.district,
        city: query.city,
        bedrooms: query.bedrooms,
        bathrooms: query.bathrooms,
        floors: query.floors,
        frontage: query.frontage,
        roadWidth: query.roadWidth,
        yearBuilt: query.yearBuilt,
        hasLegalPaper: query.hasLegalPaper,
        latitude: query.latitude,
        longitude: query.longitude,
        projectId: query.projectId,
        imageUrl: query.imageUrl,
        description: query.description,
        deepAnalysis: query.deepAnalysis,
        useV2: query.useV2,
        distanceToHospitalKm: query.distanceToHospitalKm,
        distanceToParkKm: query.distanceToParkKm,
        distanceToMallKm: query.distanceToMallKm,
        floodZoneRisk: query.floodZoneRisk,
        hasElevator: query.hasElevator,
        hasParking: query.hasParking,
        hasPool: query.hasPool,
      });
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Predict valuation failed: ${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.',
      );
    }
  }
}
