package org.mte.numecoeval.referentiel.infrastructure.restapi.controller.impactreseau;

import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.mte.numecoeval.referentiel.domain.exception.ReferentielException;
import org.mte.numecoeval.referentiel.domain.model.ImpactReseau;
import org.mte.numecoeval.referentiel.domain.ports.input.impl.ImportImpactReseauPortImpl;
import org.mte.numecoeval.referentiel.infrastructure.adapter.export.ImpactReseauCsvExportService;
import org.mte.numecoeval.referentiel.infrastructure.restapi.controller.BaseExportReferentiel;
import org.mte.numecoeval.referentiel.infrastructure.restapi.dto.ImpactReseauDTO;
import org.mte.numecoeval.referentiel.infrastructure.restapi.dto.RapportImportDTO;
import org.mte.numecoeval.referentiel.infrastructure.restapi.dto.id.ImpactReseauIdDTO;
import org.mte.numecoeval.referentiel.infrastructure.restapi.facade.ImpactReseauFacade;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.server.ResponseStatusException;

import java.io.IOException;
import java.util.Objects;

@RestController
@Slf4j
@AllArgsConstructor
public class ReferentielImpactReseauRestApiImpl implements BaseExportReferentiel<ImpactReseau>, ReferentielImpactReseauRestApi, ReferentielAdministrationImpactReseauRestApi {
    private ImpactReseauFacade referentielFacade;

    private ImpactReseauCsvExportService csvExportService;


    @SneakyThrows
    @Override
    public ImpactReseauDTO get(String refReseau, String critere, String etapeacv) {
        ImpactReseauIdDTO idImpactReseauDTO = ImpactReseauIdDTO.builder()
                .critere(critere)
                .etapeACV(etapeacv)
                .refReseau(refReseau).build();
        return referentielFacade.get(idImpactReseauDTO);
    }


    @Override
    public ResponseEntity<ImpactReseauDTO> add(ImpactReseauDTO impactReseauDTO) throws ReferentielException {
        if (Objects.isNull(impactReseauDTO)) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Le corps de la requête ne peut être null");
        }
        if (StringUtils.isBlank(impactReseauDTO.getSource())) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "La source est obligatoire");
        }
        return ResponseEntity.ok().body(referentielFacade.addOrUpdate(impactReseauDTO));
    }

    @Override
    @PutMapping(path = "/referentiel/impactreseaux", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<ImpactReseauDTO> update(ImpactReseauDTO impactReseauDTO) throws ReferentielException {
        if (Objects.isNull(impactReseauDTO)) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Le corps de la requête ne peut être null");
        }
        if (StringUtils.isBlank(impactReseauDTO.getSource())) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "La source est obligatoire");
        }
        return ResponseEntity.ok().body(referentielFacade.addOrUpdate(impactReseauDTO));
    }

    @Override
    @PostMapping(path = "/referentiel/impactreseaux/csv", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public RapportImportDTO importCSV(MultipartFile fichier) throws IOException, ReferentielException {
        if (fichier == null || fichier.isEmpty()) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Le fichier n'existe pas ou alors il est vide");
        }
        var rapportImport = new ImportImpactReseauPortImpl().importCSV(fichier.getInputStream());
        referentielFacade.purgeAndAddAll(rapportImport.getObjects());

        return new RapportImportDTO(
                fichier.getOriginalFilename(),
                rapportImport.getErreurs(),
                rapportImport.getNbrLignesImportees()
        );
    }

    @Override
    public void exportCSV(HttpServletResponse servletResponse) throws IOException {
        exportCSV(servletResponse, csvExportService, "impactReseaux");
    }

}
