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.MobileDataEnqueteBatiment;
import io.gmss.fiscad.entities.rfu.metier.Batiment;
import io.gmss.fiscad.entities.rfu.metier.EnqueteBatiment;
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.EnqueteBatimentPayload;
import io.gmss.fiscad.paylaods.request.EnquetePayLoad;
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.MobileDataEnqueteBatimentRepository;
import io.gmss.fiscad.repositories.metadata.MobileDataEnqueteRepository;
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 EnqueteBatimentAsyncWorker {
    private final TpeRepository tpeRepository;
    private final MobileDataEnqueteBatimentRepository mobileDataEnqueteBatimentRepository;
    private final EnqueteRepository enqueteRepository;
    private final EnqueteBatimentRepository enqueteBatimentRepository;
    private final UserRepository userRepository;
    private final PersonneRepository personneRepository;
    private final BatimentRepository batimentRepository;
    private final LogService logService;
    //@Async("enqueteBatimentExecutor")
    public void traitementAsyncEnqueteBatiment(MobileDataEnqueteBatiment mobileDataEnqueteBatiment) {
        EnqueteBatimentPayload enqueteBatimentPayload = mobileDataEnqueteBatiment.getEnqueteBatimentPayload();

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

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


            if (enqueteBatimentPayload.getBatimentId() == null) {
                logService.logTraiementAsync(TypeObjet.ENQUETEBATIMENT, "Problème de batiment", "batiment non fourni : ", mobileDataEnqueteBatiment.getId());
                return;
            } else {
                Optional<Batiment> optionalBatiment = batimentRepository.findFirstByExternalKeyAndTerminal_Id(enqueteBatimentPayload.getBatimentId(), enqueteBatimentPayload.getTerminalId());
                if (optionalBatiment.isEmpty()) {
                    logService.logTraiementAsync(TypeObjet.ENQUETEBATIMENT, "Problème de batiment", "Le batiment précisée n'existe pas : ", mobileDataEnqueteBatiment.getId());
                    return;
                }
            }

            EnqueteBatiment enqueteBatiment = new EnqueteBatiment();
            Optional<EnqueteBatiment> optionalEnqueteBatiment= Optional.empty();
            optionalEnqueteBatiment = enqueteBatimentRepository.findByMobileDataId(mobileDataEnqueteBatiment.getId());
            if (optionalEnqueteBatiment.isPresent()) {
                enqueteBatiment = optionalEnqueteBatiment.get();
            }else {
                optionalEnqueteBatiment = enqueteBatimentRepository.findFirstByExternalKeyAndTerminal_Id(enqueteBatimentPayload.getExternalKey(),enqueteBatimentPayload.getTerminalId());
                if (optionalEnqueteBatiment.isPresent()) {
                    enqueteBatiment = optionalEnqueteBatiment.get();
                }
            }
            enqueteBatiment.setMobileDataId(mobileDataEnqueteBatiment.getId());
            enqueteBatiment = getEnqueteBatimentFromEnqueteBatimentPayLoad(enqueteBatiment, enqueteBatimentPayload);
            enqueteBatimentRepository.save(enqueteBatiment);
            mobileDataEnqueteBatiment.setTraiter(true);
            mobileDataEnqueteBatimentRepository.save(mobileDataEnqueteBatiment);
        } catch (Exception e) {
            logService.logTraiementAsync(TypeObjet.ENQUETEBATIMENT, "Problème de inattendu", e.getMessage(), mobileDataEnqueteBatiment.getId());
        }
    }


    private EnqueteBatiment getEnqueteBatimentFromEnqueteBatimentPayLoad(EnqueteBatiment enqueteBatiment, EnqueteBatimentPayload enqueteBatimentPayload) {
        enqueteBatiment.setSurfaceAuSol(enqueteBatimentPayload.getSurfaceAuSol());
        enqueteBatiment.setAutreMenuisierie(enqueteBatimentPayload.getAutreMenuisierie());
        enqueteBatiment.setAutreMur(enqueteBatimentPayload.getAutreMur());
        enqueteBatiment.setSbee(enqueteBatimentPayload.isSbee());
        enqueteBatiment.setNumCompteurSbee(enqueteBatimentPayload.getNumCompteurSbee());
        enqueteBatiment.setSoneb(enqueteBatimentPayload.isSoneb());
        enqueteBatiment.setNumCompteurSoneb(enqueteBatimentPayload.getNumCompteurSoneb());
        enqueteBatiment.setNbreLotUnite(enqueteBatimentPayload.getNbreLotUnite());
        enqueteBatiment.setNbreUniteLocation(enqueteBatimentPayload.getNbreUniteLocation());
        enqueteBatiment.setSurfaceLouee(enqueteBatimentPayload.getSurfaceLouee());
        enqueteBatiment.setNbreMenage(enqueteBatimentPayload.getNbreMenage());
        enqueteBatiment.setNbreHabitant(enqueteBatimentPayload.getNbreHabitant());
        enqueteBatiment.setValeurMensuelleLocation(enqueteBatimentPayload.getValeurMensuelleLocation());
        enqueteBatiment.setNbreMoisLocation(enqueteBatimentPayload.getNbreMoisLocation());
        enqueteBatiment.setAutreCaracteristiquePhysique(enqueteBatimentPayload.getAutreCaracteristiquePhysique());
        enqueteBatiment.setDateDebutExcemption(enqueteBatimentPayload.getDateDebutExcemption());
        enqueteBatiment.setDateFinExcemption(enqueteBatimentPayload.getDateFinExcemption());
        enqueteBatiment.setExternalKey(enqueteBatimentPayload.getExternalKey());
        enqueteBatiment.setEnqueteExternalKey(enqueteBatimentPayload.getEnqueteId());
        enqueteBatiment.setPersonneExternalKey(enqueteBatimentPayload.getPersonneId());
        enqueteBatiment.setBatimentExternalKey(enqueteBatimentPayload.getBatimentId());

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

        if (enqueteBatimentPayload.getBatimentId() != null) {
            Optional<Batiment> optionalBatiment = batimentRepository.findFirstByExternalKeyAndTerminal_Id(enqueteBatimentPayload.getBatimentId(), enqueteBatimentPayload.getTerminalId());
            enqueteBatiment.setBatiment(optionalBatiment.orElse(null));
        }

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

        if (enqueteBatimentPayload.getUserId() != null) {
            Optional<User> optionalUser = userRepository.findById(enqueteBatimentPayload.getUserId());
            enqueteBatiment.setUser(optionalUser.orElse(null));
        }

        return enqueteBatiment;
    }
}
