package org.mte.numecoeval.expositiondonneesentrees.domain.ports.input.impl;

import lombok.extern.slf4j.Slf4j;
import org.mte.numecoeval.expositiondonneesentrees.domain.exception.NotFoundException;
import org.mte.numecoeval.expositiondonneesentrees.domain.model.Volume;
import org.mte.numecoeval.expositiondonneesentrees.domain.ports.input.StatutPourCalculPort;
import org.mte.numecoeval.expositiondonneesentrees.generated.api.model.StatutCalculRest;
import org.mte.numecoeval.expositiondonneesentrees.infrastructure.helper.Constants;
import org.mte.numecoeval.expositiondonneesentrees.infrastructure.jdbc.VolumeJdbc;
import org.mte.numecoeval.expositiondonneesentrees.infrastructure.mapper.VolumeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;


@Service
@Slf4j
public class StatutPourCalculPortImpl implements StatutPourCalculPort {

    @Autowired
    private VolumeJdbc volumeJdbc;

    @Autowired
    private VolumeMapper volumeMapper;

    @Cacheable("statutDesCalculs")
    @Override
    public StatutCalculRest statutDesCalculs(String nomLot, String nomOrganisation) {

        var volumeEqPh = volumeJdbc.getVolumeBy(nomLot, nomOrganisation, Constants.TABLE_EQUIPEMENT_PHYSIQUE);
        var volumeOpNonIT = volumeJdbc.getVolumeBy(nomLot, nomOrganisation, Constants.TABLE_OPERATION_NON_IT);
        var volumeMessagerie = volumeJdbc.getVolumeBy(nomLot, nomOrganisation, Constants.TABLE_MESSAGERIE);
        return statutCalculs(volumeEqPh, volumeOpNonIT, volumeMessagerie);
    }

    /**
     * Statut des calculs en cours pour des volumes recuperes de la bdd
     *
     * @param volumeEqPh       volume des equipements physiques
     * @param volumeMessagerie volume de la messagerie
     * @return le StatutCalculRest
     */
    public StatutCalculRest statutCalculs(Volume volumeEqPh, Volume volumeOpNonIT, Volume volumeMessagerie) {
        var totalTraite = volumeEqPh.nbTraite() + volumeOpNonIT.nbTraite() + volumeMessagerie.nbTraite();
        var totalEnCours = volumeEqPh.nbEnCours() + volumeOpNonIT.nbEnCours() + volumeMessagerie.nbEnCours();

        if (totalTraite + totalEnCours == 0) {
            throw new NotFoundException();
        }

        var etat = totalTraite * 100 / (totalTraite + totalEnCours);
        var statut = StatutCalculRest.StatutEnum.EN_COURS;
        if (etat == 100) statut = StatutCalculRest.StatutEnum.TERMINE;

        return StatutCalculRest.builder()
                .statut(statut)
                .etat(etat + "%")
                .equipementPhysique(volumeMapper.toRest(volumeEqPh))
                .operationNonIT(volumeMapper.toRest(volumeOpNonIT))
                .messagerie(volumeMapper.toRest(volumeMessagerie))
                .build();
    }
}
