package com.jasamedika.medifirst2000.dao.custom.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Repository;

import com.jasamedika.medifirst2000.dao.custom.ReportPelayananDaoCustom;
import com.jasamedika.medifirst2000.util.CommonUtil;

@Repository
public class ReportPelayananDaoCustomImpl implements ReportPelayananDaoCustom {

	@PersistenceContext
	private EntityManager em;
	
	@Override
	public Map<String, Object> getReportGenerik(String className, String fields[], String filters[]){
		Map<String, Object> result = new HashMap<>();

		Map<String, Object> mapData = new HashMap<>();
		try{
			if(CommonUtil.isNotNullOrEmpty(className)){
				mapData.put("className", (Object) className);
			}
			//------------------------------------------------------
			List<Map<String, Object>> listField = new ArrayList<>();
			for(int i=0; i<fields.length; i++){
				Map<String, Object> fieldMap = new HashMap<>();
				mapData.put("field", fields[i]);
				listField.add(fieldMap);
			}
			if(CommonUtil.isNotNullOrEmpty(listField)){
				mapData.put("listField", listField);
			}
			//------------------------------------------------------
			List<Map<String, Object>> listFilter = new ArrayList<>();
			for(int i=0; i<filters.length; i++){
				Map<String, Object> filterdMap = new HashMap<>();
				filterdMap.put("field", (Object) filters[i]);
				listFilter.add(filterdMap);
			}
			if(CommonUtil.isNotNullOrEmpty(listFilter)){
				mapData.put("listFilter", (Object) listFilter);
			}
		} catch(Exception ex){
			ex.printStackTrace();
		}
		
		try{
			Class<?> act = Class.forName("com.jasamedika.medifirst2000.entities."+(String)mapData.get("className"));
			StringBuffer buffer = new StringBuffer();
			//-----------------------------------------------------------------------------------
			buffer.append("select NEW Map( ");
			//-----------------------------------------------------------------------------------
			for(Map<String, Object> value : (List<Map<String, Object>>)mapData.get("listField")){
				buffer.append(value.get("field")+" as "+value.get("field")+",");
			}
			//-----------------------------------------------------------------------------------
			StringUtils.removeEnd(buffer.toString(), ",");
			//-----------------------------------------------------------------------------------
			buffer.append(") from "+act.getName());
			for(Map<String, Object> value : (List<Map<String, Object>>)mapData.get("listFilter")){
				buffer.append(value.get("filter")+" and");
			}
			//-----------------------------------------------------------------------------------
			StringUtils.removeEnd(buffer.toString(), "and");
			//-----------------------------------------------------------------------------------
			Query query = em.createQuery(buffer.toString());
			result = (Map<String, Object>) query.getSingleResult();
		} catch(Exception ex){
			ex.printStackTrace();
		}
		return result;
	}
		
