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.Enquete;
import io.gmss.fiscad.entities.infocad.metier.MembreGroupe;
import io.gmss.fiscad.entities.infocad.metier.Tpe;
import io.gmss.fiscad.entities.infocad.parametre.*;
import io.gmss.fiscad.entities.metadata.MobileDataMembreGroupe;
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.MembreGroupePayLoad;
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.MobileDataMembreGroupeRepository;
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 MembreGroupeAsyncWorker {
    private final TpeRepository tpeRepository;
    private final PersonneRepository personneRepository;
    private final EnqueteRepository enqueteRepository;
    private final TypeRepresentationRepository typeRepresentationRepository;
    private final MobileDataMembreGroupeRepository mobileDataMembreGroupeRepository;
    private final MembreGroupeRepository membreGroupeRepository;
    private final PositionRepresentationRepository positionRepresentationRepository;
    private final LogService logService;
    //@Async("membreGroupeExecutor")
    public void traitementAsyncMembreGroupe(MobileDataMembreGroupe mobileDataMembreGroupe) {
        MembreGroupePayLoad membreGroupePayLoad=mobileDataMembreGroupe.getMembreGroupePayLoad();
        try {
            if (membreGroupePayLoad.getTerminalId() == null) {
                logService.logTraiementAsync(TypeObjet.MEMBREGROUPE, "Problème de terminal", "terminal non fourni : ", mobileDataMembreGroupe.getId());
                return;
            } else {
                Optional<Tpe> optionalTpe = tpeRepository.findById(membreGroupePayLoad.getTerminalId());
                if (optionalTpe.isEmpty()) {
                    logService.logTraiementAsync(TypeObjet.MEMBREGROUPE, "Problème de terminal", "terminal inexistant : ", mobileDataMembreGroupe.getId());
                    return;
                }
            }
            if (membreGroupePayLoad.getPersonneRepresentanteId() == null) {
                logService.logTraiementAsync(TypeObjet.MEMBREGROUPE, "Problème de Personne représentante", "La personne représentante n'est pas précisée : ", mobileDataMembreGroupe.getId());
                return;
            } else {
                Optional<Personne> optionalPersonne = personneRepository.findFirstByExternalKeyAndTerminal_Id(membreGroupePayLoad.getPersonneRepresentanteId(), membreGroupePayLoad.getTerminalId());
                if (optionalPersonne.isEmpty()) {
                    logService.logTraiementAsync(TypeObjet.MEMBREGROUPE, "Problème de Personne représentante", "La personne représentante n'existe pas précisée : ", mobileDataMembreGroupe.getId());
                    return;
                }
            }
            if (membreGroupePayLoad.getPersonneRepresenteeId() == null) {
                logService.logTraiementAsync(TypeObjet.MEMBREGROUPE, "Problème de Personne représentée", "La personne représentante n'est pas précisée : ", mobileDataMembreGroupe.getId());
                return;
            } else {
                Optional<Personne> optionalPersonne = personneRepository.findFirstByExternalKeyAndTerminal_Id(membreGroupePayLoad.getPersonneRepresenteeId(), membreGroupePayLoad.getTerminalId());
                if (optionalPersonne.isEmpty()) {
                    logService.logTraiementAsync(TypeObjet.MEMBREGROUPE, "Problème de Personne représentante", "La personne représentante n'existe pas : ", mobileDataMembreGroupe.getId());
                    return;
                }
            }
            MembreGroupe membreGroupe = new MembreGroupe();
            Optional<MembreGroupe> optionalMembreGroupe = membreGroupeRepository.findByMobileDataId(mobileDataMembreGroupe.getId());
            if (optionalMembreGroupe.isPresent()) {
                membreGroupe = optionalMembreGroupe.get();
            }else {
                optionalMembreGroupe = membreGroupeRepository.findFirstByExternalKeyAndTerminal_Id(membreGroupePayLoad.getExternalKey(),membreGroupePayLoad.getTerminalId());
                if (optionalMembreGroupe.isPresent()) {
                    membreGroupe=optionalMembreGroupe.get();
                }
            }
            membreGroupe.setMobileDataId(mobileDataMembreGroupe.getId());
            membreGroupe = getMembreGroupeFromMembreGroupePayLoad(membreGroupe, membreGroupePayLoad);
            membreGroupeRepository.save(membreGroupe);
            mobileDataMembreGroupe.setTraiter(true);
            mobileDataMembreGroupeRepository.save(mobileDataMembreGroupe);

        } catch (Exception e) {
            logService.logTraiementAsync(TypeObjet.MEMBREGROUPE, "Problème inattendu", e.getMessage(), mobileDataMembreGroupe.getId());

        }
    }


    private MembreGroupe getMembreGroupeFromMembreGroupePayLoad(MembreGroupe membreGroupe, MembreGroupePayLoad membreGroupePayLoad) {
        if (membreGroupePayLoad.getPersonneRepresentanteId() != null) {
            Optional<Personne> optionalRepresentant = personneRepository.findFirstByExternalKeyAndTerminal_Id(membreGroupePayLoad.getPersonneRepresentanteId(), membreGroupePayLoad.getTerminalId());
            membreGroupe.setPersonneRepresantante(optionalRepresentant.orElse(null));
        }
        if (membreGroupePayLoad.getPersonneRepresenteeId() != null) {
            Optional<Personne> optionalRepresente = personneRepository.findFirstByExternalKeyAndTerminal_Id(membreGroupePayLoad.getPersonneRepresenteeId(), membreGroupePayLoad.getTerminalId());
            membreGroupe.setPersonneRepresantee(optionalRepresente.orElse(null));
        }

        if (membreGroupePayLoad.getPositionRepresentationId() != null) {
            Optional<PositionRepresentation> optionalPositionRepresentation = positionRepresentationRepository.findById(membreGroupePayLoad.getPositionRepresentationId());
            membreGroupe.setPositionRepresentation(optionalPositionRepresentation.orElse(null));
        }
        if (membreGroupePayLoad.getTerminalId() != null) {
            Optional<Tpe> optionalTpe = tpeRepository.findById(membreGroupePayLoad.getTerminalId());
            membreGroupe.setTerminal(optionalTpe.orElse(null));
        }

        if (membreGroupePayLoad.getTypeRepresentationId() != null) {
            Optional<TypeRepresentation> optionalTypeRepresentation = typeRepresentationRepository.findById(membreGroupePayLoad.getTypeRepresentationId());
            membreGroupe.setExternalKey(membreGroupePayLoad.getExternalKey());

        }

        if (membreGroupePayLoad.getEnqueteId() != null) {
            Optional<Enquete> optionalEnquete = enqueteRepository.findFirstByExternalKeyAndTerminal_Id(membreGroupePayLoad.getEnqueteId(), membreGroupePayLoad.getTerminalId());
            membreGroupe.setExternalKey(membreGroupePayLoad.getExternalKey());
            membreGroupe.setEnqueteId(optionalEnquete.get().getId());
        }
        membreGroupe.setMax_numero_acteur_concerne_id(membreGroupePayLoad.getMax_numero_acteur_concerne_id());
        membreGroupe.setMax_numero_piece_id(membreGroupePayLoad.getMax_numero_piece_id());
        membreGroupe.setEnqueteExternalKey(membreGroupePayLoad.getEnqueteId());
        membreGroupe.setBlocId(membreGroupePayLoad.getBlocId());
        membreGroupe.setObservation(membreGroupePayLoad.getObservation());
        return membreGroupe;
    }
}
