package org.mte.numecoeval.calculs.infrastructure.service.calcul;

import lombok.AllArgsConstructor;
import org.mte.numecoeval.calculs.domain.data.demande.DemandeCalculImpactReseau;
import org.mte.numecoeval.calculs.domain.data.indicateurs.ImpactReseau;
import org.mte.numecoeval.calculs.domain.model.CalculEquipementPhysique;
import org.mte.numecoeval.calculs.domain.port.input.service.CalculImpactReseauService;
import org.mte.numecoeval.calculs.infrastructure.mapper.EntreesMapper;
import org.mte.numecoeval.calculs.infrastructure.mapper.ReferentielMapper;
import org.mte.numecoeval.calculs.referentiels.generated.api.model.CritereDTO;
import org.mte.numecoeval.calculs.referentiels.generated.api.model.EtapeDTO;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@AllArgsConstructor
public class CalculReseauService {

    EntreesMapper entreesMapper;
    ReferentielMapper referentielMapper;

    CalculImpactReseauService calculImpactReseauService;

    /**
     * Calcule les impacts réseau d'un équipement physique
     * Returne la liste d'impacts
     *
     * @param calculEquipementPhysique l'equipement physique
     * @return la liste d'impacts
     */
    public List<ImpactReseau> calculImpactReseau(CalculEquipementPhysique calculEquipementPhysique) {

        List<ImpactReseau> impactReseauList = new ArrayList<>();

        if (calculEquipementPhysique == null ||
                calculEquipementPhysique.getEquipementPhysique() == null ||
                calculEquipementPhysique.getEquipementPhysique().getGoTelecharge() == null) return impactReseauList;

        LocalDateTime dateCalcul = LocalDateTime.now();

        for (EtapeDTO etape : calculEquipementPhysique.getEtapes()) {
            for (CritereDTO critere : calculEquipementPhysique.getCriteres()) {
                impactReseauList.add(calculImpactReseauService.calculerImpactReseau(DemandeCalculImpactReseau.builder()
                        .dateCalcul(dateCalcul)
                        .equipementPhysique(entreesMapper.toDomain(calculEquipementPhysique.getEquipementPhysique()))
                        .etape(referentielMapper.toEtape(etape))
                        .critere(referentielMapper.toCritere(critere))
                        .impactsReseau(referentielMapper.toListImpactReseau(calculEquipementPhysique.getImpactsReseau()))
                        .build()));
            }
        }

        return impactReseauList;
    }
}