/*
 * 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.mail;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;

import nl.tudelft.labracore.api.PersonControllerApi;
import nl.tudelft.labracore.api.dto.PersonDetailsDTO;
import nl.tudelft.labracore.lib.security.user.Person;
import nl.tudelft.queue.dto.create.CourseRequestCreateDTO;
import nl.tudelft.queue.dto.create.reporting.AcademicCounsellorReportDTO;
import nl.tudelft.queue.dto.create.reporting.ConfidentialAdvisorsReportDTO;
import nl.tudelft.queue.dto.create.reporting.ReportDTO;

public abstract class MailService {

	@Autowired
	private PersonControllerApi personApi;

	/**
	 * Setup the email to request a new course.
	 *
	 * @param  person Person requesting the new course
	 * @param  dto    CourseRequestDto containing info
	 * @param  url    Url to current running version of queue.
	 * @return        A message object which can be used to send an email.
	 */
	protected SimpleMailMessage createCourseRequestMail(Person person,
			CourseRequestCreateDTO dto,
			String url) {
		var msg = new SimpleMailMessage();

		msg.setSubject("Request to create course: " + dto.getName() + " (" + dto.getCode() + ")");
		msg.setText("user-displayname: " + person.getDisplayName() +
				"\nuser-username: " + person.getUsername() +
				"\nuser-id: " + person.getId() +
				"\nuser-email: " + person.getEmail() +
				"\nname: " + dto.getName() +
				"\ncode: " + dto.getCode() +
				"\nextra-info: " + dto.getRemarks() +
				"\n\nlink: " + url +
				"/admin/course/add?name=" + dto.getName().replaceAll(" ", "+") +
				"&code=" + dto.getCode().replaceAll(" ", "+") +
				"&manager=" + person.getUsername().replaceAll(" ", "+"));
		return msg;
	}

	public abstract void sendCourseRequest(Person person, CourseRequestCreateDTO dto);

	/**
	 * Create the email to send regarding a report filled in queue.
	 *
	 * @param  dto DTO containing all the required info
	 * @return     A message object which can be used to send the email.
	 */
	protected SimpleMailMessage createReportMail(ReportDTO dto, Person reporter) {
		var msg = new SimpleMailMessage();
		msg.setSubject("A new report was filed in Queue");

		PersonDetailsDTO reported = personApi.getPersonById(dto.getReportedId()).block();

		msg.setText(String.format("""
				%s has filed a new report in the Queue regarding misconduct caused by %s\s
				The reporter can be contacted via the following mail address: %s

				The following description was provided:
				%s

				Note: This is an automatically generated email""", reporter.getDisplayName(),
				reported.getDisplayName(), reporter.getEmail(), dto.getDescription()));

		if (dto instanceof ConfidentialAdvisorsReportDTO reportDTO) {
			msg.setTo(reportDTO.getTrusteeMail());
		} else if (dto instanceof AcademicCounsellorReportDTO reportDTO) {
			assignRecipientsForAcademicCounsellor(msg, reportDTO);
		}

		return msg;
	}

	/**
	 * Setup recipients correctly in case we are mailing to the academic counselor.
	 *
	 * @param msg The message object to setup.
	 * @param dto The dto containing the required info about mail adresses.
	 */
	private void assignRecipientsForAcademicCounsellor(SimpleMailMessage msg,
			AcademicCounsellorReportDTO dto) {
		ArrayList<String> recipients = new ArrayList<>(List.of(dto.getAcademicCounsellorEmail()));
		if (dto.isMailToStudyAssoc()) {
			recipients.add(dto.getStudyAssocMail());
		}
		msg.setTo(recipients.toArray(new String[0]));
	}

	public abstract void sendReport(ReportDTO dto, Person reporter);
}