	@Override
	public List<Map<String, Object>> getPelayananPasien(String startDate, String endDate, Integer idproduk,
			List<Integer> idDepartemen, Integer idRuangan, Integer jenisPasien) {
		
		StringBuffer buffer = new StringBuffer();
		buffer.append("select new map ("
				+ "produk.namaProduk as namaProduk, "
				+ "produk.id as produkId, "
				+ "count(produk.namaProduk) as count, "
				+ "pelayananPasien.hargaSatuan as harga, "
				+ "detail.id as detailId, "
				+ "jenisProduk.id as idJenisProduk, "
				+ "pasien.namaPasien as namaPasien, "
				+ "pasien.noCm as noCm, "
				+ "pasienDaftar.noRegistrasi as noRegistrasi, "
				+ "to_char(pasienDaftar.tglRegistrasi, 'dd-MM-yyyy HH:mm') as tglRegistrasi, "
				+ "pasienDaftar.tglRegistrasi as tanggal, "
				+ "ruangan.namaRuangan as namaRuangan, "
				+ "kelompokPasien.kelompokPasien as kelompokPasien) "
				+ "from PelayananPasien pelayananPasien "
				+ "left join pelayananPasien.produk produk "
				+ "left join produk.detailJenisProduk detail "
				+ "left join detail.jenisProduk jenisProduk "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join antrian.pasienDaftar pasienDaftar "
				+ "left join pasienDaftar.kelompokPasien kelompokPasien "
				+ "left join pasienDaftar.pasien pasien "
				+ "left join pasienDaftar.ruangan ruangan "
				+ "left join ruangan.departemen departemen "
				+ "where pelayananPasien.noRec is not null and jenisProduk.id!= 97 ");
		
		if (CommonUtil.isNotNullOrEmpty(idproduk)) {
			buffer.append("and produk.id = :idproduk ");
		}
		if (CommonUtil.isNotNullOrEmpty(startDate) && CommonUtil.isNotNullOrEmpty(endDate)) {
			buffer.append("and to_char(pasienDaftar.tglRegistrasi,'yyyy-MM-dd') between :startDate and :endDate  ");
		}
		if (CommonUtil.isNotNullOrEmpty(idDepartemen)) {
			buffer.append("and departemen.id in (:idDepartemen) ");
		}
		if (CommonUtil.isNotNullOrEmpty(idRuangan)) {
			buffer.append("and ruangan.id =:idRuangan ");
		}		
		if (CommonUtil.isNotNullOrEmpty(jenisPasien)) {
			buffer.append("and kelompokPasien.id =:jenisPasien ");
		}			
		buffer.append("group by produk.namaProduk,produk.id,pelayananPasien.hargaSatuan,detail.id, "+
				  "jenisProduk.id, pasien.namaPasien,pasien.noCm,pasienDaftar.noRegistrasi, "+
				  "to_char(pasienDaftar.tglRegistrasi, 'dd-MM-yyyy HH:mm'),ruangan.namaRuangan, "+
				  "kelompokPasien.kelompokPasien,pasienDaftar.tglRegistrasi "+
				  "order by pasienDaftar.noRegistrasi");	
		
		Query query = em.createQuery(buffer.toString());
		
		if (CommonUtil.isNotNullOrEmpty(idRuangan)) {
			query.setParameter("idRuangan", idRuangan);
		}
		if (CommonUtil.isNotNullOrEmpty(idproduk)) {
			query.setParameter("idproduk", idproduk);
		}
		if (CommonUtil.isNotNullOrEmpty(startDate) && CommonUtil.isNotNullOrEmpty(endDate)) {
			query.setParameter("startDate", startDate);
			query.setParameter("endDate", endDate);
		}
		if (CommonUtil.isNotNullOrEmpty(idDepartemen)) {
			query.setParameter("idDepartemen", idDepartemen);
		}
		if (CommonUtil.isNotNullOrEmpty(jenisPasien)) {
			query.setParameter("jenisPasien", jenisPasien);
		}
		return (List<Map<String, Object>>) query.getResultList();
	}

