import { Inject } from '@nestjs/common';
import { CommandHandler, type EventBus, type ICommandHandler } from '@nestjs/cqrs';
import { LISTING_REPOSITORY, type IListingRepository } from '@modules/listings/domain/repositories/listing.repository';
import { NotFoundException, ValidationException } 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,
  ) {}

  async execute(command: RejectListingCommand): Promise<RejectListingResult> {
    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',
    };
  }
}
