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

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.mte.numecoeval.expositiondonneesentrees.domain.ports.input.SoumissionCalculPort;
import org.mte.numecoeval.expositiondonneesentrees.domain.ports.input.SoumissionCalculSyncPort;
import org.mte.numecoeval.expositiondonneesentrees.domain.ports.input.StatutPourCalculPort;
import org.mte.numecoeval.expositiondonneesentrees.generated.api.model.DemandeCalculRest;
import org.mte.numecoeval.expositiondonneesentrees.generated.api.model.ModeRest;
import org.mte.numecoeval.expositiondonneesentrees.generated.api.model.RapportDemandeCalculRest;
import org.mte.numecoeval.expositiondonneesentrees.generated.api.model.StatutCalculRest;
import org.mte.numecoeval.expositiondonneesentrees.generated.api.server.CalculsApi;
import org.mte.numecoeval.expositiondonneesentrees.infrastructure.mapper.CalculRestMapper;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;

@RestController
@AllArgsConstructor
@Slf4j
public class CalculController implements CalculsApi {

    CalculRestMapper calculRestMapper;

    SoumissionCalculPort soumissionCalculPort;

    SoumissionCalculSyncPort soumissionCalculSyncPort;
    StatutPourCalculPort statutPourCalculPort;

    @Override
    public ResponseEntity<StatutCalculRest> statutPourCalcul(String nomLot, String nomOrganisation) {
        var statut = statutPourCalculPort.statutDesCalculs(nomLot, nomOrganisation);
        log.info("Statut global des calculs, nomOrganisation: {}, nomLot: {}. Avancement: {}", nomOrganisation, nomLot, statut.getEtat());
        return ResponseEntity.ok(statut);
    }

    @Override
    public ResponseEntity<RapportDemandeCalculRest> soumissionPourCalcul(DemandeCalculRest demandeCalculRest, ModeRest mode) {
        log.info("Soumission de calcul pour nom_lot: {}, mode: {}", demandeCalculRest.getNomLot(), mode);
        var demandeCalcul = calculRestMapper.toDomain(demandeCalculRest);

        var soumission = ModeRest.ASYNC == mode ?
                soumissionCalculPort.soumissionCalcul(demandeCalcul) :
                soumissionCalculSyncPort.soumissionCalcul(demandeCalcul);

        return ResponseEntity.ok(calculRestMapper.toRest(soumission));
    }

    @Override
    public ResponseEntity<RapportDemandeCalculRest> rejeuCalcul(DemandeCalculRest demandeCalculRest) {
        log.info("Rejeu de calcul, nom_lot: {}", demandeCalculRest.getNomLot());
        var demandeCalcul = calculRestMapper.toDomain(demandeCalculRest);

        var soumission = soumissionCalculPort.rejeuCalcul(demandeCalcul);

        var responseBody = calculRestMapper.toRest(soumission);

        return ResponseEntity.ok(responseBody);
    }
}