	@Override
	public List<Map<String, Object>> getPelayananPasienByDokter(String startDate, String endDate, Integer idproduk,
			List<Integer> idDepartemen, Integer idRuangan, Integer jenisPasien, Integer dokter) {
		StringBuffer buffer = new StringBuffer();
		buffer.append("select new map (produk.namaProduk as namaProduk, produk.id as produkId, "+
			 "count(produk.namaProduk) as count, "+
			 "pelayananPasien.hargaSatuan as harga, "+
			 "detail.id as detailId, "+
			 "jenisProduk.id as idJenisProduk, "+
			 "pasien.namaPasien as namaPasien, "+
			 "pasien.noCm as noCm, "+
			 "pasienDaftar.noRegistrasi as noRegistrasi, "+
			 "to_char(pasienDaftar.tglRegistrasi, 'dd-MM-yyyy HH:mm') as tglRegistrasi, "+
			 "pasienDaftar.tglRegistrasi as tanggal, "+
			 "ruangan.namaRuangan as namaRuangan, "+
			 "dokter.id as idDokter, "+
			 "kelompokPasien.kelompokPasien as kelompokPasien, dokter.namaLengkap as dokter) "+
			 "from PelayananPasienPetugas pelayananPasienPetugas "+
			 "left join pelayananPasienPetugas.kdpegawai dokter "+
			 "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "+
			  "left join pelayananPasien.produk produk  "+
			  "left join produk.detailJenisProduk detail "+
			  "left join detail.jenisProduk jenisProduk "+
			  "left join pelayananPasien.pasienDaftar antrian "+
			  "left join antrian.pasienDaftar pasienDaftar "+
			  "left join pasienDaftar.kelompokPasien kelompokPasien "+
			  "left join pasienDaftar.pasien pasien "+
			 "left join pasienDaftar.ruangan ruangan "+
			 "left join ruangan.departemen departemen "+
			  "where pelayananPasien.noRec is not null and jenisProduk.id!= 97 ");
		
		if (CommonUtil.isNotNullOrEmpty(idproduk)) {
			buffer.append("and produk.id != :idproduk ");
		}
		if (CommonUtil.isNotNullOrEmpty(startDate) && CommonUtil.isNotNullOrEmpty(endDate)) {
			buffer.append("and to_char(pasienDaftar.tglRegistrasi,'yyyy-MM-dd') between :startDate and :endDate  ");
		}
		if (CommonUtil.isNotNullOrEmpty(idDepartemen)) {
			buffer.append("and departemen.id in (:idDepartemen) ");
		}
		if (CommonUtil.isNotNullOrEmpty(idRuangan)) {
			buffer.append("and ruangan.id =:idRuangan ");
		}		
		if (CommonUtil.isNotNullOrEmpty(jenisPasien)) {
			buffer.append("and kelompokPasien.id =:jenisPasien ");
		}
		if (CommonUtil.isNotNullOrEmpty(dokter)) {
			buffer.append("and dokter.id =:dokter ");
		}
		buffer.append("group by produk.namaProduk,produk.id,pelayananPasien.hargaSatuan,detail.id, "+
				  "jenisProduk.id, pasien.namaPasien,pasien.noCm,pasienDaftar.noRegistrasi, "+
				  "to_char(pasienDaftar.tglRegistrasi, 'dd-MM-yyyy HH:mm'),ruangan.namaRuangan, "+
				  "kelompokPasien.kelompokPasien,dokter.namaLengkap,dokter.id,pasienDaftar.tglRegistrasi "+
				  "order by dokter.id ");		

		Query query = em.createQuery(buffer.toString());
		
		if (CommonUtil.isNotNullOrEmpty(idRuangan)) {
			query.setParameter("idRuangan", idRuangan);
		}
		if (CommonUtil.isNotNullOrEmpty(idproduk)) {
			query.setParameter("idproduk", idproduk);
		}
		if (CommonUtil.isNotNullOrEmpty(startDate) && CommonUtil.isNotNullOrEmpty(endDate)) {
			query.setParameter("startDate", startDate);
			query.setParameter("endDate", endDate);
		}
		if (CommonUtil.isNotNullOrEmpty(idDepartemen)) {
			query.setParameter("idDepartemen", idDepartemen);
		}
		if (CommonUtil.isNotNullOrEmpty(jenisPasien)) {
			query.setParameter("jenisPasien", jenisPasien);
		}
		if (CommonUtil.isNotNullOrEmpty(dokter)) {
			query.setParameter("dokter", dokter);
		}
		return (List<Map<String, Object>>)query.getResultList();
	}

