package io.gmss.fiscad.implementations.infocad.metier;

import io.gmss.fiscad.entities.decoupage.Quartier;
import io.gmss.fiscad.entities.infocad.metier.Parcelle;
import io.gmss.fiscad.entities.infocad.parametre.NatureDomaine;
import io.gmss.fiscad.entities.infocad.parametre.SituationGeographique;
import io.gmss.fiscad.exceptions.BadRequestException;
import io.gmss.fiscad.exceptions.NotFoundException;
import io.gmss.fiscad.interfaces.infocad.metier.ParcelleService;
import io.gmss.fiscad.paylaods.request.ParcellePayLoad;
import io.gmss.fiscad.repositories.decoupage.QuartierRepository;
import io.gmss.fiscad.repositories.infocad.metier.ParcelleRepository;
import io.gmss.fiscad.repositories.infocad.parametre.NatureDomaineRepository;
import io.gmss.fiscad.repositories.infocad.parametre.SituationGeographiqueRepository;
import io.gmss.fiscad.service.GeometryService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;
import java.util.Optional;

public class ParcelleServiceImpl implements ParcelleService {
    private final NatureDomaineRepository natureDomaineRepository;
    private final QuartierRepository quartierRepository;
    private final SituationGeographiqueRepository situationGeographiqueRepository;
    private final ParcelleRepository parcelleRepository;
    private final GeometryService geometryService;
    @Value("${infocad.geom.srid}")
    private String defaultSrid32631;

    @Value("${infocad.geom.sridfixe}")
    private String defaultSrid;

    public ParcelleServiceImpl(NatureDomaineRepository natureDomaineRepository, QuartierRepository quartierRepository, SituationGeographiqueRepository situationGeographiqueRepository, ParcelleRepository parcelleRepository, GeometryService geometryService) {
        this.natureDomaineRepository = natureDomaineRepository;
        this.quartierRepository = quartierRepository;
        this.situationGeographiqueRepository = situationGeographiqueRepository;
        this.parcelleRepository = parcelleRepository;
        this.geometryService = geometryService;
    }


    @Override
    public Parcelle createParcelle(ParcellePayLoad parcellePayLoad) throws BadRequestException {
        Optional<NatureDomaine> optionalNatureDomaine = natureDomaineRepository.findById(parcellePayLoad.getNatureDomaineId());
        if (!optionalNatureDomaine.isPresent()) {
            throw new BadRequestException("Impossible d'enregistrer une parcelle avec une nature de domaine inexistant");
        }
        Optional<Quartier> optionalQuartier = quartierRepository.findById(parcellePayLoad.getQuartierId());
        if (!optionalQuartier.isPresent()) {
            throw new BadRequestException("Impossible d'enregistrer une parcelle avec un quartier/village inexistant");
        }
        Optional<SituationGeographique> optionalSituationGeographique = situationGeographiqueRepository.findById(parcellePayLoad.getSituationGeographiqueId());
        if (!optionalSituationGeographique.isPresent()) {
            throw new BadRequestException("Impossible d'enregistrer une parcelle avec une situation géographique inexistant");
        }

        Parcelle parcelle = getParcelle(parcellePayLoad, optionalSituationGeographique, optionalNatureDomaine);
        return parcelleRepository.save(parcelle);
    }

    @Override
    public Parcelle updateParcelle(ParcellePayLoad parcellePayLoad) throws NotFoundException {
        Optional<Parcelle> optionalParcelle = parcelleRepository.findById(parcellePayLoad.getIdBackend());
        if (!optionalParcelle.isPresent()) {
            throw new NotFoundException("Impossible de trouver la parcelle que vous désirer modifier");
        }
        Optional<NatureDomaine> optionalNatureDomaine = natureDomaineRepository.findById(parcellePayLoad.getNatureDomaineId());
        if (!optionalNatureDomaine.isPresent()) {
            throw new BadRequestException("Impossible d'enregistrer une parcelle avec une nature de domaine inexistante");
        }
        Optional<Quartier> optionalQuartier = quartierRepository.findById(parcellePayLoad.getQuartierId());
        if (!optionalQuartier.isPresent()) {
            throw new BadRequestException("Impossible d'enregistrer une parcelle avec un quartier/village inexistant");
        }
        Optional<SituationGeographique> optionalSituationGeographique = situationGeographiqueRepository.findById(parcellePayLoad.getSituationGeographiqueId());
        if (!optionalSituationGeographique.isPresent()) {
            throw new BadRequestException("Impossible d'enregistrer une parcelle avec une situation géographique inexistant");
        }

        Parcelle parcelle = getParcelle(optionalParcelle.get(), parcellePayLoad, optionalSituationGeographique, optionalNatureDomaine);
        return parcelleRepository.save(parcelle);
    }

