import { Inject, InternalServerErrorException } from '@nestjs/common';
import { CommandHandler, EventBus, type ICommandHandler } from '@nestjs/cqrs';
import { LISTING_REPOSITORY, type IListingRepository } from '@modules/listings';
import { DomainException, NotFoundException, ValidationException, LoggerService } from '@modules/shared';
import { ListingRejectedEvent } from '../../../domain/events/listing-rejected.event';
import { RejectListingCommand } from './reject-listing.command';

export interface RejectListingResult {
  listingId: string;
  status: string;
  message: string;
}

@CommandHandler(RejectListingCommand)
export class RejectListingHandler implements ICommandHandler<RejectListingCommand> {
  constructor(
    @Inject(LISTING_REPOSITORY) private readonly listingRepo: IListingRepository,
    private readonly eventBus: EventBus,
    private readonly logger: LoggerService,
  ) {}

  async execute(command: RejectListingCommand): Promise<RejectListingResult> {
    try {
      const listing = await this.listingRepo.findById(command.listingId);
      if (!listing) {
        throw new NotFoundException('Listing không tồn tại');
      }

      if (listing.status !== 'PENDING_REVIEW') {
        throw new ValidationException(
          `Listing đang ở trạng thái ${listing.status}, chỉ có thể từ chối listing đang chờ duyệt`,
          { currentStatus: listing.status },
        );
      }

      listing.reject(command.reason);
      await this.listingRepo.update(listing);

      this.eventBus.publish(
        new ListingRejectedEvent(listing.id, command.adminId, command.reason),
      );

      return {
        listingId: listing.id,
        status: 'REJECTED',
        message: 'Listing đã bị từ chối',
      };
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Failed to reject listing ${command.listingId}: ${error instanceof Error ? error.message : String(error)}`,
        error instanceof Error ? error.stack : undefined,
        'RejectListingHandler',
      );
      throw new InternalServerErrorException('Lỗi khi từ chối listing');
    }
  }
}
