package com.wishurgift.service;

import com.wishurgift.helper.StatisticMaker;
import com.wishurgift.helper.UserMaker;
import com.wishurgift.persistence.data.StatsStatus;
import com.wishurgift.persistence.data.StatsWishlist;
import com.wishurgift.persistence.entity.User;
import com.wishurgift.persistence.repository.ContactRepository;
import com.wishurgift.persistence.repository.StatisticRepository;
import com.wishurgift.persistence.repository.UserRepository;
import com.wishurgift.service.bean.StatisticServiceBean;
import com.wishurgift.service.dto.StatisticDTO;
import com.wishurgift.service.dto.UserDTO;
import com.wishurgift.service.dto.transformer.UserTransformer;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import java.util.Optional;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

public class StatisticServiceTest {

    @Mock
    StatisticRepository statisticRepository;

    @Mock
    ContactRepository contactRepository;

    @Mock
    UserRepository userRepository;

    @Mock
    ContactService contactService;

    @InjectMocks
    StatisticServiceBean service;

    @Before
    public void before() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void getStatisticSelfTest() {
        long id = 1;
        UserDTO userDTO = UserMaker.makeUserDTO();
        User user = UserMaker.makeUser();
        StatsWishlist statsWishlist = StatisticMaker.makeStatsWishlist();
        StatsStatus statsStatus = StatisticMaker.makeStatsStatus();
        StatisticDTO expected = StatisticMaker.makeStatisticDTO();

        Mockito.when(userRepository.findById(id)).thenReturn(Optional.of(user));
        Mockito.when(statisticRepository.wishlistStats(user)).thenReturn(statsWishlist);
        Mockito.when(statisticRepository.statusStats(user)).thenReturn(statsStatus);
        Mockito.when(contactRepository.countAllContact(user)).thenReturn(expected.getContact());

        StatisticDTO actual = service.getStatistic(userDTO, id);
        assertEquals(expected, actual);
    }

    @Test
    public void getStatisticOtherTest() {
        long id = 8;
        UserDTO userDTO = UserMaker.makeUserDTO();
        User user = UserMaker.makeUser();
        StatsWishlist statsWishlist = StatisticMaker.makeStatsWishlist();
        StatsStatus statsStatus = StatisticMaker.makeStatsStatus();
        StatisticDTO expected = StatisticMaker.makeStatisticDTO();

        Mockito.when(userRepository.findById(id)).thenReturn(Optional.of(user));
        Mockito.when(contactService.isContact(userDTO, UserTransformer.entityToDto(user))).thenReturn(true);
        Mockito.when(statisticRepository.wishlistStats(user)).thenReturn(statsWishlist);
        Mockito.when(statisticRepository.statusStats(user)).thenReturn(statsStatus);
        Mockito.when(contactRepository.countAllContact(user)).thenReturn(expected.getContact());

        StatisticDTO actual = service.getStatistic(userDTO, id);
        assertEquals(expected, actual);
    }

    @Test
    public void failGetStatisticTest() {
        long id = 8;
        UserDTO userDTO = UserMaker.makeUserDTO();
        User user = UserMaker.makeUser();

        Mockito.when(userRepository.findById(id)).thenReturn(Optional.of(user));
        Mockito.when(contactService.isContact(userDTO, UserTransformer.entityToDto(user))).thenReturn(false);

        StatisticDTO actual = service.getStatistic(userDTO, id);
        assertNull(actual);
    }

    @Test
    public void userNotFoundGetStatisticTest() {
        long id = 8;
        UserDTO userDTO = UserMaker.makeUserDTO();

        Mockito.when(userRepository.findById(id)).thenReturn(Optional.empty());

        StatisticDTO actual = service.getStatistic(userDTO, id);
        assertNull(actual);
    }

}
