package org.mte.numecoeval.expositiondonneesentrees.infrastructure.jdbc;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.mte.numecoeval.expositiondonneesentrees.domain.model.DemandeCalcul;
import org.mte.numecoeval.expositiondonneesentrees.domain.model.RapportDemandeCalcul;
import org.mte.numecoeval.expositiondonneesentrees.domain.ports.input.SoumissionCalculPort;
import org.mte.numecoeval.expositiondonneesentrees.generated.api.model.StatutTraitement;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static org.mte.numecoeval.expositiondonneesentrees.infrastructure.helper.Constants.*;

@Service
@Slf4j
@AllArgsConstructor
public class SoumissionCalculPortJdbcImpl implements SoumissionCalculPort {

    private static final String STATUT_TRAITEMENT_A_INGERER = StatutTraitement.A_INGERER.getValue();

    private static final String STATUT_TRAITEMENT_EN_ATTENTE = StatutTraitement.EN_ATTENTE.getValue();

    JdbcTemplate jdbcTemplate;

    @Transactional
    @Override
    public RapportDemandeCalcul soumissionCalcul(DemandeCalcul demandeCalcul) {
        validate(demandeCalcul);

        var rapport = new RapportDemandeCalcul();
        rapport.setNomLot(demandeCalcul.getNomLot());
        rapport.setDateLot(demandeCalcul.getDateLot());
        rapport.setNomOrganisation(demandeCalcul.getNomOrganisation());
        jdbcTemplate.update(getUpdateStatementForTable(TABLE_DONNEES_ENTREES), STATUT_TRAITEMENT_A_INGERER, demandeCalcul.getNomLot(), STATUT_TRAITEMENT_EN_ATTENTE);
        rapport.setNbrDataCenter(jdbcTemplate.update(getUpdateStatementForTable(TABLE_DATA_CENTER), STATUT_TRAITEMENT_A_INGERER, demandeCalcul.getNomLot(), STATUT_TRAITEMENT_EN_ATTENTE));
        rapport.setNbrEquipementPhysique(jdbcTemplate.update(getUpdateStatementForTable(TABLE_EQUIPEMENT_PHYSIQUE), STATUT_TRAITEMENT_A_INGERER, demandeCalcul.getNomLot(), STATUT_TRAITEMENT_EN_ATTENTE));
        rapport.setNbrOperationNonIT(jdbcTemplate.update(getUpdateStatementForTable(TABLE_OPERATION_NON_IT), STATUT_TRAITEMENT_A_INGERER, demandeCalcul.getNomLot(), STATUT_TRAITEMENT_EN_ATTENTE));
        rapport.setNbrMessagerie(jdbcTemplate.update(getUpdateStatementForTable(TABLE_MESSAGERIE), STATUT_TRAITEMENT_A_INGERER, demandeCalcul.getNomLot(), STATUT_TRAITEMENT_EN_ATTENTE));
        return rapport;
    }

    @Override
    public RapportDemandeCalcul rejeuCalcul(DemandeCalcul demandeCalcul) {
        validate(demandeCalcul);

        var rapport = new RapportDemandeCalcul();
        rapport.setNomLot(demandeCalcul.getNomLot());
        rapport.setDateLot(demandeCalcul.getDateLot());
        rapport.setNomOrganisation(demandeCalcul.getNomOrganisation());

        jdbcTemplate.update(getUpdateForRejeuStatementForTable(TABLE_DONNEES_ENTREES), STATUT_TRAITEMENT_A_INGERER, demandeCalcul.getNomLot());
        rapport.setNbrDataCenter(jdbcTemplate.update(getUpdateForRejeuStatementForTable(TABLE_DATA_CENTER), STATUT_TRAITEMENT_A_INGERER, demandeCalcul.getNomLot()));
        rapport.setNbrEquipementPhysique(jdbcTemplate.update(getUpdateForRejeuStatementForTable(TABLE_EQUIPEMENT_PHYSIQUE), STATUT_TRAITEMENT_A_INGERER, demandeCalcul.getNomLot()));
        rapport.setNbrOperationNonIT(jdbcTemplate.update(getUpdateForRejeuStatementForTable(TABLE_OPERATION_NON_IT), STATUT_TRAITEMENT_A_INGERER, demandeCalcul.getNomLot()));
        rapport.setNbrMessagerie(jdbcTemplate.update(getUpdateForRejeuStatementForTable(TABLE_MESSAGERIE), STATUT_TRAITEMENT_A_INGERER, demandeCalcul.getNomLot()));
        return rapport;
    }

    private String getUpdateStatementForTable(String table) {
        return "UPDATE " + table + " SET date_update = NOW(), statut_traitement = ? " +
                "WHERE nom_lot = ? and statut_traitement = ?";
    }

    private String getUpdateForRejeuStatementForTable(String table) {
        return "UPDATE " + table + " SET date_update = NOW(), statut_traitement = ? " +
                "WHERE nom_lot = ?";
    }
}
