package ru.ulstu.is.cbapp;

import javax.persistence.EntityNotFoundException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.util.Pair;
import ru.ulstu.is.cbapp.models.Category;
import ru.ulstu.is.cbapp.models.DrivingSchool;
import ru.ulstu.is.cbapp.models.Student;
import ru.ulstu.is.cbapp.service.CategoryService;
import ru.ulstu.is.cbapp.service.DrivingSchoolService;
import ru.ulstu.is.cbapp.service.StudentService;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
public class DrivingSchoolServiceTests {
    @Autowired
    private DrivingSchoolService drivingSchoolService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private StudentService studentService;


    @Test
    public void testDeleteAllDrivingSchools() {
        drivingSchoolService.deleteAllDrivingSchools();
        int n = 3;
        for (int i = 0; i < n; i++) {
            String name = "DrivingSchool" + i;
            drivingSchoolService.addDrivingSchool(name);
        }
        drivingSchoolService.deleteAllDrivingSchools();
        Assertions.assertEquals(drivingSchoolService.findAllDrivingSchools().size(), 0);
    }

    @Test
    public void testDeleteDrivingSchool() {
        drivingSchoolService.deleteAllDrivingSchools();
        String name = "DrivingSchool1";
        DrivingSchool d = drivingSchoolService.addDrivingSchool(name);
        drivingSchoolService.deleteDrivingSchool(d.getId());
        Assertions.assertThrows(EntityNotFoundException.class, () -> {
            drivingSchoolService.findDrivingSchool(d.getId());});
    }

    @Test
    public void testAddDrivingSchool() {
        drivingSchoolService.deleteAllDrivingSchools();
        String name = "DrivingSchool1";
        DrivingSchool d = drivingSchoolService.addDrivingSchool(name);
        Assertions.assertNotNull(drivingSchoolService.findDrivingSchool(d.getId()));
        drivingSchoolService.deleteAllDrivingSchools();
    }

    @Test
    public void testUpdateDrivingSchool() {
        drivingSchoolService.deleteAllDrivingSchools();
        String name = "DrivingSchool1";
        DrivingSchool ds = drivingSchoolService.addDrivingSchool(name);
        String name2 = "DrivingSchool2";
        drivingSchoolService.updateDrivingSchool(ds.getId(), name2);
        Assertions.assertNotNull(drivingSchoolService.findDrivingSchool(ds.getId()));
        drivingSchoolService.deleteAllDrivingSchools();
    }


    @Test
    public void testFindAllDrivingSchools() {
        drivingSchoolService.deleteAllDrivingSchools();
        int n = 3;
        for (int i = 0; i < n; i++) {
            String name = "DrivingSchool" + i;
            drivingSchoolService.addDrivingSchool(name);
        }

        Assertions.assertEquals(drivingSchoolService.findAllDrivingSchools().size(), n);
        drivingSchoolService.deleteAllDrivingSchools();
    }

    @Test
    public void testGroupStudentCategory() {
        studentService.deleteAllStudents();
        drivingSchoolService.deleteAllDrivingSchools();
        categoryService.deleteAllCategories();

        final String name = "DrivingSchool";
        DrivingSchool d = drivingSchoolService.addDrivingSchool(name);

        Student s1 = studentService.addStudent("cha", "chacha", "111");
        Student s2 = studentService.addStudent("cha", "chacha", "111");
        Student s3 = studentService.addStudent("cha", "chacha", "111");

        Category c1 = categoryService.addCategory("Category1");
        Category c2 = categoryService.addCategory("Category2");
        Category c3 = categoryService.addCategory("Category3");

        studentService.addCategory(s1.getId(), c1);
        studentService.addCategory(s2.getId(), c2);
        studentService.addCategory(s3.getId(), c3);

        List<Student> studs = new ArrayList<>();
        studs.add(s1);
        studs.add(s2);
        studs.add(s3);

        drivingSchoolService.addAllStudent(d.getId(), studs);

        List<Pair<Long,Integer>> list=drivingSchoolService.CountStudentsCategory(d.getId());

        Assertions.assertNotNull(list);

        studentService.deleteAllStudents();
        drivingSchoolService.deleteAllDrivingSchools();
        categoryService.deleteAllCategories();
    }

