package io.gmss.fiscad.implementations.decoupage;

import io.gmss.fiscad.entities.decoupage.Secteur;
import io.gmss.fiscad.entities.decoupage.SecteurDecoupage;
import io.gmss.fiscad.entities.infocad.parametre.Structure;
import io.gmss.fiscad.entities.user.User;
import io.gmss.fiscad.exceptions.BadRequestException;
import io.gmss.fiscad.exceptions.NotFoundException;
import io.gmss.fiscad.interfaces.decoupage.SecteurService;
import io.gmss.fiscad.paylaods.request.SecteurDecoupagePayload;
import io.gmss.fiscad.paylaods.request.SecteurPayload;
import io.gmss.fiscad.repositories.decoupage.ArrondissementRepository;
import io.gmss.fiscad.repositories.decoupage.QuartierRepository;
import io.gmss.fiscad.repositories.decoupage.SecteurRepository;
import io.gmss.fiscad.repositories.infocad.parametre.StructureRepository;
import io.gmss.fiscad.repositories.user.UserRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

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

@Service
public class SecteurServiceImpl implements SecteurService {
    private final SecteurRepository secteurRepository;
    private final UserRepository userRepository;
    private final ArrondissementRepository arrondissementRepository;
    private final QuartierRepository quartierRepository;
    private final StructureRepository structureRepository;

    public SecteurServiceImpl(SecteurRepository secteurRepository, UserRepository userRepository, ArrondissementRepository arrondissementRepository, QuartierRepository quartierRepository, StructureRepository structureRepository) {
        this.secteurRepository = secteurRepository;
        this.userRepository = userRepository;
        this.arrondissementRepository = arrondissementRepository;
        this.quartierRepository = quartierRepository;
        this.structureRepository = structureRepository;
    }


    @Override
    public Secteur createSecteur(SecteurPayload secteurPayload) throws BadRequestException {
        if (secteurPayload.getId() != null) {
            throw new BadRequestException("Impossible de créer un nouveau secteur ayant un id non null.");
        }

        if (secteurPayload.getChefSecteurId() != null && userRepository.existsById(secteurPayload.getChefSecteurId())) {
            Secteur secteur = getSecteurFromPayload(secteurPayload);
            return secteurRepository.save(secteur);
        } else {
            throw new BadRequestException("Impossible de créer un nouveau secteur sans le chef le Chef Secteur.");
        }
    }

    private Secteur getSecteurFromPayload(SecteurPayload secteurPayload) {
        Secteur secteur = new Secteur();
        Optional<User> optionalUser = userRepository.findById(secteurPayload.getChefSecteurId());
        secteur.setChefSecteur(optionalUser.orElse(null));
        Optional<Structure> optionalStructure = structureRepository.findById(secteurPayload.getStructureId());
        secteur.setStructure(optionalStructure.orElse(null));
        List<SecteurDecoupage> secteurDecoupageList = new ArrayList<>();

        for (SecteurDecoupagePayload sdp : secteurPayload.getSecteurDecoupages()) {
            SecteurDecoupage sd = new SecteurDecoupage();
            if (sdp.getSecteurId() != null && secteurRepository.existsById(sdp.getSecteurId())) {
                sd.setSecteur(secteurRepository.findById(sdp.getSecteurId()).orElse(null));
            }

            if (sdp.getArrondissementId() != null && arrondissementRepository.existsById(sdp.getArrondissementId())) {
                sd.setArrondissement(arrondissementRepository.findById(sdp.getArrondissementId()).orElse(null));
            }

            if (sdp.getQuartierId() != null && quartierRepository.existsById(sdp.getQuartierId())) {
                sd.setQuartier(quartierRepository.findById(sdp.getQuartierId()).orElse(null));
            }
            sd.setDateDebut(sdp.getDateDebut());
            sd.setDateFin(sdp.getDateFin());
            sd.setId(sdp.getId());
            secteurDecoupageList.add(sd);
        }
        secteur.setSecteurDecoupages(secteurDecoupageList);
        //TODO
        secteur.setId(secteurPayload.getId());
        secteur.setCode(secteurPayload.getCode());
        secteur.setNom(secteurPayload.getNom());
        return secteur;
    }

    @Override
    public Secteur updateSecteur(Long id, SecteurPayload secteurPayload) throws NotFoundException {
        if (secteurPayload.getId() == null) {
            throw new BadRequestException("Impossible de mettre à jour un nouveau secteur ayant un id null.");
        }

        if (!secteurRepository.existsById(secteurPayload.getId())) {
            throw new NotFoundException("Impossible de trouver le secteur spécifié.");
        }
        if (secteurPayload.getChefSecteurId() != null && userRepository.existsById(secteurPayload.getChefSecteurId())) {
            Secteur secteur = getSecteurFromPayload(secteurPayload);
            return secteurRepository.save(secteur);
        } else {
            throw new BadRequestException("Impossible de créer un nouveau secteur sans le chef le Chef Secteur.");
        }
    }

    @Override
    public void deleteSecteur(Long id) throws NotFoundException {
        Optional<Secteur> secteurOptional = secteurRepository.findById(id);
        if (secteurOptional.isPresent()) {
            secteurRepository.deleteById(secteurOptional.get().getId());
        } else {
            throw new NotFoundException("Impossible de trouver le secteur spécifié.");
        }
    }

    @Override
    public Page<Secteur> getSecteurList(Pageable pageable) {
        return secteurRepository.findAll(pageable);
    }

    @Override
    public List<Secteur> getSecteurList() {
        return secteurRepository.findAll();
    }

    @Override
    public List<Secteur> getSecteurListUneStruture(Long structureId) {
        return secteurRepository.findAllByStructure_Id(structureId);
    }


    @Override
    public Optional<Secteur> getSecteurById(Long id) {
        return secteurRepository.findById(id);
    }
}