package io.gmss.fiscad.service.worker;

import io.gmss.fiscad.entities.decoupage.Commune;
import io.gmss.fiscad.entities.decoupage.Nationalite;
import io.gmss.fiscad.entities.infocad.metier.ActeurConcerne;
import io.gmss.fiscad.entities.infocad.metier.Enquete;
import io.gmss.fiscad.entities.infocad.metier.Tpe;
import io.gmss.fiscad.entities.infocad.parametre.*;
import io.gmss.fiscad.entities.metadata.MobileDataActeurConcerne;
import io.gmss.fiscad.entities.metadata.MobileDataPersonne;
import io.gmss.fiscad.enums.Categorie;
import io.gmss.fiscad.enums.TypeObjet;
import io.gmss.fiscad.paylaods.request.ActeurConcernePayLoad;
import io.gmss.fiscad.paylaods.request.PersonnePayLoad;
import io.gmss.fiscad.repositories.decoupage.CommuneRepository;
import io.gmss.fiscad.repositories.decoupage.NationaliteRepository;
import io.gmss.fiscad.repositories.infocad.metier.*;
import io.gmss.fiscad.repositories.infocad.parametre.*;
import io.gmss.fiscad.repositories.metadata.MobileDataActeurConcerneRepository;
import io.gmss.fiscad.repositories.metadata.MobileDataPersonneRepository;
import io.gmss.fiscad.service.LogService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
@RequiredArgsConstructor
public class PersonneAsyncWorker {
    private final TpeRepository tpeRepository;
    private final SituationMatrimonialeRepository situationMatrimonialeRepository;
    private final NationaliteRepository nationaliteRepository;
    private final PersonneRepository personneRepository;
    private final ProfessionRepository professionRepository;
    private final CommuneRepository communeRepository;
    private final MobileDataPersonneRepository mobileDataPersonneRepository;
    private final TypePersonneRepository typePersonneRepository;
    private final UploadRepository uploadRepository;
    private final MembreGroupeRepository membreGroupeRepository;
    private final PieceRepository pieceRepository;
    private final LogService logService;
    //@Async("personneExecutor")
    public void traitementAsyncPersonne(MobileDataPersonne mobileDataPersonne) {
        PersonnePayLoad personnePayLoad = mobileDataPersonne.getPersonnePayLoad();
        try {
            if (personnePayLoad.getTerminalId() == null) {
                logService.logTraiementAsync(TypeObjet.PERSONNE, "Problème de terminal", "terminal non fourni : ", mobileDataPersonne.getId());
                return;
            } else {
                Optional<Tpe> optionalTpe = tpeRepository.findById(personnePayLoad.getTerminalId());
                if (optionalTpe.isEmpty()) {
                    logService.logTraiementAsync(TypeObjet.PERSONNE, "Problème de terminal", "terminal inexistant : ", mobileDataPersonne.getId());
                    return;
                }
            }
            Personne personne = new Personne();
            Optional<Personne> optionalPersonne = personneRepository.findByMobileDataId(mobileDataPersonne.getId());
            if (optionalPersonne.isPresent()) {
                personne = optionalPersonne.get();
                deleteFromPersonne(personne.getId());
            } else {
                optionalPersonne = personneRepository.findFirstByExternalKeyAndTerminal_Id(personnePayLoad.getExternalKey(), personnePayLoad.getTerminalId());
                if (optionalPersonne.isPresent()) {
                    personne = optionalPersonne.get();
                    deleteFromPersonne(personne.getId());
                }
            }
            personne.setMobileDataId(mobileDataPersonne.getId());
            personne = getPersonneFromPersonnePayLoad(personne, personnePayLoad);
            personne = personneRepository.save(personne);
            personnePayLoad.setIdBackend(personne.getId());
            mobileDataPersonne.setTraiter(true);
            mobileDataPersonneRepository.save(mobileDataPersonne);
        } catch (Exception e) {
            logService.logTraiementAsync(TypeObjet.PERSONNE, "Problème de terminal", e.getMessage(), mobileDataPersonne.getId());
        }
    }

