package io.gmss.fiscad.implementations.user;

import io.gmss.fiscad.entities.infocad.parametre.Structure;
import io.gmss.fiscad.entities.user.DemandeReinitialisationMP;
import io.gmss.fiscad.entities.user.User;
import io.gmss.fiscad.enums.EtatDemande;
import io.gmss.fiscad.exceptions.BadRequestException;
import io.gmss.fiscad.exceptions.NotFoundException;
import io.gmss.fiscad.interfaces.user.DemandeReinitialisationMPService;
import io.gmss.fiscad.interfaces.user.UserService;
import io.gmss.fiscad.repositories.user.DemandeReinitialisationMPRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

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

@Service
public class DemandeReinitialisationMPServiceImpl implements DemandeReinitialisationMPService {

    private final DemandeReinitialisationMPRepository demandeReinitialisationMPRepository;
    private final UserService userService;

    public DemandeReinitialisationMPServiceImpl(DemandeReinitialisationMPRepository demandeReinitialisationMPRepository, UserService userService) {
        this.demandeReinitialisationMPRepository = demandeReinitialisationMPRepository;
        this.userService = userService;
    }

    @Override
    public DemandeReinitialisationMP createDemandeReinitialisationMP(String usernameOrEmail) throws BadRequestException {


        User user = userService.getUserByUsername(usernameOrEmail);

        DemandeReinitialisationMP demandeReinitialisationMP = new DemandeReinitialisationMP();
        demandeReinitialisationMP.setUser(user);
        demandeReinitialisationMP.setEtatDemande(EtatDemande.NON_TRAITE);

        if (demandeReinitialisationMP.getId() != null) {
            throw new BadRequestException("Impossible de créer une nouvelle demande de reinitialisation de mot de passe ayant un id non null.");
        }
        return demandeReinitialisationMPRepository.save(demandeReinitialisationMP);
    }

    @Override
    public DemandeReinitialisationMP updateDemandeReinitialisationMP(Long id, DemandeReinitialisationMP demandeReinitialisationMP) throws NotFoundException {
        if (demandeReinitialisationMP.getId() == null) {
            throw new BadRequestException("Impossible de mettre à jour une nouvelle demande de reinitialisation de mot de passe ayant un id null.");
        }
        if (!demandeReinitialisationMPRepository.existsById(demandeReinitialisationMP.getId())) {
            throw new NotFoundException("Impossible de trouver la demande de reinitialisation de mot de passe spécifiée dans notre base de données.");
        }
        return demandeReinitialisationMPRepository.save(demandeReinitialisationMP);
    }

    @Override
    public void deleteDemandeReinitialisationMP(Long id) throws NotFoundException {
        Optional<DemandeReinitialisationMP> demandeReinitialisationMPOptional = demandeReinitialisationMPRepository.findById(id);
        if (demandeReinitialisationMPOptional.isPresent()) {
            demandeReinitialisationMPRepository.deleteById(demandeReinitialisationMPOptional.get().getId());
        } else {
            throw new NotFoundException("Impossible de trouver la demande de reinitialisation de mot de passe spécifiée dans notre base de données.");
        }
    }

    @Override
    public Page<DemandeReinitialisationMP> getDemandeReinitialisationMPList(Pageable pageable) {
        return demandeReinitialisationMPRepository.findAll(pageable);
    }

    @Override
    public List<DemandeReinitialisationMP> getDemandeReinitialisationMPList() {
        return demandeReinitialisationMPRepository.findAll();
    }

    @Override
    public List<DemandeReinitialisationMP> getDemandeReinitialisationMPNonTraiteList(Structure structure) {
        return demandeReinitialisationMPRepository.findAllByEtatDemandeAndUser_Structure(EtatDemande.NON_TRAITE, structure);
    }

    @Override
    public Optional<DemandeReinitialisationMP> getDemandeReinitialisationMPById(Long id) {
        if (demandeReinitialisationMPRepository.existsById(id)) {
            return demandeReinitialisationMPRepository.findById(id);
        } else {
            throw new NotFoundException("Impossible de trouver la demande de reinitialisation de mot de passe spécifiée dans la base de données.");
        }

    }

    @Override
    public DemandeReinitialisationMP traiterDemandeReinitialisation(Long id, String password) {
        Optional<DemandeReinitialisationMP> demandeReinitialisationMPOptional = getDemandeReinitialisationMPById(id);
        if (demandeReinitialisationMPOptional.isPresent()) {
            DemandeReinitialisationMP demandeReinitialisationMP = demandeReinitialisationMPOptional.get();
            User user = demandeReinitialisationMP.getUser();
            userService.resetPassword(user.getUsername(), password);
            demandeReinitialisationMP.setEtatDemande(EtatDemande.TRAITE);
            return demandeReinitialisationMPRepository.save(demandeReinitialisationMP);
        } else {
            throw new NotFoundException("La demande de réinitialisation du mot de passe n'est pas trouvée.");
        }
    }
}