	@Override
	public List<Map<String, Object>> getPenerimaanKasirByDokter(String startDate, String endDate, Integer idproduk,
			Integer idDepartemen, Integer idRuangan, Integer jenisPasien, Integer dokter,String noRec) {
		StringBuffer buffer = new StringBuffer();
		buffer.append("select new map "
				+ "(produk.namaProduk as namaProduk, "
				+ "produk.id as produkId, "
				+ "pelayananPasien.hargaSatuan as harga, " 
				+ "detail.id as detailId, " 
				+ "jenisProduk.id as idJenisProduk,  "
				+ "pasien.namaPasien as namaPasien, " 
				+ "pasien.noCm as noCm,  "
				+ "pasienDaftar.noRegistrasi as noRegistrasi, "
  				+ "to_char(pasienDaftar.tglRegistrasi, 'dd-MM-yyyy HH:mm') as tglRegistrasi,"
  				+ "ruangan.namaRuangan as namaRuangan,  "
  				+ "dokter.id as idDokter, "
  				+ "kelompokPasien.kelompokPasien as kelompokPasien, "
  				+ "dokter.namaLengkap as dokter, "
				+ "kasir.namaLengkap as kasir, "
  				+ "jenisProduk.id as idJenisProduk, "
  				+ "pelayananPasien.hargaDiscount as hargaDiscount, "
  				+ "sbm.noRec as noRecSBM) "
  				+ "from PelayananPasienPetugas pelayananPasienPetugas "
  				+ "left join pelayananPasienPetugas.kdpegawai dokter  "
  				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien  "
  				+ "left join pelayananPasien.strukPelayanan strukPelayanan "
  				+ "left join strukPelayanan.nosbmlast sbm "
  				+ "left join sbm.kdpegawaipenerima pegawaiPenerima "
  				+ "left join pegawaiPenerima.pegawai kasir "
  				+ "left join pelayananPasien.produk produk  "
  				+ "left join produk.detailJenisProduk detail  "
  				+ "left join detail.jenisProduk jenisProduk "
  				+ "left join pelayananPasien.pasienDaftar antrian  "
  				+ "left join antrian.pasienDaftar pasienDaftar  "
   				+ "left join pasienDaftar.kelompokPasien kelompokPasien left join pasienDaftar.pasien pasien  "
    			+ "left join pasienDaftar.ruangan ruangan left join ruangan.departemen departemen "
				+ "where pelayananPasien.noRec is not null and jenisProduk.id!= 97 ");
		
		if (CommonUtil.isNotNullOrEmpty(idproduk)) {
			buffer.append("and produk.id = :idproduk ");
		}
		if (CommonUtil.isNotNullOrEmpty(startDate) && CommonUtil.isNotNullOrEmpty(endDate)) {
			buffer.append("and to_char(pasienDaftar.tglRegistrasi,'yyyy-MM-dd HH:mm') between :startDate and :endDate  ");
		}
		if (CommonUtil.isNotNullOrEmpty(idDepartemen)) {
			buffer.append("and departemen.id = :idDepartemen ");
		}
		if (CommonUtil.isNotNullOrEmpty(idRuangan)) {
			buffer.append("and ruangan.id =:idRuangan ");
		}		
		if (CommonUtil.isNotNullOrEmpty(jenisPasien)) {
			buffer.append("and kelompokPasien.id =:jenisPasien ");
		}
		if (CommonUtil.isNotNullOrEmpty(dokter)) {
			buffer.append("and dokter.id =:dokter ");
		}
		if (CommonUtil.isNotNullOrEmpty(noRec)) {
			buffer.append("and pasienDaftar.noRec =:noRec ");
		}
		buffer.append(" order by dokter.id,pasienDaftar.noRegistrasi ");		

		Query query = em.createQuery(buffer.toString());
		
		if (CommonUtil.isNotNullOrEmpty(idRuangan)) {
			query.setParameter("idRuangan", idRuangan);
		}
		if (CommonUtil.isNotNullOrEmpty(idproduk)) {
			query.setParameter("idproduk", idproduk);
		}
		if (CommonUtil.isNotNullOrEmpty(startDate) && CommonUtil.isNotNullOrEmpty(endDate)) {
			query.setParameter("startDate", startDate);
			query.setParameter("endDate", endDate);
		}
		if (CommonUtil.isNotNullOrEmpty(idDepartemen)) {
			query.setParameter("idDepartemen", idDepartemen);
		}
		if (CommonUtil.isNotNullOrEmpty(jenisPasien)) {
			query.setParameter("jenisPasien", jenisPasien);
		}
		if (CommonUtil.isNotNullOrEmpty(dokter)) {
			query.setParameter("dokter", dokter);
		}
		if (CommonUtil.isNotNullOrEmpty(noRec)) {
			query.setParameter("noRec", noRec);
		}
		return (List<Map<String, Object>>)query.getResultList();
	}