    private Personne getPersonneFromPersonnePayLoad(Personne personne, PersonnePayLoad personnePayLoad) {
        if (personnePayLoad.getCommuneId() != null) {
            Optional<Commune> optionalCommune = communeRepository.findById(personnePayLoad.getCommuneId());
            personne.setCommune(optionalCommune.orElse(null));
        }
        if (personnePayLoad.getNationaliteId() != null) {
            Optional<Nationalite> optionalNationalite = nationaliteRepository.findById(personnePayLoad.getNationaliteId());
            personne.setNationalite(optionalNationalite.orElse(null));
        }
        if (personnePayLoad.getProfessionId() != null) {
            Optional<Profession> optionalProfession = professionRepository.findById(personnePayLoad.getProfessionId());
            personne.setProfession(optionalProfession.orElse(null));
        }
        if (personnePayLoad.getTypePersonneId() != null) {
            Optional<TypePersonne> optionalTypePersonne = typePersonneRepository.findById(personnePayLoad.getTypePersonneId());
            personne.setTypePersonne(optionalTypePersonne.orElse(null));
        } else {
            Optional<TypePersonne> optionalTypePersonne = typePersonneRepository.findFirstByCategorie(Categorie.PERSONNE_PHYSIQUE);
            personne.setTypePersonne(optionalTypePersonne.orElse(null));

        }
        if (personnePayLoad.getSituationMatrimonialeId() != null) {
            Optional<SituationMatrimoniale> optionalSituationMatrimoniale = situationMatrimonialeRepository.findById(personnePayLoad.getSituationMatrimonialeId());
            personne.setSituationMatrimoniale(optionalSituationMatrimoniale.orElse(null));
        }
        if (personnePayLoad.getTerminalId() != null) {
            Optional<Tpe> optionalTpe = tpeRepository.findById(personnePayLoad.getTerminalId());
            personne.setTerminal(optionalTpe.orElse(null));
        }

        personne.setCategorie(personnePayLoad.getCategorie());
        personne.setAdresse(personnePayLoad.getAdresse());
        personne.setIfu(personnePayLoad.getIfu());
        personne.setDateNaissanceOuConsti(personnePayLoad.getDateNaissanceOuConsti());
        personne.setLieuNaissance(personnePayLoad.getLieuNaissance());
        personne.setNomOuSigle(personnePayLoad.getNomOuSigle());
        personne.setNpi(personnePayLoad.getNpi());
        personne.setNumRavip(personnePayLoad.getNumRavip());
        personne.setPrenomOuRaisonSociale(personnePayLoad.getPrenomOuRaisonSociale());
        personne.setTel1(personnePayLoad.getTel1());
        personne.setTel2(personnePayLoad.getTel2());
        personne.setExternalKey(personnePayLoad.getExternalKey());

        personne.setHaveRepresentant(personnePayLoad.getHaveRepresentant());
        personne.setRavipQuestion(personnePayLoad.getRavipQuestion());
        personne.setAge(personnePayLoad.getAge());
        personne.setNomJeuneFille(personnePayLoad.getNomJeuneFille());
        personne.setNomMere(personnePayLoad.getNomMere());
        personne.setPrenomMere(personnePayLoad.getPrenomMere());
        personne.setIndicatifTel1(personnePayLoad.getIndicatifTel1());
        personne.setIndicatifTel2(personnePayLoad.getIndicatifTel2());
        personne.setSexe(personnePayLoad.getSexe());
        personne.setMustHaveRepresentant(personnePayLoad.getMustHaveRepresentant());
        personne.setFilePath(personnePayLoad.getFilePath());
        personne.setObservation(personnePayLoad.getObservation());
        return personne;
    }
    private void deleteFromPersonne(Long idBackend) {
        uploadRepository.deleteUploadByMembreGroupe_PersonneRepresantee_Id(idBackend);
        uploadRepository.deleteUploadByPiece_Personne_Id(idBackend);
        uploadRepository.deleteUploadByPersonne_Id(idBackend);
        membreGroupeRepository.deleteMembreGroupeByPersonneRepresantante_Id(idBackend);
        pieceRepository.deletePieceByPersonne_Id(idBackend);
    }

}
