import { Inject } from '@nestjs/common';
import { QueryHandler, type IQueryHandler } from '@nestjs/cqrs';
import { CacheService, CachePrefix, CacheTTL } from '@modules/shared';
import { type ListingSearchItem } from '../../../domain/repositories/listing-read.dto';
import { LISTING_REPOSITORY, type IListingRepository, type PaginatedResult } from '../../../domain/repositories/listing.repository';
import { SearchListingsQuery } from './search-listings.query';

@QueryHandler(SearchListingsQuery)
export class SearchListingsHandler implements IQueryHandler<SearchListingsQuery> {
  constructor(
    @Inject(LISTING_REPOSITORY) private readonly listingRepo: IListingRepository,
    private readonly cacheService: CacheService,
  ) {}

  async execute(query: SearchListingsQuery): Promise<PaginatedResult<ListingSearchItem>> {
    const cacheKey = CacheService.buildKey(
      CachePrefix.SEARCH,
      query.status,
      query.transactionType,
      query.propertyType,
      query.city,
      query.district,
      query.minPrice?.toString(),
      query.maxPrice?.toString(),
      query.minArea?.toString(),
      query.maxArea?.toString(),
      query.bedrooms?.toString(),
      String(query.page),
      String(query.limit),
    );

    return this.cacheService.getOrSet(
      cacheKey,
      async () =>
        this.listingRepo.search({
          status: query.status,
          transactionType: query.transactionType,
          propertyType: query.propertyType,
          city: query.city,
          district: query.district,
          minPrice: query.minPrice,
          maxPrice: query.maxPrice,
          minArea: query.minArea,
          maxArea: query.maxArea,
          bedrooms: query.bedrooms,
          page: query.page,
          limit: query.limit,
        }),
      CacheTTL.SEARCH_RESULTS,
      'listing_search',
    );
  }
}
