package org.fuseri.modulelanguageschool.user;

import org.fuseri.model.dto.user.UserCreateDto;
import org.fuseri.model.dto.user.UserDto;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    private final UserDto userDto = new UserDto(
            "xnovak", "xnovak@emample.com", "Peter", "Novak",new HashMap<>());
    private final UserCreateDto userCreateDto = new UserCreateDto(
            "xnovak", "xnovak@emample.com", "Peter", "Novak");

    private final User userFromCreateDto = new User(
            "xnovak", "xnovak@emample.com", "Peter", "Novak", null, null);

    private final User userFromDto = new User(
            "xnovak", "xnovak@emample.com", "Peter", "Novak", null, new HashMap<>());

    @Test
    void nullFromCreateDto() {
        User mappedUser = userMapper.fromCreateDto(null);
        assertNull(mappedUser);
    }

    @Test
    void fromCreateDto() {
        User mappedUser = userMapper.fromCreateDto(userCreateDto);
        assertEquals(userFromCreateDto, mappedUser);
    }

    @Test
    void nullFromDto() {
        User mappedUser = userMapper.fromDto(null);
        assertNull(mappedUser);
    }

    @Test
    void fromDto() {
        User mappedUser = userMapper.fromDto(userDto);
        assertEquals(userFromDto, mappedUser);
    }

    @Test
    void nullToDto() {
        var createdDto = userMapper.toDto(null);
        assertNull(createdDto);
    }

    @Test
    void toDto() {
        var mappedDto = userMapper.toDto(userFromDto);
        assertEquals(userDto, mappedDto);
    }

    @Test
    void nullToDtoList() {
        var mappedDtos = userMapper.toDtoList(null);
        assertNull(mappedDtos);
    }

    @Test
    void toEmptyDtoList() {
        var mappedDtos = userMapper.toDtoList(Collections.emptyList());
        assertTrue(mappedDtos.isEmpty());
    }

    @Test
    void toDtoList() {
        var mappedDtos = userMapper.toDtoList(List.of(userFromDto));
        assertEquals(List.of(userDto), mappedDtos);
    }

    @Test
    void toEmptyDtoPage() {
        Page<UserDto> pageDto = userMapper.toDtoPage(Page.empty());
        assertEquals(1, pageDto.getTotalPages());
        assertTrue(pageDto.getContent().isEmpty());
    }

    @Test
    void toDtoPage() {
        List<User> users = List.of(userFromDto);
        Page<User> page = new PageImpl<>(users, PageRequest.of(0, 10), users.size());
        Page<UserDto> pageDto = userMapper.toDtoPage(page);

        assertEquals(page.getTotalPages(), pageDto.getTotalPages());
        assertEquals(page.getNumber(), pageDto.getNumber());
        assertEquals(page.getNumberOfElements(), pageDto.getNumberOfElements());
        assertEquals(page.getSize(), pageDto.getSize());
        assertEquals(page.getTotalElements(), pageDto.getTotalElements());
        assertEquals(List.of(userDto), pageDto.getContent());
    }
}