    @Test
    public void testAddStudent() {

        studentService.deleteAllStudents();
        drivingSchoolService.deleteAllDrivingSchools();

        final String name = "DrivingSchool";
        DrivingSchool d = drivingSchoolService.addDrivingSchool(name);

        Student s1 = studentService.addStudent("cha", "chacha", "111");
        Student s2 = studentService.addStudent("cha", "chacha", "111");
        Student s3 = studentService.addStudent("cha", "chacha", "111");


        List<Student> studs = new ArrayList<>();
        studs.add(s1);
        studs.add(s2);
        studs.add(s3);

        drivingSchoolService.addAllStudent(d.getId(), studs);

        Assertions.assertTrue(drivingSchoolService.findDrivingSchool(d.getId()).getStudents().contains(s1));
        Assertions.assertTrue(drivingSchoolService.findDrivingSchool(d.getId()).getStudents().contains(s2));
        Assertions.assertTrue(drivingSchoolService.findDrivingSchool(d.getId()).getStudents().contains(s3));

        studentService.deleteAllStudents();
        drivingSchoolService.deleteAllDrivingSchools();
    }

    @Test
    public void testDeleteStudent() {
        studentService.deleteAllStudents();
        drivingSchoolService.deleteAllDrivingSchools();

        final String name = "DrivingSchool";
        DrivingSchool d = drivingSchoolService.addDrivingSchool(name);
        Student student1 = studentService.addStudent("cha1", "chacha1", "111");
        Student student2 = studentService.addStudent("cha2", "chacha2", "1111");
        Student student3 = studentService.addStudent("cha3", "chacha3", "11111");

        drivingSchoolService.addNewStudent(d.getId(), student1);
        drivingSchoolService.addNewStudent(d.getId(), student2);
        drivingSchoolService.addNewStudent(d.getId(), student3);

        Assertions.assertTrue(drivingSchoolService.findDrivingSchool(d.getId()).getStudents().contains(student1));
        Assertions.assertTrue(drivingSchoolService.findDrivingSchool(d.getId()).getStudents().contains(student2));
        Assertions.assertTrue(drivingSchoolService.findDrivingSchool(d.getId()).getStudents().contains(student3));

        DrivingSchool ds=drivingSchoolService.findDrivingSchool(d.getId());

        Assertions.assertNotNull(ds);

        Assertions.assertTrue(ds.getStudents().contains(student1));
        Assertions.assertTrue(ds.getStudents().contains(student2));
        Assertions.assertTrue(ds.getStudents().contains(student3));

        studentService.deleteAllStudents();
        drivingSchoolService.deleteAllDrivingSchools();
    }

    @Test
    public void testFindAllStudent(){
        studentService.deleteAllStudents();
        drivingSchoolService.deleteAllDrivingSchools();

        DrivingSchool d = drivingSchoolService.addDrivingSchool("ds");
        Student student1 = studentService.addStudent("cha1", "chacha1", "1111");
        Student student2 = studentService.addStudent("cha2", "chacha2", "11111");
        Student student3 = studentService.addStudent("cha3", "chacha3", "111111");

        drivingSchoolService.addNewStudent(d.getId(), student1);
        drivingSchoolService.addNewStudent(d.getId(), student2);
        drivingSchoolService.addNewStudent(d.getId(), student3);

        Assertions.assertTrue(drivingSchoolService.findDrivingSchool(d.getId()).getStudents().contains(student1));
        Assertions.assertTrue(drivingSchoolService.findDrivingSchool(d.getId()).getStudents().contains(student2));
        Assertions.assertTrue(drivingSchoolService.findDrivingSchool(d.getId()).getStudents().contains(student3));

        studentService.deleteAllStudents();
        drivingSchoolService.deleteAllDrivingSchools();
    }
}
