import { Inject, InternalServerErrorException } from '@nestjs/common';
import { QueryHandler, type IQueryHandler } from '@nestjs/cqrs';
import { CacheService, CachePrefix, CacheTTL, DomainException, LoggerService } from '@modules/shared';
import {
  VALUATION_REPOSITORY,
  type IValuationRepository,
} from '../../../domain/repositories/valuation.repository';
import { type ValuationHistoryPoint } from '../../../domain/services/avm-service';
import { ValuationHistoryQuery } from './valuation-history.query';

export interface ValuationHistoryDto {
  propertyId: string;
  history: ValuationHistoryPoint[];
  totalRecords: number;
}

@QueryHandler(ValuationHistoryQuery)
export class ValuationHistoryHandler implements IQueryHandler<ValuationHistoryQuery> {
  constructor(
    @Inject(VALUATION_REPOSITORY) private readonly valuationRepo: IValuationRepository,
    private readonly cache: CacheService,
    private readonly logger: LoggerService,
  ) {}

  async execute(query: ValuationHistoryQuery): Promise<ValuationHistoryDto> {
    try {
      const cacheKey = CacheService.buildKey(
        CachePrefix.VALUATION,
        'history',
        query.propertyId,
        query.limit.toString(),
      );

      return await this.cache.getOrSet(
        cacheKey,
        async () => {
          const entities = await this.valuationRepo.findByPropertyId(query.propertyId);
          const limited = entities.slice(0, query.limit);

          const history: ValuationHistoryPoint[] = limited.map((entity) => ({
            estimatedPrice: entity.estimatedPrice.toString(),
            confidence: entity.confidence,
            pricePerM2: entity.pricePerM2,
            modelVersion: entity.modelVersion,
            valuedAt: entity.createdAt.toISOString(),
          }));

          return {
            propertyId: query.propertyId,
            history,
            totalRecords: entities.length,
          };
        },
        CacheTTL.DISTRICT_STATS,
        'valuation_history',
      );
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Valuation history failed for property ${query.propertyId}: ${error instanceof Error ? error.message : error}`,
        error instanceof Error ? error.stack : undefined,
        this.constructor.name,
      );
      throw new InternalServerErrorException('Không thể lấy lịch sử định giá. Vui lòng thử lại sau.');
    }
  }
}
