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.MobileDataBatiment;
import io.gmss.fiscad.entities.metadata.MobileDataEnquete;
import io.gmss.fiscad.entities.rfu.metier.Batiment;
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.BatimentPaylaod;
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.metadata.MobileDataBatimentRepository;
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 BatimentAsyncWorker {
    private final TpeRepository tpeRepository;
    private final ParcelleRepository parcelleRepository;
    private final EnqueteRepository enqueteRepository;
    private final MobileDataBatimentRepository mobileDataBatimentRepository;
    private final BatimentRepository batimentRepository;
    private final LogService logService;
    //@Async("batimentExecutor")
    public void traitementAsyncBatiment(MobileDataBatiment mobileDataBatiment) {
        BatimentPaylaod batimentPaylaod = mobileDataBatiment.getBatimentPaylaod();
        try {
            if (batimentPaylaod.getTerminalId() == null) {
                logService.logTraiementAsync(TypeObjet.BATIMENT, "Problème de terminal", "terminal non fourni : ", mobileDataBatiment.getId());
                return;
            } else {
                Optional<Tpe> optionalTpe = tpeRepository.findById(batimentPaylaod.getTerminalId());
                if (optionalTpe.isEmpty()) {
                    logService.logTraiementAsync(TypeObjet.BATIMENT, "Problème de terminal", "terminal inexistant : ", mobileDataBatiment.getId());
                    return;
                }
            }

            if (batimentPaylaod.getParcelleId() == null) {
                logService.logTraiementAsync(TypeObjet.BATIMENT, "Problème de parcelle", "terminal inexistant : ", mobileDataBatiment.getId());
                return;
            } else {
                Optional<Parcelle> optionalParcelle = parcelleRepository.findFirstByExternalKeyAndTerminal_Id(batimentPaylaod.getParcelleId(), batimentPaylaod.getTerminalId());
                if (optionalParcelle.isEmpty()) {
                    logService.logTraiementAsync(TypeObjet.BATIMENT, "Problème de parcelle", "La parcelle précisée n'existe pas : ", mobileDataBatiment.getId());
                    return;
                }
            }

            Batiment batiment = new Batiment();
            Optional<Batiment> optionalBatiment= Optional.empty();
            optionalBatiment = batimentRepository.findByMobileDataId(mobileDataBatiment.getId());
            if (optionalBatiment.isPresent()) {
                batiment = optionalBatiment.get();
            }else {
                optionalBatiment = batimentRepository.findFirstByExternalKeyAndTerminal_Id(batimentPaylaod.getExternalKey(),batimentPaylaod.getTerminalId());
                if (optionalBatiment.isPresent()) {
                    batiment = optionalBatiment.get();
                }
            }
            batiment.setMobileDataId(mobileDataBatiment.getId());
            batiment = getBatimentFromBatimentPayLoad(batiment, batimentPaylaod);
            batimentRepository.save(batiment);
            mobileDataBatiment.setTraiter(true);
            mobileDataBatimentRepository.save(mobileDataBatiment);
        } catch (Exception e) {
            logService.logTraiementAsync(TypeObjet.BATIMENT, "Problème de inattendu", e.getMessage(), mobileDataBatiment.getId());
        }
    }

    private Batiment getBatimentFromBatimentPayLoad(Batiment batiment, BatimentPaylaod batimentPaylaod) {

        if (batimentPaylaod.getParcelleId() != null) {
            Optional<Parcelle> optionalParcelle = parcelleRepository.findFirstByExternalKeyAndTerminal_Id(batimentPaylaod.getParcelleId(), batimentPaylaod.getTerminalId());
            batiment.setParcelle(optionalParcelle.orElse(null));
        }

        if (batimentPaylaod.getTerminalId() != null) {
            Optional<Tpe> optionalTpe = tpeRepository.findById(batimentPaylaod.getTerminalId());
            batiment.setTerminal(optionalTpe.orElse(null));
        }
        if (batimentPaylaod.getTerminalId() != null && batimentPaylaod.getEnqueteId() != null) {
            Optional<Enquete> optionalEnquete = enqueteRepository.findFirstByExternalKeyAndTerminal_Id(batimentPaylaod.getEnqueteId(), batimentPaylaod.getTerminalId());
            if (optionalEnquete.isPresent()) {
                batiment.setEnqueteId(optionalEnquete.get().getId());
            }
        }
        batiment.setParcelleExternalKey(batimentPaylaod.getParcelleId());
        batiment.setEnqueteExternalKey(batimentPaylaod.getEnqueteId());
        batiment.setNub(batimentPaylaod.getNub());
        batiment.setCode(batimentPaylaod.getCode());
        batiment.setDateConstruction(batimentPaylaod.getDateConstruction());
        batiment.setExternalKey(batimentPaylaod.getExternalKey());

        return batiment;
    }

}
