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

import io.gmss.fiscad.entities.infocad.metier.Commentaire;
import io.gmss.fiscad.enums.Origine;
import io.gmss.fiscad.exceptions.BadRequestException;
import io.gmss.fiscad.exceptions.NotFoundException;
import io.gmss.fiscad.interfaces.infocad.metier.CommentaireService;
import io.gmss.fiscad.paylaods.request.SyncCommentaireRequest;
import io.gmss.fiscad.paylaods.response.CommentaireResponse;
import io.gmss.fiscad.repositories.infocad.metier.CommentaireRepository;
import org.springframework.stereotype.Service;

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

@Service
public class CommentaireServiceImpl implements CommentaireService {

    private final CommentaireRepository commentaireRepository;

    public CommentaireServiceImpl(CommentaireRepository commentaireRepository) {
        this.commentaireRepository = commentaireRepository;
    }

    @Override
    public Commentaire createCommentaire(Commentaire commentaire) throws BadRequestException {
        if (commentaire.getId() != null) {
            throw new BadRequestException("Impossible de créer un nouveau commentaire ayant un id non null.");
        }
        return commentaireRepository.save(commentaire);
    }

    @Override
    public Commentaire updateCommentaire(Long id, Commentaire commentaire) throws NotFoundException {
        if (commentaire.getId() == null) {
            throw new BadRequestException("Impossible de mettre à jour un nouveau commentaire ayant un id null.");
        }
        if (!commentaireRepository.existsById(commentaire.getId())) {
            throw new NotFoundException("Impossible de trouver le commentaire spécifié dans notre base de données.");
        }
        return commentaireRepository.save(commentaire);
    }

    @Override
    public void deleteCommentaire(Long id) throws NotFoundException {
        Optional<Commentaire> commentaireOptional = commentaireRepository.findById(id);
        if (commentaireOptional.isPresent()) {
            commentaireRepository.deleteById(commentaireOptional.get().getId());
        } else {
            throw new NotFoundException("Impossible de trouver le commentaire spécifié dans notre base de données.");
        }
    }

    @Override
    public List<Commentaire> getCommentairesByEnqueteAndTerminal(Long idEnquete, Long terminalId) {
        return commentaireRepository.findAllByIdEnqueteAndTerminalId(idEnquete, terminalId);
    }

    @Override
    public List<Commentaire> getCommentairesByEnqueteAndLu(Long idEnquete, boolean lu) {
        return commentaireRepository.findAllByIdEnqueteAndLu(idEnquete, lu);
    }

    @Override
    public List<Commentaire> getCommentairesByOrigineAndStateReadAndTerminalId(Origine origine, boolean lu, Long terminalId) {
        return commentaireRepository.findAllByOrigineAndLuAndTerminalId(origine, lu, terminalId);
    }

    @Override
    public List<Commentaire> getCommentairesByOrigineAndStateSynchronizedAndTerminalId(Origine origine, boolean synchronise, Long terminalId) {
        return commentaireRepository.findAllByOrigineAndSynchroniseAndTerminalId(origine, synchronise, terminalId);
    }


    @Override
    public Optional<Commentaire> getCommentaireByNup(String nup) {
        return commentaireRepository.getCommentaireByNupParcelle(nup);
    }

    @Override
    public List<Commentaire> getCommentaireList() {
        return commentaireRepository.findAll();
    }

    @Override
    public Optional<Commentaire> getCommentaireById(Long id) {
        return commentaireRepository.findById(id);
    }

    @Override
    public boolean setCommentaireRead(Long id) {
        if (commentaireRepository.existsById(id)) {
            Commentaire commentaire = commentaireRepository.getById(id);
            commentaire.setLu(true);
            updateCommentaire(id, commentaire);
            return true;
        }
        return false;
    }

    @Override
    public List<CommentaireResponse> saveAllCommentairesFromMobile(List<Commentaire> commentaires) {
        List<CommentaireResponse> commentaireResponses = new ArrayList<>();
        commentaires.forEach(commentaire -> {
            Commentaire commentaire1 = createCommentaire(commentaire);
            CommentaireResponse commentaireResponse = new CommentaireResponse(commentaire1.getId(), commentaire1.getExternalKey());
            commentaireResponses.add(commentaireResponse);
        });
        return commentaireResponses;
    }

    @Override
    public List<CommentaireResponse> notifySynchronizedDoneFromMobile(List<SyncCommentaireRequest> syncCommentaireRequests) {

        if (syncCommentaireRequests != null || !syncCommentaireRequests.isEmpty()) {
            List<CommentaireResponse> commentaireResponses = new ArrayList<>();
            syncCommentaireRequests.forEach(syncCommentaireRequest -> {
                Optional<Commentaire> commentaireOptional = commentaireRepository.findById(syncCommentaireRequest.getIdBackend());
                if (commentaireOptional.isPresent()) {
                    Commentaire commentaire = commentaireOptional.get();
                    commentaire.setExternalKey(syncCommentaireRequest.getExternalKey());
                    commentaire.setSynchronise(true);
                    commentaireRepository.save(commentaire);
                    CommentaireResponse commentaireResponse = new CommentaireResponse(commentaire.getId(), commentaire.getExternalKey());
                    commentaireResponses.add(commentaireResponse);
                }
            });
            return commentaireResponses;
        }
        return null;
    }
}
