import { Injectable } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
import { CacheService, CachePrefix, LoggerService } from '@modules/shared';
import { ListingIndexerService } from '../services/listing-indexer.service';

@Injectable()
export class ListingApprovedEventHandler {
  constructor(
    private readonly indexer: ListingIndexerService,
    private readonly cache: CacheService,
    private readonly logger: LoggerService,
  ) {}

  @OnEvent('listing.approved')
  async handle(payload: { listingId: string }): Promise<void> {
    this.logger.log(`Handling listing.approved for ${payload.listingId}`, 'ListingApprovedHandler');
    await Promise.all([
      this.indexer.indexListing(payload.listingId),
      this.invalidateSearchAndAnalyticsCache(payload.listingId),
    ]);
  }

  @OnEvent('listing.updated')
  async handleUpdate(payload: { listingId: string }): Promise<void> {
    this.logger.log(`Handling listing.updated for ${payload.listingId}`, 'ListingApprovedHandler');
    await Promise.all([
      this.indexer.indexListing(payload.listingId),
      this.invalidateSearchAndAnalyticsCache(payload.listingId),
    ]);
  }

  @OnEvent('listing.deactivated')
  async handleDeactivation(payload: { listingId: string }): Promise<void> {
    this.logger.log(`Handling listing.deactivated for ${payload.listingId}`, 'ListingApprovedHandler');
    await Promise.all([
      this.indexer.removeListing(payload.listingId),
      this.invalidateSearchAndAnalyticsCache(payload.listingId),
    ]);
  }

  @OnEvent('listing.sold')
  async handleSold(payload: { listingId: string }): Promise<void> {
    this.logger.log(`Handling listing.sold for ${payload.listingId}`, 'ListingApprovedHandler');
    await Promise.all([
      this.indexer.removeListing(payload.listingId),
      this.invalidateSearchAndAnalyticsCache(payload.listingId),
    ]);
  }

  private async invalidateSearchAndAnalyticsCache(listingId: string): Promise<void> {
    await Promise.all([
      this.cache.invalidate(CacheService.buildKey(CachePrefix.LISTING, listingId)),
      this.cache.invalidateByPrefix(CachePrefix.SEARCH),
      this.cache.invalidateByPrefix(CachePrefix.GEO_SEARCH),
      this.cache.invalidateByPrefix(CachePrefix.MARKET_DISTRICT),
      this.cache.invalidateByPrefix(CachePrefix.MARKET_REPORT),
      this.cache.invalidateByPrefix(CachePrefix.MARKET_HEATMAP),
      this.cache.invalidateByPrefix(CachePrefix.MARKET_TREND),
    ]);
    this.logger.log(`Cache invalidated for listing ${listingId}`, 'ListingApprovedHandler');
  }
}
