/**
 * Fraccionamiento Service
 * Servicio para gestión de fraccionamientos/obras
 *
 * @module Construction
 */

import { Repository, FindOptionsWhere } from 'typeorm';
import { AppDataSource } from '../../../shared/database/typeorm.config';
import { Fraccionamiento, EstadoFraccionamiento } from '../entities/fraccionamiento.entity';

export interface CreateFraccionamientoDto {
  tenantId: string;
  proyectoId: string;
  codigo: string;
  nombre: string;
  descripcion?: string;
  direccion?: string;
  ubicacionGeo?: string;
  fechaInicio?: Date;
  fechaFinEstimada?: Date;
  createdById?: string;
}

export interface UpdateFraccionamientoDto {
  nombre?: string;
  descripcion?: string;
  direccion?: string;
  ubicacionGeo?: string;
  fechaInicio?: Date;
  fechaFinEstimada?: Date;
  estado?: EstadoFraccionamiento;
}

export interface FraccionamientoFilters {
  tenantId: string;
  proyectoId?: string;
  estado?: EstadoFraccionamiento;
}

export class FraccionamientoService {
  private repository: Repository<Fraccionamiento>;

  constructor() {
    this.repository = AppDataSource.getRepository(Fraccionamiento);
  }

  async findAll(filters: FraccionamientoFilters): Promise<Fraccionamiento[]> {
    const where: FindOptionsWhere<Fraccionamiento> = {
      tenantId: filters.tenantId,
    };

    if (filters.proyectoId) {
      where.proyectoId = filters.proyectoId;
    }

    if (filters.estado) {
      where.estado = filters.estado;
    }

    return this.repository.find({
      where,
      relations: ['proyecto'],
      order: { createdAt: 'DESC' },
    });
  }

  async findById(id: string, tenantId: string): Promise<Fraccionamiento | null> {
    return this.repository.findOne({
      where: { id, tenantId },
      relations: ['proyecto', 'createdBy'],
    });
  }

  async findByCodigo(codigo: string, tenantId: string): Promise<Fraccionamiento | null> {
    return this.repository.findOne({
      where: { codigo, tenantId },
    });
  }

  async findByProyecto(proyectoId: string, tenantId: string): Promise<Fraccionamiento[]> {
    return this.repository.find({
      where: { proyectoId, tenantId },
      order: { codigo: 'ASC' },
    });
  }

  async create(data: CreateFraccionamientoDto): Promise<Fraccionamiento> {
    const fraccionamiento = this.repository.create(data);
    return this.repository.save(fraccionamiento);
  }

  async update(
    id: string,
    tenantId: string,
    data: UpdateFraccionamientoDto
  ): Promise<Fraccionamiento | null> {
    const fraccionamiento = await this.findById(id, tenantId);
    if (!fraccionamiento) {
      return null;
    }

    Object.assign(fraccionamiento, data);
    return this.repository.save(fraccionamiento);
  }

  async delete(id: string, tenantId: string): Promise<boolean> {
    const result = await this.repository.delete({ id, tenantId });
    return result.affected ? result.affected > 0 : false;
  }

  async countByProyecto(proyectoId: string, tenantId: string): Promise<number> {
    return this.repository.count({
      where: { proyectoId, tenantId },
    });
  }
}
