package managedbean.profile;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Properties;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.resource.NotSupportedException;

import org.primefaces.PrimeFaces;

import TO.FamilyDoctorTO;
import TO.MedicalSpecialtyTO;
import TO.PatientTO;
import TO.PrimaryHealthCareCenterTO;
import TO.SpecialistDoctorTO;
import ejb.systemAdmin.SystemAdminFacadeRemote;
import managedbean.common.UserType;
import managedbean.common.ValidationUtils;

/**
 * ManagedBEan que gestiona el registro de usuarios: Usuarios de tipo "Paciente"
 * Usuarios de tipo "Médico de Familia" usuarios de tipo "Médico especialista"
 * 
 * @author Marcos García Núñez (mgarcianun@uoc.edu)
 *
 */
@Named("registerUser")
@ViewScoped
public class RegisterUserMBean extends ProfileMBeanBase implements Serializable {

	private static final long serialVersionUID = 1L;

	private Integer id;
	private String nif;
	private String name;
	private String surname;
	private String password;
	private String passwordRepeat;
	private String email;
	// private HashMap<String, String> userTypes;
	private List<UserType> userTypes;
	private String userType;
	private PrimaryHealthCareCenterTO primaryHealthCareCenter;
	private MedicalSpecialtyTO medicalSpecialty;
	private Collection<MedicalSpecialtyTO> medicalSpecialitiesList;
	private Collection<PrimaryHealthCareCenterTO> primaryHealthCareCentersList;

	/**
	 * Constructor. Inicializa la conexión con el EJB Remoto
	 * 
	 * @throws Exception
	 */
	public RegisterUserMBean() throws Exception {
		super.initializeProfileFacadeRemote();
	}

	@PostConstruct
	public void init() {
		this.userTypes = new ArrayList<UserType>();
		this.userTypes.add(UserType.PATIENT);
		this.userTypes.add(UserType.FAMILY_DOCTOR);
		this.userTypes.add(UserType.SPECIALIST_DOCTOR);

		this.userType = UserType.PATIENT.name();

		Properties props = System.getProperties();
		Context ctx;
		try {
			ctx = new InitialContext(props);
			SystemAdminFacadeRemote rman = (SystemAdminFacadeRemote) ctx.lookup("java:app/MyHealth.jar/SystemAdminFacadeBean!ejb.systemAdmin.SystemAdminFacadeRemote");

			this.medicalSpecialitiesList = rman.listAllMedicalSpecialities();
			this.primaryHealthCareCentersList = rman.listAllCAPs();
		} catch (NamingException e) {
			this.manageException(e);
		}
	}

	public List<UserType> getUserTypes() {
		return userTypes;
	}

	public void onUserTypeChange() {
		switch (UserType.valueOf(this.userType)) {
		case SPECIALIST_DOCTOR:
			try {
				PrimeFaces.current().ajax().addCallbackParam("specs", true);
			} catch (Exception e) {
				this.manageException(e);
			}
			break;
		case FAMILY_DOCTOR:
			try {
				PrimeFaces.current().ajax().addCallbackParam("caps", true);
			} catch (Exception e) {
				this.manageException(e);
			}
			break;
		case ADMINISTRADOR:
		case PATIENT:
			PrimeFaces.current().ajax().addCallbackParam("pats", true);
			break;
		}
	}

	public Collection<MedicalSpecialtyTO> getMedicalSpecialtiesList() {
		return medicalSpecialitiesList;
	}

//	public void setMedicalSpecialtiesList(Collection<MedicalSpecialtyTO> list) {
//		medicalSpecialitiesList = list;
//	}

	public Collection<PrimaryHealthCareCenterTO> getPhcList() {
		return primaryHealthCareCentersList;
	}

//	public void setPhcList(Collection<PrimaryHealthCareCenterTO> list) {
//		primaryHealthCareCentersList = list;
//	}

	public boolean isPatient() {
		return (UserType.valueOf(this.userType) == UserType.PATIENT);
	}

	public boolean isFamilyDoctor() {
		return (UserType.valueOf(this.userType) == UserType.FAMILY_DOCTOR);
	}

	public boolean isSpecialistDoctor() {
		return (UserType.valueOf(this.userType) == UserType.SPECIALIST_DOCTOR);
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getSurname() {
		return surname;
	}

	public void setSurname(String surname) {
		this.surname = surname;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getNif() {
		return nif;
	}

	public void setNif(String nif) {
		this.nif = nif;
	}

	public Integer getId() {
		return id;
	}

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

	public void addNewUser() {
		int error = 0;

		if (this.isFamilyDoctor() && this.primaryHealthCareCenter == null) {
			this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Centro de atención primaria no seleccionado", "Por favor, especifique un centro de atención primaria.");
			error++;
		}
		if (this.isSpecialistDoctor() && this.medicalSpecialty == null) {
			this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Especialidad médica no seleccionada", "Por favor, especifique una especialidad médica.");
			error++;
		}
		if (ValidationUtils.isValid(nif) == false) {
			this.addFacesMessage(FacesMessage.SEVERITY_WARN, "El NIF indicado no es válido", "Por favor, especifique un NIF válido.");
			error++;
		}

		if (error == 0) {
			try {
				switch (UserType.valueOf(this.userType)) {
				case PATIENT:
					PatientTO pat = this.remoteManager.registerPatient(id, nif, name, surname, password, email);

					break;
				case FAMILY_DOCTOR:
					FamilyDoctorTO fd = this.remoteManager.registerFamilyDoctor1(id, nif, name, surname, password, email, this.primaryHealthCareCenter);

					break;
				case SPECIALIST_DOCTOR:
					SpecialistDoctorTO sd = this.remoteManager.registerSpecialistDoctor(id, nif, name, surname, password, email, this.medicalSpecialty);

					break;
				case ADMINISTRADOR:
					throw new NotSupportedException("No se soporta el registro directo de administradores.");
				}

				this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Alta realizada",
						"El usuario " + name + " " + surname + " se ha registrado correctamente. Por favor, comprueba su correo electrónico para verificar su cuenta.");
			} catch (Exception e) {
				this.manageException(e);
			}
		}

		// FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	public String getPasswordRepeat() {
		return passwordRepeat;
	}

	public void setPasswordRepeat(String passwordRepeat) {
		this.passwordRepeat = passwordRepeat;
	}

	public String getUserType() {
		return userType;
	}

	public void setUserType(String userType) {
		this.userType = userType;
	}

	public MedicalSpecialtyTO getMedicalSpecialty() {
		return medicalSpecialty;
	}

	public void setMedicalSpecialty(MedicalSpecialtyTO medicalSpecialty) {
		this.medicalSpecialty = medicalSpecialty;
	}

	public PrimaryHealthCareCenterTO getPrimaryHealthCareCenter() {
		return primaryHealthCareCenter;
	}

	public void setPrimaryHealthCareCenter(PrimaryHealthCareCenterTO primaryHealthCareCenter) {
		this.primaryHealthCareCenter = primaryHealthCareCenter;
	}

}
