package org.fuseri.modulelanguageschool.lecture;

import org.fuseri.modulelanguageschool.course.Language;
import org.fuseri.modulelanguageschool.course.ProficiencyLevel;
import org.fuseri.modulelanguageschool.user.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;

import java.util.List;
import java.util.Optional;

@Service
public class LectureService {

    private final LectureRepository lectureRepository;

    @Autowired
    public LectureService(LectureRepository lectureRepository) {
        this.lectureRepository = lectureRepository;
    }

    @Transactional
    public Lecture save(Lecture lecture) {
        return lectureRepository.save(lecture);
    }

    @Transactional(readOnly = true)
    public Lecture findById(Long id) {
        return lectureRepository.findById(id)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND,
                        "Lecture with id: " + id + " was not found."));
    }

    @Transactional(readOnly = true)
    public List<Lecture> findAllByCourse(Long id) {
        return lectureRepository.findAllByCourse(id);
    }

    @Transactional
    public Lecture update(Long id, Lecture newLecture) {
        Optional<Lecture> optionalLecture = lectureRepository.findById(id);
        if (optionalLecture.isPresent()) {
            Lecture lecture = optionalLecture.get();
            lecture.setLectureFrom(newLecture.getLectureFrom());
            lecture.setLectureTo(newLecture.getLectureTo());
            lecture.setTopic(newLecture.getTopic());
            lecture.setCourse(newLecture.getCourse());
            lecture.setLecturer(newLecture.getLecturer());
            lecture.setStudents(newLecture.getStudents());
            return lectureRepository.save(lecture);
        } else {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND,
                    "Lecture with id: " + id + " was not found.");
        }
    }

    @Transactional
    public void delete(Long id) {
        lectureRepository.deleteById(id);
    }

    @Transactional
    public List<Lecture> findAll(Language language) {
        return lectureRepository.findAllByLang(language);
    }

    @Transactional
    public List<Lecture> findAll(Language language, ProficiencyLevel proficiencyLevel) {
        return lectureRepository.findAllByLangProf(language, proficiencyLevel);
    }

    @Transactional
    public Lecture enrol(Long id, User student) {
        Optional<Lecture> optionalLecture = lectureRepository.findById(id);
        if (optionalLecture.isPresent()) {
            Lecture lecture = optionalLecture.get();
            lecture.enrolStudent(student);
            return lectureRepository.save(lecture);
        } else {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND,
                    "Lecture with id: " + id + " was not found.");
        }
    }

    @Transactional
    public Lecture expel(Long id, User student) {
        Optional<Lecture> optionalLecture = lectureRepository.findById(id);
        if (optionalLecture.isPresent()) {
            Lecture lecture = optionalLecture.get();
            lecture.expelStudent(student);
            return lectureRepository.save(lecture);
        } else {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND,
                    "Lecture with id: " + id + " was not found.");
        }
    }

    @Transactional
    public Lecture setLecturer(Long id, User lecturer) {
        Optional<Lecture> optionalLecture = lectureRepository.findById(id);
        if (optionalLecture.isPresent()) {
            Lecture lecture = optionalLecture.get();
            lecture.setLecturer(lecturer);
            return lectureRepository.save(lecture);
        } else {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND,
                    "Lecture with id: " + id + " was not found.");
        }
    }
}
