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.Query;

import org.springframework.stereotype.Repository;

import com.jasamedika.medifirst2000.dao.custom.PelayananPasienDaoCustom;
import com.jasamedika.medifirst2000.dao.custom.base.impl.CoreDaoImpl;
import com.jasamedika.medifirst2000.entities.PelayananPasien;
import com.jasamedika.medifirst2000.util.CommonUtil;

@Repository
public class PelayananPasienDaoCustomImpl extends CoreDaoImpl<PelayananPasien> implements PelayananPasienDaoCustom{
	
	public PelayananPasienDaoCustomImpl() {
		super(PelayananPasien.class);
	}

	@Override
	public Map<String, Object> getHistoryPelayanan(){
		Map<String, Object> result = new HashMap<>();
		try{
			List<Map<String, Object>> listData = new ArrayList<>();
			Query query = em.createQuery(""
					+ "select NEW Map ("
					+ "a.noRec as pelayananPasienNoRec, "
					+ "b.id as kelasId, "
					+ "b.namaKelas as namaKelas, "
					+ "c.id as produkId, "
					+ "c.namaProduk as namaProduk, "
					+ "d.noRec as registrasiNoRec) "
					+ "from PelayananPasien a "
					+ "left join a.kelas b "
					+ "left join a.produk c "
					+ "left join a.pasienDaftar d ");
			List<Map<String, Object>> listQuery = query.getResultList();
			for(Map<String, Object> data : listQuery){
				Map<String, Object> PelayananPasien = new HashMap<>();
				PelayananPasien.put("noRec", data.get("pelayananPasienNoRec"));
				
				Map<String, Object> kelas = new HashMap<>();
				kelas.put("id", data.get("kelasId"));
				kelas.put("namaKelas", data.get("namaKelas"));
				PelayananPasien.put("kelas", kelas);
				
				Map<String, Object> produk = new HashMap<>();	
				produk.put("id", data.get("produkId"));
				produk.put("namaProduk", data.get("namaProduk"));
				PelayananPasien.put("produk", produk);
				
				Map<String, Object> pasienDaftar = new HashMap<>();
				pasienDaftar.put("noRec", data.get("registrasiNoRec"));
				PelayananPasien.put("pasienDaftar", pasienDaftar);
				
				try{
					Query query2 = em.createQuery(""
							+ "select NEW Map ("
							+ "b.id as jenisPetugasPeId, "
							+ "b.jenisPetugasPe as jenisPetugasPe, "
							+ "c.id as pegawaiId, "
							+ "c.namaLengkap as namaLengkap, "
							+ "d.id as produkId, "
							+ "d.namaProduk as namaProduk, "
							+ "e.id as ruanganId, "
							+ "e.namaRuangan as namaRuangan, "
							+ "f.id as asalProdukId, "
							+ "f.asalProduk as asalProduk) "
							+ "from PelayananPasienPetugas a "
							+ "left join a.kdjenispetugaspe b "
							+ "left join a.kdpegawai c "
							+ "left join a.kdproduk d "
							+ "left join a.kdruangan e "
							+ "left join a.kdasalproduk f "
							+ "where a.noRec=:noRec");
							query2.setParameter("noRec", 
						    (String)data.get("pelayananPasienNoRec"));
							List<Map<String, Object>> listQuery2 = query2.getResultList();
							
						List<Map<String, Object>> petugas = new ArrayList<>();	
						for(Map<String, Object> data2 : listQuery2){
							Map<String, Object> petugasMap = new HashMap<>();
							
							Map<String, Object> jenisPetugasPe = new HashMap<>();
							jenisPetugasPe.put("id", data2.get("jenisPetugasPeId"));
							jenisPetugasPe.put("jenisPetugasPe", data2.get("jenisPetugasPe"));
							petugasMap.put("objectJenisPetugasPe", jenisPetugasPe);
							
							Map<String, Object> objectPegawai = new HashMap<>();
							objectPegawai.put("id", data2.get("pegawaiId"));
							objectPegawai.put("namaLengkap", data2.get("namaLengkap"));
							petugasMap.put("objectPegawai", objectPegawai);
							
							Map<String, Object> objectProduk = new HashMap<>();
							objectProduk.put("id", data2.get("produkId"));
							objectProduk.put("namaProduk", data2.get("namaProduk"));
							petugasMap.put("objectProduk", objectProduk);
							
							Map<String, Object> objectRuangan = new HashMap<>();
							objectRuangan.put("id", data2.get("ruanganId"));
							objectRuangan.put("namaRuangan", data2.get("namaRuangan"));
							petugasMap.put("objectRuangan", objectRuangan);
							
							Map<String, Object> objectAsalProduk = new HashMap<>();
							objectAsalProduk.put("id", data2.get("asalProdukId"));
							objectAsalProduk.put("asalProduk", data2.get("asalProduk"));
							petugasMap.put("objectAsalProduk", objectAsalProduk);
							
							if(CommonUtil.isNotNullOrEmpty(petugasMap)){
								petugas.add(petugasMap);
							}
						}
						if(CommonUtil.isNotNullOrEmpty(petugas)){
							PelayananPasien.put("petugas", petugas);
						}
				}catch(Exception ex){
					ex.printStackTrace();
				}
				if(CommonUtil.isNotNullOrEmpty(PelayananPasien)){
					listData.add(PelayananPasien);
				}
			}
			if(CommonUtil.isNotNullOrEmpty(listData)){
				result.put("listData", listData);
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}
		return result; 
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Map<String, Object>> getFeeForService(Integer page, Integer limit, 
			Integer pegawaiId, String fromDate, String toDate) {
		List<Map<String, Object>> serviceList = new ArrayList<>();
		
		// ambil data pelayanan pasien per tipe pegawai = dokter
		StringBuffer hql = new StringBuffer();
		hql.append("select new Map("
				+ "p.id as idPegawai, "
				+ "p.nipPns as nipPegawai, "
				+ "p.namaLengkap as namaDokter, "
				+ "pr.namaProduk as namaProduk, "
				+ "pp.jumlah as jmlProduk, "
				+ "pp.hargaSatuan as hargaProduk, "
				+ "pp.hargaJual as hargJual, "
				+ "pp.hargaDiscount as hargaDiskon, "
				+ "pp.tglPelayanan as tglPelayanan) "
				+ "from PelayananPasien pp "
				+ "join pp.produk pr "
				+ "join pp.pasienDaftar pd "
				+ "join pd.pegawai p "
				+ "join p.jenisPegawai jp "
				+ "where jp.id=1 ");
		
		if (CommonUtil.isNotNullOrEmpty(pegawaiId)) {
			hql.append("and p.id = :pegawaiId ");
		} 
		hql.append("and p.id in (");
		
		// ambil data dokter dari jadwal dokter
		StringBuffer employeeQuery = new StringBuffer();
		employeeQuery.append("select distinct(jpd.id) "
				+ "from JadwalDokter jdd "
				+ "join jdd.dokter jpd "
				+ "join jpd.jenisPegawai jjpd "
				+ "join jdd.jadwalPraktek jjppd "
				+ "where jjpd.id=1 ");
		if (CommonUtil.isNotNullOrEmpty(pegawaiId)) {
			employeeQuery.append("and jpd.id=:pegawaiId ");
		}
		if (CommonUtil.isNotNullOrEmpty(fromDate) && CommonUtil.isNullOrEmpty(toDate)) {
			employeeQuery.append("and jdd.tanggalJadwal >= date(:fromDate) ");
		} else if (CommonUtil.isNotNullOrEmpty(fromDate) && CommonUtil.isNotNullOrEmpty(toDate)) {
			employeeQuery.append("and jdd.tanggalJadwal between date(:fromDate) and date(:toDate) ");
		} else if (CommonUtil.isNullOrEmpty(fromDate) && CommonUtil.isNotNullOrEmpty(toDate)) {
			employeeQuery.append("and jdd.tanggalJadwal <= date(:toDate) ");
		}
		
		hql.append(employeeQuery);
		hql.append(") and pp.tglPelayanan not in (");
		
		// ambil data jadwal dokter
		StringBuffer scheduleQuery = new StringBuffer();
		scheduleQuery.append("select jdd.tanggalJadwal "
				+ "from JadwalDokter jdd "
				+ "join jdd.dokter jpd "
				+ "join jpd.jenisPegawai jjpd "
				+ "where jjpd.id=1 ");
		if (CommonUtil.isNotNullOrEmpty(pegawaiId)) {
			scheduleQuery.append("and jpd.id=:pegawaiId ");
		}
		if (CommonUtil.isNotNullOrEmpty(fromDate) && CommonUtil.isNullOrEmpty(toDate)) {
			employeeQuery.append("and jdd.tanggalJadwal >= date(:fromDate) ");
		} else if (CommonUtil.isNotNullOrEmpty(fromDate) && CommonUtil.isNotNullOrEmpty(toDate)) {
			employeeQuery.append("and jdd.tanggalJadwal between date(:fromDate) and date(:toDate) ");
		} else if (CommonUtil.isNullOrEmpty(fromDate) && CommonUtil.isNotNullOrEmpty(toDate)) {
			employeeQuery.append("and jdd.tanggalJadwal <= date(:toDate) ");
		}
		
		hql.append(scheduleQuery + ") ");
		
		if (CommonUtil.isNotNullOrEmpty(fromDate) && CommonUtil.isNullOrEmpty(toDate)) {
			hql.append("and pp.tglPelayanan >= date(:fromDate) ");
		} else if (CommonUtil.isNotNullOrEmpty(fromDate) && CommonUtil.isNotNullOrEmpty(toDate)) {
			hql.append("and pp.tglPelayanan between date(:fromDate) and date(:toDate) ");
		} else if (CommonUtil.isNullOrEmpty(fromDate) && CommonUtil.isNotNullOrEmpty(toDate)) {
			hql.append("and pp.tglPelayanan <= date(:toDate) ");
		}
		
		
		// set all non-null parameters 
		Query q = em.createQuery(hql.toString());
		
		if (CommonUtil.isNotNullOrEmpty(pegawaiId)) {
			q.setParameter("pegawaiId", pegawaiId);
		}
		
		if (CommonUtil.isNotNullOrEmpty(fromDate) && CommonUtil.isNullOrEmpty(toDate)) {
			q.setParameter("fromDate", "'" + fromDate + "'");
		} else if (CommonUtil.isNotNullOrEmpty(fromDate) && CommonUtil.isNotNullOrEmpty(toDate)) {
			q.setParameter("fromDate", "'" + fromDate + "'");
			q.setParameter("toDate", "'" + toDate + "'");
		} else if (CommonUtil.isNullOrEmpty(fromDate) && CommonUtil.isNotNullOrEmpty(toDate)) {
			q.setParameter("toDate", "'" + toDate + "'");
		}
		
		q.setFirstResult(page);
		q.setMaxResults(limit);
		
		serviceList = q.getResultList();
		
		return serviceList;
	}
}
