import { Inject } from '@nestjs/common';
import { type ICommandHandler, CommandHandler } from '@nestjs/cqrs';
import { createId } from '@paralleldrive/cuid2';
import { NotFoundException } from '@modules/shared';
import { IndustrialListingEntity } from '../../../domain/entities/industrial-listing.entity';
import {
  INDUSTRIAL_LISTING_REPOSITORY,
  type IIndustrialListingRepository,
} from '../../../domain/repositories/industrial-listing.repository';
import { type IIndustrialParkRepository, INDUSTRIAL_PARK_REPOSITORY  } from '../../../domain/repositories/industrial-park.repository';
import { TypesenseIndustrialService } from '../../../infrastructure/services/typesense-industrial.service';
import { CreateIndustrialListingCommand } from './create-industrial-listing.command';

@CommandHandler(CreateIndustrialListingCommand)
export class CreateIndustrialListingHandler implements ICommandHandler<CreateIndustrialListingCommand> {
  constructor(
    @Inject(INDUSTRIAL_LISTING_REPOSITORY)
    private readonly repo: IIndustrialListingRepository,
    @Inject(INDUSTRIAL_PARK_REPOSITORY)
    private readonly parkRepo: IIndustrialParkRepository,
    private readonly typesense: TypesenseIndustrialService,
  ) {}

  async execute(cmd: CreateIndustrialListingCommand): Promise<{ id: string }> {
    const park = await this.parkRepo.findById(cmd.parkId);
    if (!park) {
      throw new NotFoundException('Industrial park', cmd.parkId);
    }

    const now = new Date();
    const entity = new IndustrialListingEntity(
      createId(),
      {
        parkId: cmd.parkId,
        agentId: cmd.agentId,
        sellerId: cmd.sellerId,
        propertyType: cmd.propertyType,
        leaseType: cmd.leaseType,
        status: 'DRAFT',
        title: cmd.title,
        description: cmd.description,
        areaM2: cmd.areaM2,
        ceilingHeightM: cmd.ceilingHeightM,
        floorLoadTonM2: cmd.floorLoadTonM2,
        columnSpacingM: cmd.columnSpacingM,
        dockCount: cmd.dockCount,
        craneCapacityTon: cmd.craneCapacityTon,
        hasMezzanine: cmd.hasMezzanine,
        hasOfficeArea: cmd.hasOfficeArea,
        officeAreaM2: cmd.officeAreaM2,
        priceUsdM2: cmd.priceUsdM2,
        pricingUnit: cmd.pricingUnit,
        totalLeasePrice: cmd.totalLeasePrice,
        managementFee: cmd.managementFee,
        depositMonths: cmd.depositMonths,
        minLeaseYears: cmd.minLeaseYears,
        maxLeaseYears: cmd.maxLeaseYears,
        leaseExpiry: cmd.leaseExpiry,
        availableFrom: cmd.availableFrom,
        powerCapacityKva: cmd.powerCapacityKva,
        waterSupplyM3Day: cmd.waterSupplyM3Day,
        media: cmd.media,
        viewCount: 0,
        inquiryCount: 0,
        publishedAt: null,
      },
      now,
      now,
    );

    await this.repo.save(entity);
    await this.typesense.indexListing(entity.id).catch(() => {});
    return { id: entity.id };
  }
}
