import { Inject } from '@nestjs/common';
import { EventsHandler, type IEventHandler, CommandBus } from '@nestjs/cqrs';
import { ListingCreatedEvent } from '@modules/listings/domain/events/listing-created.event';
import { ModerateListingCommand } from '@modules/listings/application/commands/moderate-listing/moderate-listing.command';
import { PrismaService, LoggerService } from '@modules/shared';
import {
  AI_SERVICE_CLIENT,
  type IAiServiceClient,
} from '../../infrastructure/services/ai-service.client';

const AUTO_REJECT_THRESHOLD = 0.8;
const AI_MODERATOR_ID = 'system:ai-moderation';

@EventsHandler(ListingCreatedEvent)
export class ListingCreatedModerationHandler implements IEventHandler<ListingCreatedEvent> {
  constructor(
    @Inject(AI_SERVICE_CLIENT) private readonly aiClient: IAiServiceClient,
    private readonly commandBus: CommandBus,
    private readonly prisma: PrismaService,
    private readonly logger: LoggerService,
  ) {}

  async handle(event: ListingCreatedEvent): Promise<void> {
    try {
      await this.moderateListing(event);
    } catch (err) {
      this.logger.warn(
        `AI moderation skipped for listing ${event.aggregateId}: ${(err as Error).message}`,
        'ListingCreatedModerationHandler',
      );
    }
  }

  private async moderateListing(event: ListingCreatedEvent): Promise<void> {
    const property = await this.prisma.property.findUnique({
      where: { id: event.propertyId },
      select: { title: true, description: true },
    });

    if (!property) return;

    const textToModerate = `${property.title}\n${property.description}`;

    const result = await this.aiClient.moderate({
      text: textToModerate,
      context: 'listing',
    });

    if (!result.is_flagged) {
      this.logger.debug(
        `Listing ${event.aggregateId} passed AI moderation (score: ${result.score})`,
        'ListingCreatedModerationHandler',
      );
      return;
    }

    this.logger.log(
      `Listing ${event.aggregateId} flagged by AI moderation (score: ${result.score}, ` +
        `flags: ${result.flags.map((f) => f.category).join(', ')})`,
      'ListingCreatedModerationHandler',
    );

    const flagNotes = result.flags
      .map((f) => `[${f.severity}] ${f.category}: ${f.reason}`)
      .join('; ');

    const action = result.score >= AUTO_REJECT_THRESHOLD ? 'reject' : 'approve';

    await this.commandBus.execute(
      new ModerateListingCommand(
        event.aggregateId,
        AI_MODERATOR_ID,
        action,
        result.score,
        `[AI Auto-Moderation] ${flagNotes}`,
      ),
    );
  }
}
