package io.gmss.fiscad.implementations.rfu.parametre;

import io.gmss.fiscad.entities.decoupage.Secteur;
import io.gmss.fiscad.entities.infocad.parametre.Bloc;
import io.gmss.fiscad.entities.rfu.parametre.Campagne;
import io.gmss.fiscad.entities.rfu.parametre.Equipe;
import io.gmss.fiscad.entities.rfu.parametre.Participer;
import io.gmss.fiscad.exceptions.BadRequestException;
import io.gmss.fiscad.exceptions.NotFoundException;
import io.gmss.fiscad.interfaces.rfu.parametre.EquipeService;
import io.gmss.fiscad.paylaods.request.EquipePayload;
import io.gmss.fiscad.paylaods.request.ParticiperPayload;
import io.gmss.fiscad.repositories.decoupage.SecteurRepository;
import io.gmss.fiscad.repositories.infocad.parametre.BlocRepository;
import io.gmss.fiscad.repositories.rfu.parametre.CampagneRepository;
import io.gmss.fiscad.repositories.rfu.parametre.EquipeRepository;
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 EquipeServiceImpl implements EquipeService {
    private final EquipeRepository equipeRepository;
    private final UserRepository userRepository;
    private final BlocRepository blocRepository;
    private final SecteurRepository secteurRepository;
    private final CampagneRepository campagneRepository;

    public EquipeServiceImpl(EquipeRepository equipeRepository, UserRepository userRepository, BlocRepository blocRepository, SecteurRepository secteurRepository, CampagneRepository campagneRepository) {
        this.equipeRepository = equipeRepository;
        this.userRepository = userRepository;
        this.blocRepository = blocRepository;
        this.secteurRepository = secteurRepository;
        this.campagneRepository = campagneRepository;
    }


    @Override
    public Equipe createEquipe(EquipePayload equipePayload) throws BadRequestException {
        if (equipePayload.getId() != null) {
            throw new BadRequestException("Impossible de créer une nouvelle equipe ayant un id non null.");
        }
        Equipe equipe = getEquipeFromPayload(equipePayload);
        return equipeRepository.save(equipe);
    }

    private Equipe getEquipeFromPayload(EquipePayload equipePayload) {
        Equipe equipe = new Equipe();
        Optional<Bloc> optionalBloc = blocRepository.findById(equipePayload.getBlocId());
        equipe.setBloc(optionalBloc.orElse(null));
        equipe.setId(equipePayload.getId());
        equipe.setCode(equipePayload.getCode());
        equipe.setNom(equipePayload.getNom());
        Optional<Secteur> optionalSecteur = secteurRepository.findById(equipePayload.getSecteurId());
        equipe.setSecteur(optionalSecteur.orElse(null));
        Optional<Campagne> optionalCampagne = campagneRepository.findById(equipePayload.getCampagneId());
        equipe.setCampagne(optionalCampagne.orElse(null));

        List<Participer> participerList = new ArrayList<>();

        for (ParticiperPayload pp : equipePayload.getParticiperPayloads()) {
            Participer part = new Participer();
            part.setId(pp.getId());
            if (pp.getEquipeId() != null && equipeRepository.existsById(equipe.getId())) {
                part.setEquipe(equipeRepository.findById(equipe.getId()).orElse(null));
            }
            if (pp.getUserId() != null && userRepository.existsById(pp.getUserId())) {
                part.setUser(userRepository.findById(pp.getUserId()).orElse(null));
            }
            part.setDateDebut(pp.getDateDebut());
            part.setDateFin(pp.getDateFin());
            participerList.add(part);
        }
        equipe.setParticipers(participerList);

        return equipe;
    }

    @Override
    public Equipe updateEquipe(Long id, EquipePayload equipePayload) throws NotFoundException {
        if (equipePayload.getId() == null) {
            throw new BadRequestException("Impossible de mettre à jour une nouvelle equipe ayant un id null.");
        }
        if (!equipeRepository.existsById(equipePayload.getId())) {
            throw new NotFoundException("Impossible de trouver la equipe spécifiée dans notre base de données.");
        }
        Equipe equipe = getEquipeFromPayload(equipePayload);
        return equipeRepository.save(equipe);
    }

    @Override
    public void deleteEquipe(Long id) throws NotFoundException {
        Optional<Equipe> equipeOptional = equipeRepository.findById(id);
        if (equipeOptional.isPresent()) {
            equipeRepository.deleteById(equipeOptional.get().getId());
        } else {
            throw new NotFoundException("Impossible de trouver la equipe spécifiée dans notre base de données.");
        }
    }

    @Override
    public Page<Equipe> getEquipeList(Pageable pageable) {
        return equipeRepository.findAll(pageable);
    }

    @Override
    public List<Equipe> getEquipeList() {
        return equipeRepository.findAll();
    }


    @Override
    public Optional<Equipe> getEquipeById(Long id) {
        return equipeRepository.findById(id);
    }
}
