import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { CreateLotDto } from './dto/create-lot.dto';
import { SetTantiemesDto } from './dto/set-tantiemes.dto';
import { CreateVehicleDto } from './dto/create-vehicle.dto';

@Injectable()
export class LotsService {
  constructor(private readonly prisma: PrismaService) {}

  async create(dto: CreateLotDto) {
    const spatialUnit = await this.prisma.spatialUnit.findUnique({
      where: { id: dto.spatialUnitId },
    });
    if (!spatialUnit) throw new BadRequestException('Spatial unit not found');

    return this.prisma.lot.create({
      data: {
        complexId: spatialUnit.complexId,
        spatialUnitId: dto.spatialUnitId,
        lotNumber: dto.lotNumber,
        type: dto.type,
        surfaceM2: dto.surfaceM2,
        tantiemesGeneral: dto.tantiemesGeneral ?? 0,
      },
    });
  }

  findByComplex(complexId: string) {
    return this.prisma.lot.findMany({
      where: { complexId },
      include: {
        spatialUnit: true,
        residents: { where: { endDate: null }, include: { user: true } },
      },
      orderBy: { lotNumber: 'asc' },
    });
  }

  async findOne(id: string) {
    const lot = await this.prisma.lot.findUnique({
      where: { id },
      include: {
        spatialUnit: true,
        residents: { include: { user: true } },
        tantiemes: { include: { repartitionKey: true } },
        vehicles: true,
      },
    });
    if (!lot) throw new NotFoundException();
    return lot;
  }

  async setTantiemes(lotId: string, dto: SetTantiemesDto) {
    await this.prisma.lotTantieme.upsert({
      where: {
        lotId_repartitionKeyId: { lotId, repartitionKeyId: dto.repartitionKeyId },
      },
      create: {
        lotId,
        repartitionKeyId: dto.repartitionKeyId,
        quota: dto.quota,
      },
      update: { quota: dto.quota },
    });
    return this.findOne(lotId);
  }

  // ================= VEHICLES =================

  listVehicles(lotId: string) {
    return this.prisma.vehicle.findMany({
      where: { lotId },
      include: { resident: { include: { user: true } } },
      orderBy: { createdAt: 'desc' },
    });
  }

  async addVehicle(lotId: string, dto: CreateVehicleDto) {
    const resident = await this.prisma.resident.findUnique({ where: { id: dto.residentId } });
    if (!resident) throw new BadRequestException('Resident not found');
    if (resident.lotId !== lotId) throw new BadRequestException('Resident does not belong to this lot');
    const plate = dto.plateNumber.trim().toUpperCase();
    return this.prisma.vehicle.create({
      data: {
        lotId,
        residentId: dto.residentId,
        plateNumber: plate,
        brand: dto.brand ?? null,
        model: dto.model ?? null,
        color: dto.color ?? null,
      },
    });
  }

  async removeVehicle(vehicleId: string) {
    const v = await this.prisma.vehicle.findUnique({ where: { id: vehicleId } });
    if (!v) throw new NotFoundException();
    await this.prisma.vehicle.delete({ where: { id: vehicleId } });
    return { success: true };
  }

  async update(id: string, dto: CreateLotDto) {
    const lot = await this.prisma.lot.findUnique({ where: { id } });
    if (!lot) throw new NotFoundException();
    return this.prisma.lot.update({
      where: { id },
      data: {
        lotNumber: dto.lotNumber,
        type: dto.type,
        surfaceM2: dto.surfaceM2 != null ? dto.surfaceM2 : undefined,
        tantiemesGeneral: dto.tantiemesGeneral != null ? dto.tantiemesGeneral : undefined,
      },
      include: { spatialUnit: true },
    });
  }

  async remove(id: string) {
    const lot = await this.prisma.lot.findUnique({ where: { id } });
    if (!lot) throw new NotFoundException();
    await this.prisma.lot.delete({ where: { id } });
    return { deleted: true };
  }
}