/*
 * Queue - A Queueing system that can be used to handle labs in higher education
 * Copyright (C) 2016-2024  Delft University of Technology
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
package nl.tudelft.queue.service;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.ui.Model;

import jakarta.persistence.EntityNotFoundException;
import lombok.AllArgsConstructor;
import nl.tudelft.labracore.api.ProgramControllerApi;
import nl.tudelft.labracore.api.dto.PersonSummaryDTO;
import nl.tudelft.labracore.lib.security.user.Person;
import nl.tudelft.queue.cache.CourseCacheManager;
import nl.tudelft.queue.cache.EditionCacheManager;
import nl.tudelft.queue.cache.PersonCacheManager;
import nl.tudelft.queue.cache.SessionCacheManager;
import nl.tudelft.queue.dto.create.reporting.AcademicCounsellorReportDTO;
import nl.tudelft.queue.dto.create.reporting.ConfidentialAdvisorsReportDTO;
import nl.tudelft.queue.dto.create.reporting.ReportDTO;
import nl.tudelft.queue.model.Request;
import nl.tudelft.queue.repository.RequestRepository;
import nl.tudelft.queue.service.mail.MailService;

@Service
@AllArgsConstructor
public class ReportService {

	private final EditionCacheManager editionCacheManager;
	private final CourseCacheManager courseCacheManager;
	private final ProgramControllerApi programControllerApi;
	private RequestRepository requestRepository;

	private PersonCacheManager pCache;

	private SessionCacheManager sCache;

	private MailService mailService;

	public void getReportDetails(Long requestId, Person reporter, Model model) {
		Request<?> request = requestRepository.findById(requestId).orElseThrow(EntityNotFoundException::new);
		List<PersonSummaryDTO> usersInvolved = request.getAllPersonsInvolved().stream()
				.filter(l -> !l.equals(reporter.getId())).map(id -> pCache.getRequired(id,
						aLong -> {
							throw new EntityNotFoundException();
						}))
				.toList();
		model.addAttribute("usersInvolved", usersInvolved);

		var session = sCache.get(request.getSession().getSession()).orElseThrow();
		var edition = editionCacheManager.get(session.getEdition().getId()).orElseThrow();
		var course = courseCacheManager.get(edition.getCourse().getId()).orElseThrow();
		var program = programControllerApi.getProgramById(course.getProgram().getId()).block();

		model.addAttribute("program", program);

		var academicCounsellorBuilder = AcademicCounsellorReportDTO.builder();
		if (program.getAcademicCounsellor() != null) {
			academicCounsellorBuilder.academicCounsellorEmail(program.getAcademicCounsellor().getEmail());
		}
		if (program.getStudyAssociationTrustee() != null) {
			academicCounsellorBuilder.studyAssocMail(program.getStudyAssociationTrustee().getEmail());
		}
		model.addAttribute("academicCounsellorDto", academicCounsellorBuilder.build());

		model.addAttribute("confidentialAdvisorDto",
				ConfidentialAdvisorsReportDTO.builder().build());
	}

	public void doReportConfidential(ReportDTO dto, Person reporter) {
		mailService.sendReport(dto, reporter);
	}
}