	@Override
	public List<String> getPasienDaftar(String startDate, String endDate, Integer idproduk,
			Integer idDepartemen, Integer idRuangan, Integer jenisPasien, Integer Dokter) {
		StringBuffer buffer = new StringBuffer();
		buffer.append("select distinct pasienDaftar.noRec as noRec "
  				+ "from PelayananPasienPetugas pelayananPasienPetugas "
  				+ "left join pelayananPasienPetugas.kdpegawai dokter  "
  				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien  "
  				+ "left join pelayananPasien.strukPelayanan strukPelayanan "
  				+ "left join strukPelayanan.nosbmlast sbm "
  				+ "left join sbm.kdpegawaipenerima pegawaiPenerima "
  				+ "left join pegawaiPenerima.pegawai kasir "
  				+ "left join pelayananPasien.produk produk  "
  				+ "left join produk.detailJenisProduk detail  "
  				+ "left join detail.jenisProduk jenisProduk "
  				+ "left join pelayananPasien.pasienDaftar antrian  "
  				+ "left join antrian.pasienDaftar pasienDaftar  "
   				+ "left join pasienDaftar.kelompokPasien kelompokPasien left join pasienDaftar.pasien pasien  "
    			+ "left join pasienDaftar.ruangan ruangan left join ruangan.departemen departemen "
				+ "where pelayananPasien.noRec is not null and jenisProduk.id!= 97 ");
		
		if (CommonUtil.isNotNullOrEmpty(idproduk)) {
			buffer.append("and produk.id != :idproduk ");
		}
		if (CommonUtil.isNotNullOrEmpty(startDate) && CommonUtil.isNotNullOrEmpty(endDate)) {
			buffer.append("and to_char(pasienDaftar.tglRegistrasi,'yyyy-MM-dd HH:mm') between :startDate and :endDate  ");
		}
		if (CommonUtil.isNotNullOrEmpty(idDepartemen)) {
			buffer.append("and departemen.id = :idDepartemen ");
		}
		if (CommonUtil.isNotNullOrEmpty(idRuangan)) {
			buffer.append("and ruangan.id =:idRuangan ");
		}		
		if (CommonUtil.isNotNullOrEmpty(jenisPasien)) {
			buffer.append("and kelompokPasien.id =:jenisPasien ");
		}
		if (CommonUtil.isNotNullOrEmpty(Dokter)) {
			buffer.append("and dokter.id =:dokter ");
		}
		buffer.append(" order by pasienDaftar.noRec ");		

		Query query = em.createQuery(buffer.toString());
		
		if (CommonUtil.isNotNullOrEmpty(idRuangan)) {
			query.setParameter("idRuangan", idRuangan);
		}
		if (CommonUtil.isNotNullOrEmpty(idproduk)) {
			query.setParameter("idproduk", idproduk);
		}
		if (CommonUtil.isNotNullOrEmpty(startDate) && CommonUtil.isNotNullOrEmpty(endDate)) {
			query.setParameter("startDate", startDate);
			query.setParameter("endDate", endDate);
		}
		if (CommonUtil.isNotNullOrEmpty(idDepartemen)) {
			query.setParameter("idDepartemen", idDepartemen);
		}
		if (CommonUtil.isNotNullOrEmpty(jenisPasien)) {
			query.setParameter("jenisPasien", jenisPasien);
		}
		if (CommonUtil.isNotNullOrEmpty(Dokter)) {
			query.setParameter("dokter", Dokter);
		}
		return (List<String>)query.getResultList();
	}
}
