package com.agilex.healthcare.schedulingmanager.datalayer;

import com.agilex.healthcare.mobilehealthplatform.domain.PatientData;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.List;

public class SimpleEntityManager<T extends PersistenceObject> {

	protected final EntityManager entityManager;
	private String baseQuery;

	public SimpleEntityManager(String baseQuery, EntityManager entityManager) {
		this(entityManager);
		this.baseQuery = baseQuery;
	}

	public SimpleEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	public List<T> get(Class<T> returnType) {
		TypedQuery<T> query = entityManager.createQuery(baseQuery, returnType);

		return query.getResultList();
	}

	public List<T> get(JpaFilter filter, Class<T> returnType) {

		TypedQuery<T> query = entityManager.createQuery(filter.createFilterQueryStr(baseQuery), returnType);

		filter.addFilterParameters(query);

		return query.getResultList();
	}

	public List<T> get(String patientId, JpaFilter filter, Class<T> returnType) {

		TypedQuery<T> query = entityManager.createQuery(filter.createFilterQueryStr(baseQuery), returnType);

		addParameter(query, "patientId", patientId);
		filter.addFilterParameters(query);

		return query.getResultList();
	}

	public List<T> get(String eventId, Class<T> returnType) {
		TypedQuery<T> query = entityManager.createQuery(baseQuery, returnType);
		addParameter(query, "id", eventId);

		return query.getResultList();
	}

	public List<T> get(String patientId, String eventId, Class<T> returnType) {
		TypedQuery<T> query = entityManager.createQuery(baseQuery, returnType);
		addParameter(query, "id", eventId);
		addParameter(query, "patientId", patientId);

		return query.getResultList();
	}

	private void addParameter(TypedQuery<T> query, String field, String value) {
		query.setParameter(field, value);
	}

	public T save(T po) {
    	ValidPo<T> validPo = new ValidPo<T>(entityManager,po);
     	if (validPo.isOk()) {
            return entityManager.merge(po);
    	}
    	return null;
	}

	public void delete(PatientData patientData, Class<T> returnType) {
		PersistenceObject po = entityManager.find(returnType, patientData.getUniqueId());
		if (computeOk(po, patientData)) {
			entityManager.remove(po);
		}
	}

	private boolean computeOk(PersistenceObject po, PatientData patientData) {
		try {
			return exists(po) && po.getUserId().equalsIgnoreCase(patientData.getPatientId());
		} catch (NullPointerException e) {
			return true;
		}
	}

	private boolean exists(PersistenceObject po) {
		return po != null && po.getId() != null;
	}
}