package org.fuseri.modulelanguageschool.lecture;

import org.fuseri.modulelanguageschool.course.Course;
import org.fuseri.modulelanguageschool.course.Language;
import org.fuseri.modulelanguageschool.course.ProficiencyLevel;
import org.fuseri.modulelanguageschool.user.User;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

@DataJpaTest
class LectureRepositoryTest {

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private LectureRepository lectureRepository;


    private final Course course = new Course("AJ1", 10,
            Language.ENGLISH, ProficiencyLevel.A1);
    private final User student = new User("novakovat", "novakova@gmail.com", "Tereza",
            "Nováková", new HashSet<>(), new HashMap<>());
    private final User lecturer = new User("dolezelt", "dolezel@gmail.com", "Tomáš",
            "Doležel", new HashSet<>(), new HashMap<>());
    private final Lecture lecture = new Lecture(
            LocalDateTime.now().plusDays(2),
            LocalDateTime.now().plusDays(2).plusHours(2),
            "Learning how to spell deprecated",
            10,
            course, lecturer, new ArrayList<>(List.of(student)));

    @Test
    void saveLecture() {
        Lecture saved = lectureRepository.save(lecture);

        Assertions.assertNotNull(saved);
        Assertions.assertEquals(lecture, saved);
    }

    @Test
    void findById() {
        entityManager.persist(lecturer);
        entityManager.persist(student);
        entityManager.persist(course);
        entityManager.persist(lecture);
        entityManager.flush();

        Lecture found = lectureRepository.findById(lecture.getId()).orElse(null);

        Assertions.assertNotNull(found);
        Assertions.assertEquals(found, lecture);
    }

    @Test
    void findAllByCourse() {
        entityManager.persist(lecturer);
        entityManager.persist(student);
        entityManager.persist(course);
        entityManager.persist(lecture);
        entityManager.flush();

        List<Lecture> found = lectureRepository.findAllByCourse(lecture.getCourse().getId());

        Assertions.assertEquals(1, found.size());
        Assertions.assertEquals(found.get(0), lecture);
    }

    @Test
    void findAllByLang() {
        entityManager.persist(lecturer);
        entityManager.persist(student);
        entityManager.persist(course);
        entityManager.persist(lecture);
        entityManager.flush();

        List<Lecture> found = lectureRepository.findAllByLang(lecture.getCourse().getLanguage());

        Assertions.assertEquals(1, found.size());
        Assertions.assertEquals(found.get(0), lecture);
    }

    @Test
    void findAllByLangProf() {
        entityManager.persist(lecturer);
        entityManager.persist(student);
        entityManager.persist(course);
        entityManager.persist(lecture);
        entityManager.flush();

        List<Lecture> found = lectureRepository.findAllByLangProf(lecture.getCourse().getLanguage(),
                lecture.getCourse().getProficiency());

        Assertions.assertEquals(1, found.size());
        Assertions.assertEquals(found.get(0), lecture);
    }

    @Test
    void testFindAllLectures() {
        Lecture lecture1 = new Lecture();
        Lecture lecture2 = new Lecture();

        lectureRepository.save(lecture1);
        lectureRepository.save(lecture2);

        Page<Lecture> lecturePage = lectureRepository.findAll(PageRequest.of(0, 42));

        Assertions.assertEquals(2, lecturePage.getTotalElements());
        Assertions.assertEquals(lecturePage.getContent(), Arrays.asList(lecture1, lecture2));
    }

    @Test
    void testDeleteLecture() {
        Long lectureId = entityManager.persist(new Lecture()).getId();
        entityManager.flush();

        lectureRepository.deleteById(lectureId);

        Assertions.assertTrue(lectureRepository.findById(lectureId).isEmpty());
    }
}