    @Override
    public void deleteParcelle(Long id) throws NotFoundException {
        Optional<Parcelle> optionalParcelle = parcelleRepository.findById(id);
        if (optionalParcelle.isPresent()) {
            parcelleRepository.deleteById(optionalParcelle.get().getId());
        } else {
            throw new NotFoundException("Impossible de trouver la parcelle que vous désirez supprimer.");
        }
    }

    @Override
    public Page<Parcelle> getParcelleList(Pageable pageable) {
        return parcelleRepository.findAll(pageable);
    }

    @Override
    public List<Parcelle> getParcelleList() {
        return parcelleRepository.findAll();
    }

    @Override
    public Optional<Parcelle> getParcelleById(Long id) {
        if (parcelleRepository.existsById(id)) {
            return parcelleRepository.findById(id);
        } else {
            throw new NotFoundException("Impossible de trouver l'enquête.");
        }
    }

    private Parcelle getParcelle(ParcellePayLoad parcellePayLoad, Optional<SituationGeographique> optionalSituationGeographique, Optional<NatureDomaine> optionalNatureDomaine) {
        StringBuilder coordonnees = new StringBuilder();
        Parcelle parcelle = new Parcelle();
        parcelle.setP(parcellePayLoad.getP());
        parcelle.setI(parcellePayLoad.getI());
        parcelle.setQ(parcellePayLoad.getQ());
        parcelle.setNup(parcellePayLoad.getNup());
        parcelle.setLatitude(parcellePayLoad.getLatitude());
        parcelle.setLongitude(parcellePayLoad.getLongitude());
        //parcelle.setSituationGeographique(optionalSituationGeographique.get());
        parcelle.setSituationGeographique(parcellePayLoad.getSituationGeographique());
        parcelle.setNatureDomaine(optionalNatureDomaine.get());
        parcelle.setNupProvisoire(parcellePayLoad.getNupProvisoire());
        // parcelle.setGeomSrid(parcellePayLoad.getGeomSrid());
        //////////spatial
//        try {
//            Point point=null;
//            if (parcellePayLoad.getLatitude() != null && parcellePayLoad.getLongitude() != null){
//            coordonnees.append(parcelle.getLongitude()).append(" ").append(parcelle.getLatitude());
//            point = geometryService.toGeometryPoint(coordonnees.toString(), parcelle.getGeomSrid());//Integer.parseInt(defaultSrid));
//            if(parcelle.getGeomSrid()==Integer.parseInt(defaultSrid32631)) {
//                parcelle.setGeometry32631(point);
//                parcelle. setGeometry(null);
//            }
//            if(parcelle.getGeomSrid()==Integer.parseInt(defaultSrid)) {
//                parcelle.setGeometry(point);
//                parcelle.setGeometry32631(null);
//            }
//        }
//        }catch (Exception e){
//
//        }
        return parcelle;
    }

    private Parcelle getParcelle(Parcelle parcelle, ParcellePayLoad parcellePayLoad, Optional<SituationGeographique> optionalSituationGeographique, Optional<NatureDomaine> optionalNatureDomaine) {
        StringBuilder coordonnees = new StringBuilder();
        parcelle.setP(parcellePayLoad.getP());
        parcelle.setI(parcellePayLoad.getI());
        parcelle.setQ(parcellePayLoad.getQ());
        parcelle.setNup(parcellePayLoad.getNup());
        parcelle.setLatitude(parcellePayLoad.getLatitude());
        parcelle.setLongitude(parcellePayLoad.getLongitude());
        //parcelle.setSituationGeographique(optionalSituationGeographique.get());
        parcelle.setSituationGeographique(parcellePayLoad.getSituationGeographique());
        parcelle.setNatureDomaine(optionalNatureDomaine.get());
        parcelle.setNupProvisoire(parcellePayLoad.getNupProvisoire());
        //parcelle.setGeomSrid(parcellePayLoad.getGeomSrid());
        //////////spatial
//        try {
//            Point point=null;
//            if (parcellePayLoad.getLatitude() != null && parcellePayLoad.getLongitude() != null && parcellePayLoad.getGeomSrid() != 0){
//                coordonnees.append(parcelle.getLongitude()).append(" ").append(parcelle.getLatitude());
//                point = geometryService.toGeometryPoint(coordonnees.toString(), parcelle.getGeomSrid());//Integer.parseInt(defaultSrid));
//                if(parcelle.getGeomSrid()==Integer.parseInt(defaultSrid32631)) {
//                    parcelle.setGeometry32631(point);
//                    parcelle.setGeometry(null);
//                }
//                if(parcelle.getGeomSrid()==Integer.parseInt(defaultSrid)) {
//                    parcelle.setGeometry(point);
//                    parcelle.setGeometry32631(null);
//                }
//            }
//        }catch (Exception e){
//
//        }
        return parcelle;
    }


}