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.metadata.MobileDataEnquete;
import io.gmss.fiscad.entities.metadata.MobileDataUniteLogement;
import io.gmss.fiscad.entities.rfu.metier.Batiment;
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.UniteLogementPaylaod;
import io.gmss.fiscad.repositories.infocad.metier.*;
import io.gmss.fiscad.repositories.infocad.parametre.BlocRepository;
import io.gmss.fiscad.repositories.metadata.MobileDataEnqueteRepository;
import io.gmss.fiscad.repositories.metadata.MobileDataUniteLogementRepository;
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 UniteLogementAsyncWorker {
    private final TpeRepository tpeRepository;
    private final MobileDataUniteLogementRepository mobileDataUniteLogementRepository;
    private final EnqueteRepository enqueteRepository;
    private final EnqueteUniteLogementRepository enqueteUniteLogementRepository;
    private final EnqueteBatimentRepository enqueteBatimentRepository;
    private final UserRepository userRepository;
    private final ZoneRfuRepository zoneRfuRepository;
    private final UploadRepository uploadRepository;
    private final PieceRepository pieceRepository;
    private final BlocRepository blocRepository;
    private final MobileDataEnqueteRepository mobileDataEnqueteRepository;
    private final ActeurConcerneRepository acteurConcerneRepository;
    private final CaracteristiqueParcelleRepository caracteristiqueParcelleRepository;
    private final CaracteristiqueBatimentRepository caracteristiqueBatimentRepository;
    private final CaracteristiqueUniteLogementRepository caracteristiqueUniteLogementRepository;
    private final UniteLogementRepository uniteLogementRepository;
    private final BatimentRepository batimentRepository;
    private final LogService logService;
    //@Async("uniteLogementExecutor")
    public void traitementAsyncUniteLogement(MobileDataUniteLogement mobileDataUniteLogement) {
        UniteLogementPaylaod uniteLogementPaylaod = mobileDataUniteLogement.getUniteLogementPaylaod();

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

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

            UniteLogement uniteLogement = new UniteLogement();
            Optional<UniteLogement> optionalUniteLogement= Optional.empty();
            optionalUniteLogement = uniteLogementRepository.findByMobileDataId(mobileDataUniteLogement.getId());
            if (optionalUniteLogement.isPresent()) {
                uniteLogement = optionalUniteLogement.get();
            }else {
                optionalUniteLogement = uniteLogementRepository.findFirstByExternalKeyAndTerminal_Id(uniteLogementPaylaod.getExternalKey(),uniteLogementPaylaod.getTerminalId());
                if (optionalUniteLogement.isPresent()) {
                    uniteLogement = optionalUniteLogement.get();
                }
            }
            uniteLogement.setMobileDataId(mobileDataUniteLogement.getId());
            uniteLogement = getUniteLogementFromUniteLogementPayLoad(uniteLogement, uniteLogementPaylaod);
            uniteLogementRepository.save(uniteLogement);
            mobileDataUniteLogement.setTraiter(true);
            mobileDataUniteLogementRepository.save(mobileDataUniteLogement);
        } catch (Exception e) {
            logService.logTraiementAsync(TypeObjet.UNITELOGEMENT, "Problème de inattendu", e.getMessage(), mobileDataUniteLogement.getId());
        }
    }


    private UniteLogement getUniteLogementFromUniteLogementPayLoad(UniteLogement uniteLogement, UniteLogementPaylaod uniteLogementPaylaod) {

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

        if (uniteLogementPaylaod.getTerminalId() != null) {
            Optional<Tpe> optionalTpe = tpeRepository.findById(uniteLogementPaylaod.getTerminalId());
            uniteLogement.setTerminal(optionalTpe.orElse(null));
        }
        if (uniteLogementPaylaod.getTerminalId() != null && uniteLogementPaylaod.getEnqueteId() != null) {
            Optional<Enquete> optionalEnquete = enqueteRepository.findFirstByExternalKeyAndTerminal_Id(uniteLogementPaylaod.getEnqueteId(), uniteLogementPaylaod.getTerminalId());
            if (optionalEnquete.isPresent()) {
                uniteLogement.setEnqueteId(optionalEnquete.get().getId());
            }
        }
        uniteLogement.setEnqueteExternalKey(uniteLogementPaylaod.getEnqueteId());
        uniteLogement.setNul(uniteLogementPaylaod.getNul());
        uniteLogement.setNumeroEtage(uniteLogementPaylaod.getNumeroEtage());
        uniteLogement.setCode(uniteLogementPaylaod.getCode());
        uniteLogement.setExternalKey(uniteLogementPaylaod.getExternalKey());
        uniteLogement.setBatimentExternalKey(uniteLogementPaylaod.getBatimentId());
        return uniteLogement;
    }
}
