import { Inject } from '@nestjs/common';
import { type ICommandHandler, CommandHandler } from '@nestjs/cqrs';
import { createId } from '@paralleldrive/cuid2';
import { EventBusService } from '@modules/shared';
import { TransferListingEntity } from '../../../domain/entities/transfer-listing.entity';
import { TransferListingCreatedEvent } from '../../../domain/events';
import {
  TRANSFER_LISTING_REPOSITORY,
  type ITransferListingRepository,
} from '../../../domain/repositories/transfer-listing.repository';
import { CreateTransferListingCommand } from './create-transfer-listing.command';

@CommandHandler(CreateTransferListingCommand)
export class CreateTransferListingHandler implements ICommandHandler<CreateTransferListingCommand> {
  constructor(
    @Inject(TRANSFER_LISTING_REPOSITORY)
    private readonly repo: ITransferListingRepository,
    private readonly eventBus: EventBusService,
  ) {}

  async execute(cmd: CreateTransferListingCommand): Promise<{ id: string }> {
    const id = createId();
    const now = new Date();
    const entity = new TransferListingEntity(id, {
      sellerId: cmd.sellerId,
      category: cmd.category,
      status: 'DRAFT',
      title: cmd.title,
      description: cmd.description,
      address: cmd.address,
      ward: cmd.ward,
      district: cmd.district,
      city: cmd.city,
      latitude: cmd.latitude,
      longitude: cmd.longitude,
      askingPriceVND: cmd.askingPriceVND,
      aiEstimatePriceVND: null,
      aiConfidence: null,
      pricingSource: cmd.pricingSource,
      isNegotiable: cmd.isNegotiable,
      areaM2: cmd.areaM2,
      monthlyRentVND: cmd.monthlyRentVND,
      depositMonths: cmd.depositMonths,
      remainingLeaseMo: cmd.remainingLeaseMo,
      businessType: cmd.businessType,
      footTraffic: cmd.footTraffic,
      media: null,
      moderationScore: null,
      moderationNotes: null,
      viewCount: 0,
      saveCount: 0,
      inquiryCount: 0,
      contactPhone: cmd.contactPhone,
      contactName: cmd.contactName,
      featuredUntil: null,
      expiresAt: null,
      publishedAt: null,
    }, now, now);

    await this.repo.save(entity, cmd.items);

    this.eventBus.publish(
      new TransferListingCreatedEvent(id, cmd.sellerId, cmd.category),
    );

    return { id };
  }
}
