package managedbean.visit;

import java.io.IOException;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;
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 org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

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

@Named("PatientVisitList")
@ViewScoped
public class PatientVisitListMBean extends ManagedBeanBase implements Serializable {

	private static final long serialVersionUID = 1L;

	private PatientTO patient;

	private Integer patientId;
	private LazyDataModel<VisitTO> lazyDataModelVisitList;
	private LocalDate selectedDate;
	private String lastUIQuery;
	private List<PatientTO> patientList;

	public PatientVisitListMBean() {
	}

	@PostConstruct
	public void init() {
		this.lastUIQuery = "";

		// Si el usuario es un paciente listamos las visitas de ese paciente, si es admnistrador listamos todas.
		switch (SessionUtils.getUserType()) {
		case ADMINISTRATOR:
			this.patientId = null;
			this.patient = null;
			this.selectedDate = LocalDate.now();

			this.patientList = this.getRemoteManagerCommon().listPatientsPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
			break;
		case PATIENT:
			this.patientId = Integer.valueOf(SessionUtils.getUserId());
			this.patient = this.getRemoteManagerCommon().findPatientById(patientId);
			this.selectedDate = null;
			break;
		case FAMILY_DOCTOR:
		case SPECIALIST_DOCTOR:
			this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Acesso denegado", "Su perfil de usuario no está autorizado acceder a esta página.");
			return;
		}

		this.lazyDataModelVisitList = new LazyDataModel<VisitTO>() {
			private static final long serialVersionUID = 1L;

			@Override
			public List<VisitTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
				if (patient != null)
					patientId = patient.getId();
				else
					patientId = null;

				Long totalRowCount = getRemoteManagerVisit().getVisitsCount(patientId, selectedDate);
				this.setRowCount(totalRowCount.intValue());

				return getRemoteManagerVisit().listVisitsPaged(patientId, selectedDate, (first / pageSize), pageSize);
			}
		};
	}

	public List<PatientTO> completePatient(String query) {
		if (query != null && query.equals(this.lastUIQuery) == false) {
			this.lastUIQuery = query;
			// Recuperamos las 200 primeras coincidencias
			this.patientList = this.getRemoteManagerCommon().listPatientsFiltered(query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
		}
		return this.patientList;
	}

	public List<PatientTO> getPatientList() {
		return patientList;
	}

	public void removeVisit(Integer visitId) throws IOException {
		if (SessionUtils.getUserType() == UserType.PATIENT) {
			this.getRemoteManagerVisit().removeVisit(visitId);
			this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Visita eliminada", String.format("La visita con Id: %d se ha eliminado correctamente", visitId));
		} else
			this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Error de autorización", "Su perfil de usuario no tiene permisos para eliminar una visita.");
	}

	public void editVisit(Integer visitId) throws IOException {
		FacesContext ctx = FacesContext.getCurrentInstance();
		ctx.getExternalContext().redirect(String.format("UpdateVisit.xhtml?id=%d&fromPage=%s", visitId, ctx.getViewRoot().getViewId()));
	}

	public LazyDataModel<VisitTO> getLazyDataModelVisitList() {
		return lazyDataModelVisitList;
	}

	public void showData() {
	}

	public LocalDate getSelectedDate() {
		return selectedDate;
	}

	public void setSelectedDate(LocalDate selectedDate) {
		this.selectedDate = selectedDate;
	}

	public PatientTO getPatient() {
		return patient;
	}

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

	public boolean isAdmin() {
		return SessionUtils.getUserType() == UserType.ADMINISTRATOR;
	}
}
