/**
 * Proyecto Service
 * Servicio para gestión de proyectos de construcción
 *
 * @module Construction
 */

import { Repository, FindOptionsWhere } from 'typeorm';
import { AppDataSource } from '../../../shared/database/typeorm.config';
import { Proyecto, EstadoProyecto } from '../entities/proyecto.entity';

export interface CreateProyectoDto {
  tenantId: string;
  codigo: string;
  nombre: string;
  descripcion?: string;
  direccion?: string;
  ciudad?: string;
  estado?: string;
  fechaInicio?: Date;
  fechaFinEstimada?: Date;
  createdById?: string;
}

export interface UpdateProyectoDto {
  nombre?: string;
  descripcion?: string;
  direccion?: string;
  ciudad?: string;
  estado?: string;
  fechaInicio?: Date;
  fechaFinEstimada?: Date;
  estadoProyecto?: EstadoProyecto;
}

export interface ProyectoFilters {
  tenantId: string;
  estadoProyecto?: EstadoProyecto;
  ciudad?: string;
}

export class ProyectoService {
  private repository: Repository<Proyecto>;

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

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

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

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

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

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

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

  async create(data: CreateProyectoDto): Promise<Proyecto> {
    const proyecto = this.repository.create(data);
    return this.repository.save(proyecto);
  }

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

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

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

  async getStatistics(tenantId: string): Promise<{
    total: number;
    activos: number;
    completados: number;
    pausados: number;
  }> {
    const proyectos = await this.repository.find({ where: { tenantId } });

    return {
      total: proyectos.length,
      activos: proyectos.filter(p => p.estadoProyecto === 'activo').length,
      completados: proyectos.filter(p => p.estadoProyecto === 'completado').length,
      pausados: proyectos.filter(p => p.estadoProyecto === 'pausado').length,
    };
  }
}
