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

import org.springframework.stereotype.Service;

import lombok.AllArgsConstructor;
import nl.tudelft.librador.dto.DTOConverter;
import nl.tudelft.queue.cache.ModuleCacheManager;
import nl.tudelft.queue.cache.PersonCacheManager;
import nl.tudelft.queue.dto.view.requests.LabRequestViewDTO;
import nl.tudelft.queue.model.LabRequest;
import nl.tudelft.queue.model.enums.RequestStatus;
import nl.tudelft.queue.model.events.*;
import nl.tudelft.queue.realtime.messages.*;

@Service
@AllArgsConstructor
public class RequestStatusUpdateMessageService {

	private final RequestViewDTOService requestViewDTOService;

	private final ModuleCacheManager moduleCache;
	private final PersonCacheManager personCache;

	private final DTOConverter converter;

	public RequestCreatedMessage convert(RequestCreatedEvent event) {
		RequestCreatedMessage message = converter.convert((LabRequest) event.getRequest(),
				RequestCreatedMessage.class);
		LabRequestViewDTO request = requestViewDTOService.convert((LabRequest) event.getRequest());

		setLabRequestAttributes(message, request);

		message.setStatus(RequestStatus.PENDING);
		message.setSentence(request.toSentence());

		if (request.getEdition() != null) {
			message.setEditionId(request.getEdition().getId());
			message.setCourseId(request.getEdition().getCourse().getId());
		} else if (request.getEditionCollection() != null) {
			message.setEcId(request.getEditionCollection().getId());
			message.setEditionId(moduleCache
					.getRequired(request.getAssignment().getModule().getId())
					.getEdition().getId());
		}

		return message;
	}

	public RequestForwardedToAnyMessage convert(RequestForwardedToAnyEvent event) {
		RequestForwardedToAnyMessage message = converter.convert(event, RequestForwardedToAnyMessage.class);
		LabRequestViewDTO request = requestViewDTOService.convert(event.getRequest());

		setLabRequestAttributes(message, request);

		return message;
	}

	public RequestForwardedToPersonMessage convert(RequestForwardedToPersonEvent event) {
		RequestForwardedToPersonMessage message = converter.convert(event,
				RequestForwardedToPersonMessage.class);
		LabRequestViewDTO request = requestViewDTOService.convert(event.getRequest());

		setLabRequestAttributes(message, request);

		return message;
	}

	private void setLabRequestAttributes(LabRequestMessage message, LabRequestViewDTO request) {
		message.setOrganizationName(request.organizationName());

		message.setLabId(request.getQSession().getId());
		message.setRequestType(request.getRequestType());
		message.setRequestTypeDisplayName(request.getRequestType().displayName());
		message.setRequestedBy(request.requesterEntityName());

		message.setAssignmentId(request.getAssignment().getId());
		message.setAssignmentName(request.getAssignment().getName());
		message.setModuleId(request.getAssignment().getModule().getId());
		message.setModuleName(request.getAssignment().getModule().getName());

		if (request.getRoom() != null) {
			message.setRoomId(request.getRoom().getId());
			message.setRoomName(request.getRoom().getName());
			message.setBuildingId(request.getRoom().getBuilding().getId());
			message.setBuildingName(request.getRoom().getBuilding().getName());
		} else if (request.getOnlineMode() != null) {
			message.setOnlineMode(request.getOnlineMode());
			message.setOnlineModeDisplayName(request.getOnlineMode().getDisplayName());
		}
	}

	public RequestTakenMessage convert(RequestTakenEvent event) {
		RequestTakenMessage message = converter.convert(event, RequestTakenMessage.class);
		message.setTakenBy(personCache.getRequired(event.getAssistant()).getDisplayName());
		return message;
	}

}
