import { Inject } from '@nestjs/common';
import { type ICommandHandler, CommandHandler } from '@nestjs/cqrs';
import { createId } from '@paralleldrive/cuid2';
import { ConflictException } from '@modules/shared';
import { ProjectDevelopmentEntity } from '../../../domain/entities/project-development.entity';
import {
  PROJECT_REPOSITORY,
  type IProjectRepository,
} from '../../../domain/repositories/project-development.repository';
import { CreateProjectCommand } from './create-project.command';

@CommandHandler(CreateProjectCommand)
export class CreateProjectHandler implements ICommandHandler<CreateProjectCommand> {
  constructor(
    @Inject(PROJECT_REPOSITORY)
    private readonly repo: IProjectRepository,
  ) {}

  async execute(cmd: CreateProjectCommand): Promise<{ id: string; slug: string }> {
    const existing = await this.repo.findBySlug(cmd.slug);
    if (existing) {
      throw new ConflictException(`Dự án với slug "${cmd.slug}" đã tồn tại`);
    }

    const now = new Date();
    const entity = new ProjectDevelopmentEntity(
      createId(),
      {
        name: cmd.name,
        slug: cmd.slug,
        developer: cmd.developer,
        developerLogo: cmd.developerLogo,
        totalUnits: cmd.totalUnits,
        completedUnits: 0,
        status: cmd.status,
        startDate: cmd.startDate,
        completionDate: cmd.completionDate,
        description: cmd.description,
        amenities: cmd.amenities,
        masterPlanUrl: cmd.masterPlanUrl,
        latitude: cmd.latitude,
        longitude: cmd.longitude,
        address: cmd.address,
        ward: cmd.ward,
        district: cmd.district,
        city: cmd.city,
        minPrice: cmd.minPrice,
        maxPrice: cmd.maxPrice,
        pricePerM2Range: cmd.pricePerM2Range,
        totalArea: cmd.totalArea,
        buildingCount: cmd.buildingCount,
        floorCount: cmd.floorCount,
        unitTypes: cmd.unitTypes,
        media: null,
        documents: null,
        tags: cmd.tags,
        suitableFor: cmd.suitableFor ?? [],
        whyThisLocation: cmd.whyThisLocation ?? null,
        isVerified: false,
        ownerId: cmd.ownerId ?? null,
      },
      now,
      now,
    );

    await this.repo.save(entity);
    return { id: entity.id, slug: entity.slug };
  }
}
