package com.wishurgift.service.bean;

import com.wishurgift.persistence.entity.Contact;
import com.wishurgift.persistence.entity.User;
import com.wishurgift.persistence.repository.ContactRepository;
import com.wishurgift.persistence.repository.UserRepository;
import com.wishurgift.service.ContactService;
import com.wishurgift.service.dto.UserDTO;
import com.wishurgift.service.dto.request.TagRequestDTO;
import com.wishurgift.service.dto.transformer.UserTransformer;
import com.wishurgift.wrapper.Page;

import javax.ejb.Stateless;
import javax.inject.Inject;
import java.util.List;
import java.util.Optional;

@Stateless
public class ContactServiceBean implements ContactService {


    @Inject
    private ContactRepository repository;

    @Inject
    private UserRepository userRepository;

    @Override
    public UserDTO add(UserDTO principal, TagRequestDTO request) {
        // Recup l'utilisateur principale et l'utilisateur que l'on demande en contact
        Optional<User> optionalConnected = userRepository.findById(principal.getId());
        Optional<User> optionalOther = userRepository.findByTag(UserTransformer.convertTag(request.getTag()));
        if (!optionalConnected.isPresent() || !optionalOther.isPresent()) {
            return null;
        }
        User connected = optionalConnected.get();
        User other = optionalOther.get();
        // Verifie qu'il n'existe pas deja une demande
        Optional<Contact> contactOptional = repository.findRequest(connected, other);
        if (contactOptional.isPresent()) {
            return null;
        }
        // Ajoute la demande
        Contact contact = new Contact();
        contact.setRequester(connected);
        contact.setContact(other);
        repository.insert(contact);
        return UserTransformer.entityToDto(other);
    }

    @Override
    public void remove(UserDTO principal, UserDTO contact) {
        // Recup l'utilisateur principale et le contacte
        Optional<User> optionalConnected = userRepository.findById(principal.getId());
        Optional<User> optionalOther = userRepository.findById(contact.getId());
        if (!optionalConnected.isPresent() || !optionalOther.isPresent()) {
            return;
        }
        User connected = optionalConnected.get();
        User other = optionalOther.get();
        // Supprime les requeste présentes
        Optional<Contact> request1 = repository.findRequest(connected, other);
        Optional<Contact> request2 = repository.findRequest(other, connected);
        request1.ifPresent(value -> repository.delete(value));
        request2.ifPresent(value -> repository.delete(value));
    }

    @Override
    public boolean isContact(UserDTO principal, UserDTO contact) {
        // Recup l'utilisateur principale et le contacte
        Optional<User> optionalConnected = userRepository.findById(principal.getId());
        Optional<User> optionalOther = userRepository.findById(contact.getId());
        if (!optionalConnected.isPresent() || !optionalOther.isPresent()) {
            return false;
        }
        User connected = optionalConnected.get();
        User other = optionalOther.get();
        // Regarde si ils se sont tous les deux ajouté en contact
        Optional<Contact> request1 = repository.findRequest(connected, other);
        Optional<Contact> request2 = repository.findRequest(other, connected);
        return request1.isPresent() && request2.isPresent();
    }

    @Override
    public Page<UserDTO> getRequest(UserDTO principal) {
        // Recup l'utilisateur principale
        Optional<User> optionalConnected = userRepository.findById(principal.getId());
        if (!optionalConnected.isPresent()) {
            return null;
        }
        User connected = optionalConnected.get();
        // Recup liste des utilisateurs demandé en contact
        List<User> users = repository.getAllRequest(connected);
        List<UserDTO> userDTOs = UserTransformer.entityToDto(users);
        return Page.unpaged(userDTOs);
    }

    @Override
    public Page<UserDTO> getRequest(int page, int size, UserDTO principal) {
        // Recup l'utilisateur principale
        Optional<User> optionalConnected = userRepository.findById(principal.getId());
        if (!optionalConnected.isPresent()) {
            return null;
        }
        User connected = optionalConnected.get();
        // Recup liste des utilisateurs demandé en contact
        List<User> users = repository.getAllRequest(page, size, connected);
        List<UserDTO> userDTOs = UserTransformer.entityToDto(users);
        return Page.paged(page, repository.countAllRequest(connected), userDTOs);
    }

    @Override
    public Page<UserDTO> getPending(UserDTO principal) {
        // Recup l'utilisateur principale
        Optional<User> optionalConnected = userRepository.findById(principal.getId());
        if (!optionalConnected.isPresent()) {
            return null;
        }
        User connected = optionalConnected.get();
        // Recup liste des demandes en contact
        List<User> users = repository.getAllPending(connected);
        List<UserDTO> userDTOs = UserTransformer.entityToDto(users);
        return Page.unpaged(userDTOs);
    }

    @Override
    public Page<UserDTO> getPending(int page, int size, UserDTO principal) {
        // Recup l'utilisateur principale
        Optional<User> optionalConnected = userRepository.findById(principal.getId());
        if (!optionalConnected.isPresent()) {
            return null;
        }
        User connected = optionalConnected.get();
        // Recup liste des demandes en contact
        List<User> users = repository.getAllPending(page, size, connected);
        List<UserDTO> userDTOs = UserTransformer.entityToDto(users);
        return Page.paged(page, repository.countAllPending(connected), userDTOs);
    }

    @Override
    public Page<UserDTO> getContact(UserDTO principal) {
        // Recup l'utilisateur principale
        Optional<User> optionalConnected = userRepository.findById(principal.getId());
        if (!optionalConnected.isPresent()) {
            return null;
        }
        User connected = optionalConnected.get();
        // Recup liste des contacts
        List<User> users = repository.getAllContact(connected);
        List<UserDTO> userDTOs = UserTransformer.entityToDto(users);
        return Page.unpaged(userDTOs);
    }

    @Override
    public Page<UserDTO> getContact(int page, int size, UserDTO principal) {
        // Recup l'utilisateur principale
        Optional<User> optionalConnected = userRepository.findById(principal.getId());
        if (!optionalConnected.isPresent()) {
            return null;
        }
        User connected = optionalConnected.get();
        // Recup liste des contacts
        List<User> users = repository.getAllContact(page, size, connected);
        List<UserDTO> userDTOs = UserTransformer.entityToDto(users);
        return Page.paged(page, repository.countAllContact(connected), userDTOs);
    }

}
