package io.gmss.fiscad.service.worker;

import io.gmss.fiscad.entities.decoupage.Quartier;
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.NatureDomaine;
import io.gmss.fiscad.entities.metadata.MobileDataEnquete;
import io.gmss.fiscad.entities.metadata.MobileDataParcelle;
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.ParcellePayLoad;
import io.gmss.fiscad.repositories.decoupage.QuartierRepository;
import io.gmss.fiscad.repositories.infocad.metier.*;
import io.gmss.fiscad.repositories.infocad.parametre.BlocRepository;
import io.gmss.fiscad.repositories.infocad.parametre.NatureDomaineRepository;
import io.gmss.fiscad.repositories.metadata.MobileDataEnqueteRepository;
import io.gmss.fiscad.repositories.metadata.MobileDataParcelleRepository;
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 ParcelleAsyncWorker {
    private final TpeRepository tpeRepository;
    private final ParcelleRepository parcelleRepository;
    private final MobileDataParcelleRepository mobileDataParcelleRepository;
    private final NatureDomaineRepository natureDomaineRepository;
    private final QuartierRepository quartierRepository;
    private final LogService logService;
    //@Async("parcelleExecutor")
    public void traitementAsyncParcelle(MobileDataParcelle mobileDataParcelle) {
        ParcellePayLoad parcellePayLoad = mobileDataParcelle.getParcellePayLoad();

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

            Parcelle parcelle = new Parcelle();
            Optional<Parcelle> optionalParcelle=Optional.empty();
            optionalParcelle = parcelleRepository.findByMobileDataId(mobileDataParcelle.getId());
            if (optionalParcelle.isPresent()) {
                parcelle = optionalParcelle.get();
            }else {
                optionalParcelle = parcelleRepository.findFirstByExternalKeyAndTerminal_Id(parcellePayLoad.getExternalKey(),parcellePayLoad.getTerminalId());
                if (optionalParcelle.isPresent()) {
                    parcelle = optionalParcelle.get();
                }
            }
            parcelle.setMobileDataId(mobileDataParcelle.getId());
            parcelle = getParcelleFromParcellePayLoad(parcelle, parcellePayLoad);
            parcelleRepository.save(parcelle);
            mobileDataParcelle.setTraiter(true);
            mobileDataParcelleRepository.save(mobileDataParcelle);
        } catch (Exception e) {
            logService.logTraiementAsync(TypeObjet.PARCELLE, "Problème de inattendu", e.getMessage(), mobileDataParcelle.getId());
        }
    }


    private Parcelle getParcelleFromParcellePayLoad(Parcelle parcelle, ParcellePayLoad parcellePayLoad) {
        if (parcellePayLoad.getNatureDomaineId() != null) {
            Optional<NatureDomaine> optionalNatureDomaine = natureDomaineRepository.findById(parcellePayLoad.getNatureDomaineId());
            parcelle.setNatureDomaine(optionalNatureDomaine.orElse(null));
        }
        if (parcellePayLoad.getQuartierId() != null) {
            Optional<Quartier> optionalQuartier = quartierRepository.findById(parcellePayLoad.getQuartierId());
            parcelle.setQuartier(optionalQuartier.orElse(null));
        }
        if (parcellePayLoad.getTerminalId() != null) {
            Optional<Tpe> optionalTpe = tpeRepository.findById(parcellePayLoad.getTerminalId());
            parcelle.setTerminal(optionalTpe.orElse(null));
        }
        parcelle.setExternalKey(parcellePayLoad.getExternalKey());
        parcelle.setNupProvisoire(parcellePayLoad.getNupProvisoire());
        parcelle.setQ(parcellePayLoad.getQ());
        parcelle.setI(parcellePayLoad.getI());
        parcelle.setP(parcellePayLoad.getP());
        parcelle.setNup(parcellePayLoad.getNup());
        parcelle.setLongitude(parcellePayLoad.getLongitude());
        parcelle.setLatitude(parcellePayLoad.getLatitude());
        parcelle.setNumTitreFoncier(parcellePayLoad.getNumTitreFoncier());
        parcelle.setTypeDomaineId(parcellePayLoad.getTypeDomaineId());
        parcelle.setNumeroProvisoire(parcellePayLoad.getNumeroProvisoire());
        parcelle.setBlocId(parcellePayLoad.getBlocId());
        parcelle.setObservation(parcellePayLoad.getObservation());
        parcelle.setSituationGeographique(parcellePayLoad.getSituationGeographique());
        parcelle.setAutreNumeroTitreFoncier(parcellePayLoad.getAutreNumeroTitreFoncier());
        return parcelle;
    }
}
