package managedbean.visit;

import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import TO.FamilyDoctorTO;
import TO.PatientTO;
import TO.VisitTO;
import common.UserType;
import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;

@Named("UpdateVisit")
@ViewScoped
public class UpdateVisitMBean extends ManagedBeanBase implements Serializable {

	private static final long serialVersionUID = 1L;

	private Integer id;
	private LocalDate date;
	private LocalTime time;
	private String observations;
	private String result;
	private PatientTO patient;
	private FamilyDoctorTO familyDoctor;
	private boolean resultReadOnly;
	private boolean readOnly;
	private UserType userType;
	private String fromPage;

	public UpdateVisitMBean() {
	}

	@PostConstruct
	public void init() {
		this.userType = SessionUtils.getUserType();
		if (this.userType == UserType.SPECIALIST_DOCTOR) {
			this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Acesso denegado", "Su perfil de usuario no está autorizado acceder a esta página.");
			return;
		}

		FacesContext context = FacesContext.getCurrentInstance();
		Map<String, String> requestParams = context.getExternalContext().getRequestParameterMap();
		VisitTO vi = null;

		try {
			this.fromPage = requestParams.get("fromPage");

			// Parámetro con el "id" de la visita.
			int parId = Integer.valueOf(requestParams.get("id"));

			vi = this.getRemoteManagerVisit().getVisit(parId);
		} catch (Exception e) {
			this.manageException(e);
		}

		if (vi != null) {
			this.id = vi.getId();
			this.date = vi.getDate();
			this.time = vi.getTime();
			this.observations = vi.getObservations();
			this.result = vi.getResult();
			this.patient = vi.getPatient();
			this.familyDoctor = vi.getFamilyDoctor();
		} else {
			this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Identificador de visita no válido",
					"No se ha podido recuperar el identificador de visita especificado. Por favor, vuelva a intentarlo seleccionando de nuevo la visita.");
		}
	}

	public void saveData() {
		try {
			switch (this.userType) {
			case ADMINISTRATOR:
			case PATIENT:
				// Administrador y paciente pueden actualizar la fecha y hora de la visita (excepto el resultado)
				// Comprobamos que la fecha fijada para la visita no sea anterior a la actual
				int error = 0;
				LocalDate today = LocalDate.now();

				if (this.date.isBefore(today)) {
					this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Fecha incorrecta", "La cita fijada es anterior al momento actual");
					error++;
				}
				if (this.date.equals(today) && this.time.isBefore(LocalTime.now())) {
					this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Fecha incorrecta", "La cita fijada es anterior al momento actual");
					error++;
				}
				if (error == 0) {
					this.getRemoteManagerVisit().updateVisit(this.id, this.date, this.time);
					this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Visita actualizada", "La fecha y hora de la visita se ha actualizado correctamente.");
				}
				break;
			case FAMILY_DOCTOR:
				// El médico de familia solo puede actualizar el resultado.
				// TODO: implementar método EJB para actualizar el resultado.
				this.getRemoteManagerVisit().addResultToVisit(this.id, this.result);
				this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Resultado actualizado", "El resultado de la visita se ha actualizado correctamente.");
				break;
			case SPECIALIST_DOCTOR:
				this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Acesso denegado", "Su perfil de usuario no está autorizado acceder a esta página.");
				return;
			}
		} catch (Exception e) {
			this.manageException(e);
		}
	}

	public LocalDate getDate() {
		return date;
	}

	public void setDate(LocalDate date) {
		this.date = date;
	}

	public LocalTime getTime() {
		return time;
	}

	public void setTime(LocalTime time) {
		this.time = time;
	}

	public String getObservations() {
		return observations;
	}

	public void setObservations(String observations) {
		this.observations = observations;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

	public PatientTO getPatient() {
		return patient;
	}

	public void setPatient(PatientTO patient) {
		this.patient = patient;
	}

	public FamilyDoctorTO getFamilyDoctor() {
		return familyDoctor;
	}

	public void setFamilyDoctor(FamilyDoctorTO familyDoctor) {
		this.familyDoctor = familyDoctor;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public boolean isReadOnly() {
		switch (this.userType) {
		case ADMINISTRATOR:
		case PATIENT:
			// Si no tiene resultado entonces es editable.
			return (this.result != null && this.result.trim().equals("") == false);
		case FAMILY_DOCTOR:
		case SPECIALIST_DOCTOR:
		default:
			// Para los medicos siempres es de solo lectura (el especialista no pdrá ni ver la página, se incluye pro completitud.
			return true;
		}
	}

	// Un médico de familia siempre puede editar el resultado de una visita si la visita sucedió en el pasado, o está programada para el día de hoy
	public boolean isResultReadOnly() {
		if (this.userType == UserType.FAMILY_DOCTOR)
			// Si la visita sucede en el futuro (a partir de mañana) el resultado no es editable.
			if (this.date.isAfter(LocalDate.now()))
				return true;
			else
				return false;
		else
			return true;
	}

	public String getFromPage() {
		return fromPage;
	}

	public void setFromPage(String fromPage) {
		this.fromPage = fromPage;
	}

}
