package org.fuseri.modulelanguageschool.course;

import org.fuseri.model.dto.course.CourseCreateDto;
import org.fuseri.model.dto.course.CourseDto;
import org.fuseri.model.dto.course.LanguageTypeDto;
import org.fuseri.model.dto.course.ProficiencyLevelDto;
import org.fuseri.modulelanguageschool.user.User;
import org.fuseri.modulelanguageschool.user.UserService;
import org.mapstruct.Mapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;

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

@Mapper(componentModel = "spring", uses = {UserService.class})
public interface CourseMapper {

    default CourseDto mapToDto(Course course) {
        if (course == null) {
            return null;
        }

        var dto = new CourseDto(course.getName(),
                course.getCapacity(),
                LanguageTypeDto.valueOf(course.getLanguage().name()),
                ProficiencyLevelDto.valueOf(course.getProficiency().name()),
                new ArrayList<>(),
                course.isFinished());
        dto.setId(course.getId());
        var students = new ArrayList<Long>();
        for (User user : course.getStudents()) {
            students.add(user.getId());
        }
        dto.setStudents(students);
        return dto;
    }

    default Course mapToCourse(CourseDto dto, UserService userService) {
        if (dto == null) {
            return null;
        }
        var course = new Course(dto.getName(),
                dto.getCapacity(),
                Language.valueOf(dto.getLanguage().name()),
                ProficiencyLevel.valueOf(dto.getProficiency().name()),
                new ArrayList<>(),
                dto.getFinished());
        course.setId(dto.getId());
        for (Long userId : dto.getStudents()) {
            course.enrolStudent(userService.find(userId));
        }
        return course;
    }

    default List<CourseDto> mapToList(List<Course> courses) {
        if (courses == null) {
            return null;
        }
        return new ArrayList<>(courses.stream().map(this::mapToDto).toList());
    }

    default Page<CourseDto> mapToPageDto(Page<Course> courses) {
        return new PageImpl<>(mapToList(courses.getContent()), courses.getPageable(), courses.getTotalPages());
    }

    default Course mapToCourse(CourseCreateDto createDto) {
        if (createDto == null) {
            return null;
        }
        return new Course(createDto.getName(),
                createDto.getCapacity(),
                Language.valueOf(createDto.getLanguage().name()),
                ProficiencyLevel.valueOf(createDto.getProficiency().name()),
                new ArrayList<>(),
                false);
    }
}

