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

export interface BulkModerateResult {
  processed: number;
  succeeded: string[];
  failed: Array<{ listingId: string; reason: string }>;
}

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

  async execute(command: BulkModerateListingsCommand): Promise<BulkModerateResult> {
    try {
      if (command.listingIds.length === 0) {
        throw new ValidationException('Danh sách listing không được rỗng', {});
      }

      if (command.listingIds.length > 50) {
        throw new ValidationException('Tối đa 50 listing mỗi lần', {
          count: command.listingIds.length,
        });
      }

      if (command.action === 'reject' && !command.reason) {
        throw new ValidationException('Lý do từ chối là bắt buộc', {});
      }

      const succeeded: string[] = [];
      const failed: Array<{ listingId: string; reason: string }> = [];

      for (const listingId of command.listingIds) {
        try {
          const listing = await this.listingRepo.findById(listingId);
          if (!listing) {
            failed.push({ listingId, reason: 'Listing không tồn tại' });
            continue;
          }

          if (listing.status !== 'PENDING_REVIEW') {
            failed.push({ listingId, reason: `Trạng thái hiện tại: ${listing.status}` });
            continue;
          }

          if (command.action === 'approve') {
            listing.approve();
            await this.listingRepo.update(listing);
            this.eventBus.publish(new ListingApprovedEvent(listing.id, command.adminId));
          } else {
            listing.reject(command.reason!);
            await this.listingRepo.update(listing);
            this.eventBus.publish(new ListingRejectedEvent(listing.id, command.adminId, command.reason!));
          }

          succeeded.push(listingId);
        } catch (error) {
          const message = error instanceof Error ? error.message : 'Lỗi không xác định';
          failed.push({ listingId, reason: message });
        }
      }

      return {
        processed: command.listingIds.length,
        succeeded,
        failed,
      };
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Failed to bulk moderate listings: ${error instanceof Error ? error.message : String(error)}`,
        error instanceof Error ? error.stack : undefined,
        'BulkModerateListingsHandler',
      );
      throw new InternalServerErrorException('Lỗi khi duyệt/từ chối hàng loạt listing');
    }
  }
}
