package io.gmss.fiscad.service.worker;

import io.gmss.fiscad.entities.infocad.metier.Enquete;
import io.gmss.fiscad.entities.infocad.metier.Parcelle;
import io.gmss.fiscad.entities.infocad.metier.Tpe;
import io.gmss.fiscad.entities.infocad.parametre.Bloc;
import io.gmss.fiscad.entities.infocad.parametre.Personne;
import io.gmss.fiscad.entities.metadata.MobileDataEnquete;
import io.gmss.fiscad.entities.metadata.MobileDataEnqueteUniteLogement;
import io.gmss.fiscad.entities.rfu.metier.EnqueteUniteLogement;
import io.gmss.fiscad.entities.rfu.metier.UniteLogement;
import io.gmss.fiscad.entities.rfu.parametre.ZoneRfu;
import io.gmss.fiscad.entities.user.User;
import io.gmss.fiscad.enums.TypeObjet;
import io.gmss.fiscad.paylaods.request.EnquetePayLoad;
import io.gmss.fiscad.paylaods.request.EnqueteUniteLogementPayload;
import io.gmss.fiscad.repositories.infocad.metier.*;
import io.gmss.fiscad.repositories.infocad.parametre.BlocRepository;
import io.gmss.fiscad.repositories.infocad.parametre.PersonneRepository;
import io.gmss.fiscad.repositories.metadata.MobileDataEnqueteRepository;
import io.gmss.fiscad.repositories.metadata.MobileDataEnqueteUniteLogementRepository;
import io.gmss.fiscad.repositories.rfu.metier.*;
import io.gmss.fiscad.repositories.rfu.parametre.ZoneRfuRepository;
import io.gmss.fiscad.repositories.user.UserRepository;
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 EnqueteUniteLogementAsyncWorker {
    private final TpeRepository tpeRepository;
    private final MobileDataEnqueteUniteLogementRepository mobileDataEnqueteUniteLogementRepository;
    private final EnqueteRepository enqueteRepository;
    private final EnqueteUniteLogementRepository enqueteUniteLogementRepository;
    private final PersonneRepository personneRepository;
    private final UserRepository userRepository;
    private final UniteLogementRepository uniteLogementRepository;
    private final LogService logService;
    //@Async("enqueteUniteLogementExecutor")
    public void traitementAsyncEnqueteUniteLogement(MobileDataEnqueteUniteLogement mobileDataEnqueteUniteLogement) {
        EnqueteUniteLogementPayload enqueteUniteLogementPayload = mobileDataEnqueteUniteLogement.getEnqueteUniteLogementPayload();

        try {
            if (enqueteUniteLogementPayload.getTerminalId() == null) {
                logService.logTraiementAsync(TypeObjet.ENQUETEUNITELOGEMENT, "Problème de terminal", "terminal non fourni : ", mobileDataEnqueteUniteLogement.getId());
                return;
            } else {
                Optional<Tpe> optionalTpe = tpeRepository.findById(enqueteUniteLogementPayload.getTerminalId());
                if (optionalTpe.isEmpty()) {
                    logService.logTraiementAsync(TypeObjet.ENQUETEUNITELOGEMENT, "Problème de terminal", "terminal inexistant : ", mobileDataEnqueteUniteLogement.getId());
                    return;
                }
            }

            if (enqueteUniteLogementPayload.getEnqueteId() == null) {
                logService.logTraiementAsync(TypeObjet.ENQUETEUNITELOGEMENT, "Problème de enquete", "enquete non fourni : ", mobileDataEnqueteUniteLogement.getId());
                return;
            } else {
                Optional<Enquete> optionalEnquete = enqueteRepository.findFirstByExternalKeyAndTerminal_Id(enqueteUniteLogementPayload.getEnqueteId(), enqueteUniteLogementPayload.getTerminalId());
                if (optionalEnquete.isEmpty()) {
                    logService.logTraiementAsync(TypeObjet.ENQUETEUNITELOGEMENT, "Problème de batiment", "L'enquete précisée n'existe pas : ", mobileDataEnqueteUniteLogement.getId());
                    return;
                }
            }


            if (enqueteUniteLogementPayload.getUniteLogementId() == null) {
                logService.logTraiementAsync(TypeObjet.ENQUETEUNITELOGEMENT, "Problème de Unite logement", "batiment non fourni : ", mobileDataEnqueteUniteLogement.getId());
                return;
            } else {
                Optional<UniteLogement> optionalUniteLogement = uniteLogementRepository.findFirstByExternalKeyAndTerminal_Id(enqueteUniteLogementPayload.getUniteLogementId(), enqueteUniteLogementPayload.getTerminalId());
                if (optionalUniteLogement.isEmpty()) {
                    logService.logTraiementAsync(TypeObjet.ENQUETEUNITELOGEMENT, "Problème de Unite de logement", "Le batiment précisée n'existe pas : ", mobileDataEnqueteUniteLogement.getId());
                    return;
                }
            }

            EnqueteUniteLogement enqueteUniteLogement = new EnqueteUniteLogement();
            Optional<EnqueteUniteLogement> optionalEnqueteUniteLogement= Optional.empty();
            optionalEnqueteUniteLogement = enqueteUniteLogementRepository.findByMobileDataId(mobileDataEnqueteUniteLogement.getId());
            if (optionalEnqueteUniteLogement.isPresent()) {
                enqueteUniteLogement = optionalEnqueteUniteLogement.get();
            }else {
                optionalEnqueteUniteLogement = enqueteUniteLogementRepository.findFirstByExternalKeyAndTerminal_Id(enqueteUniteLogementPayload.getUniteLogementId(),enqueteUniteLogementPayload.getTerminalId());
                if (optionalEnqueteUniteLogement.isPresent()) {
                    enqueteUniteLogement = optionalEnqueteUniteLogement.get();
                }
            }
            enqueteUniteLogement.setMobileDataId(mobileDataEnqueteUniteLogement.getId());
            enqueteUniteLogement = getEnqueteUniteLogementFromEnqueteUniteLogementPayLoad(enqueteUniteLogement, enqueteUniteLogementPayload);
            enqueteUniteLogementRepository.save(enqueteUniteLogement);
            mobileDataEnqueteUniteLogement.setTraiter(true);
            mobileDataEnqueteUniteLogementRepository.save(mobileDataEnqueteUniteLogement);
        } catch (Exception e) {
            logService.logTraiementAsync(TypeObjet.ENQUETEUNITELOGEMENT, "Problème de inattendu", e.getMessage(), mobileDataEnqueteUniteLogement.getId());
        }
    }


    private EnqueteUniteLogement getEnqueteUniteLogementFromEnqueteUniteLogementPayLoad(EnqueteUniteLogement enqueteUniteLogement, EnqueteUniteLogementPayload enqueteUniteLogementPayload) {

        if (enqueteUniteLogementPayload.getPersonneId() != null) {
            Optional<Personne> optionalPersonne = personneRepository.findFirstByExternalKeyAndTerminal_Id(enqueteUniteLogementPayload.getPersonneId(), enqueteUniteLogementPayload.getTerminalId());
            enqueteUniteLogement.setPersonne(optionalPersonne.orElse(null));
        }

        if (enqueteUniteLogementPayload.getUniteLogementId() != null) {
            Optional<UniteLogement> optionalUniteLogement = uniteLogementRepository.findFirstByExternalKeyAndTerminal_Id(enqueteUniteLogementPayload.getUniteLogementId(), enqueteUniteLogementPayload.getTerminalId());
            enqueteUniteLogement.setUniteLogement(optionalUniteLogement.orElse(null));
        }

        if (enqueteUniteLogementPayload.getEnqueteId() != null) {
            Optional<Enquete> optionalEnquete = enqueteRepository.findFirstByExternalKeyAndTerminal_Id(enqueteUniteLogementPayload.getEnqueteId(), enqueteUniteLogementPayload.getTerminalId());
            enqueteUniteLogement.setEnquete(optionalEnquete.orElse(null));
        }
        if (enqueteUniteLogementPayload.getTerminalId() != null) {
            Optional<Tpe> optionalTpe = tpeRepository.findById(enqueteUniteLogementPayload.getTerminalId());
            enqueteUniteLogement.setTerminal(optionalTpe.orElse(null));
        }

        if (enqueteUniteLogementPayload.getUserId() != null) {
            Optional<User> optionalUser = userRepository.findById(enqueteUniteLogementPayload.getUserId());
            enqueteUniteLogement.setUser(optionalUser.orElse(null));
        }
        enqueteUniteLogement.setEnqueteExternalKey(enqueteUniteLogementPayload.getEnqueteId());
        enqueteUniteLogement.setSurface(enqueteUniteLogementPayload.getSurface());
        enqueteUniteLogement.setNbrePiece(enqueteUniteLogementPayload.getNbrePiece());
        enqueteUniteLogement.setNbreHabitant(enqueteUniteLogementPayload.getNbreHabitant());
        enqueteUniteLogement.setNbreMenage(enqueteUniteLogementPayload.getNbreMenage());
        enqueteUniteLogement.setEnLocation(enqueteUniteLogementPayload.isEnLocation());
        enqueteUniteLogement.setMontantMensuelLoyer(enqueteUniteLogementPayload.getMontantMensuelLoyer());
        enqueteUniteLogement.setNbreMoisEnLocation(enqueteUniteLogementPayload.getNbreMoisEnLocation());
        enqueteUniteLogement.setMontantLocatifAnnuelDeclare(enqueteUniteLogementPayload.getMontantLocatifAnnuelDeclare());
        enqueteUniteLogement.setSurfaceLouee(enqueteUniteLogementPayload.getSurfaceLouee());
        enqueteUniteLogement.setSbee(enqueteUniteLogementPayload.isSbee());
        enqueteUniteLogement.setSoneb(enqueteUniteLogementPayload.isSoneb());
        enqueteUniteLogement.setNumCompteurSbee(enqueteUniteLogementPayload.getNumCompteurSbee());
        enqueteUniteLogement.setNumCompteurSoneb(enqueteUniteLogementPayload.getNumCompteurSoneb());
        enqueteUniteLogement.setDateDebutExcemption(enqueteUniteLogementPayload.getDateDebutExcemption());
        enqueteUniteLogement.setDateFinExcemption(enqueteUniteLogementPayload.getDateFinExcemption());
        enqueteUniteLogement.setExternalKey(enqueteUniteLogementPayload.getExternalKey());
        enqueteUniteLogement.setPersonneExternalKey(enqueteUniteLogementPayload.getPersonneId());
        enqueteUniteLogement.setUniteLogementExternalKey(enqueteUniteLogementPayload.getUniteLogementId());

        return enqueteUniteLogement;
    }
}
