package com.jasamedika.medifirst2000.dao;

import java.util.List;
import java.util.Map;

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import com.jasamedika.medifirst2000.entities.SkoringTindakanMedis;

@Repository("skoringTindakanMedisDao")
public interface SkoringTindakanMedisDao extends PagingAndSortingRepository<SkoringTindakanMedis, String> {

	String strAllEnabled = "select new Map(stm.noRec as noRec," + "stm.statusEnabled as statusEnabled,"
			+ "uk.id as unitKerjaId,uk.name as unitKerja," + "sk.id as kelompokKerjaId,sk.name as kelompokKerja,"
			+ "pr.id as produkId,pr.namaProduk as namaProduk," + "stm.detailProduk as detailProduk,"
			+ "stm.skor as skor," + "stm.statusVerifikasi as isStatusVerifikasi,"
			+ "(case when stm.statusVerifikasi is false then 'Belum Verifikasi' "
			+ "when stm.statusVerifikasi is true then 'Terverifikasi' end) as statusVerifikasi,"
			+ "stm.tanggalMulaiBerlaku as tglMulaiBerlaku," + "stm.tanggalPembaharuanData as tglPembaharuanData) "
			+ "from SkoringTindakanMedis stm " + "inner join stm.produk pr " + "inner join stm.kelompokKerja sk "
			+ "inner join sk.unitKerja uk " + "where stm.statusEnabled is true "
			+ "and to_char(stm.tanggalMulaiBerlaku,'yyyy-MM-dd') <= to_char(now(),'yyyy-MM-dd')";

	String kelompokKerja = " and sk.id in (:listSubunitKerjaId)";

	String produk = " and lower(pr.namaProduk) like %:namaProduk%";

	String detailProduk = " and lower(stm.detailProduk) like %:detailProduk%";

	String statusVerifikasi = " and stm.statusVerifikasi = :isStatusVerifikasi";

	String sortSearch = " order by sk.name asc," + "pr.namaProduk asc," + "stm.detailProduk asc, "
			+ "stm.tanggalMulaiBerlaku desc, stm.tanggalPembaharuanData desc";

	@Query(strAllEnabled + sortSearch)
	List<Map<String, Object>> findAllEnabled();

	@Query(strAllEnabled + kelompokKerja + sortSearch)
	List<Map<String, Object>> findAllEnabledByUnit(@Param("listSubunitKerjaId") List<Integer> listIdKelompokKerja);

	@Query(strAllEnabled + produk + sortSearch)
	List<Map<String, Object>> findAllEnabledByProduk(@Param("namaProduk") String namaProduk);

	@Query(strAllEnabled + detailProduk + sortSearch)
	List<Map<String, Object>> findAllEnabledByDetail(@Param("detailProduk") String detailProduk);

	@Query(strAllEnabled + statusVerifikasi + sortSearch)
	List<Map<String, Object>> findAllEnabledByVerif(@Param("isStatusVerifikasi") Boolean statusVerifikasi);

	@Query(strAllEnabled + kelompokKerja + produk + sortSearch)
	List<Map<String, Object>> findAllEnabledByUnitProduk(@Param("listSubunitKerjaId") List<Integer> listIdKelompokKerja,
			@Param("namaProduk") String namaProduk);

	@Query(strAllEnabled + kelompokKerja + detailProduk + sortSearch)
	List<Map<String, Object>> findAllEnabledByUnitDetail(@Param("listSubunitKerjaId") List<Integer> listIdKelompokKerja,
			@Param("detailProduk") String detailProduk);

	@Query(strAllEnabled + kelompokKerja + statusVerifikasi + sortSearch)
	List<Map<String, Object>> findAllEnabledByUnitVerif(@Param("listSubunitKerjaId") List<Integer> listIdKelompokKerja,
			@Param("isStatusVerifikasi") Boolean statusVerifikasi);

	@Query(strAllEnabled + produk + detailProduk + sortSearch)
	List<Map<String, Object>> findAllEnabledByProdukDetail(@Param("namaProduk") String namaProduk,
			@Param("detailProduk") String detailProduk);

	@Query(strAllEnabled + produk + statusVerifikasi + sortSearch)
	List<Map<String, Object>> findAllEnabledByProdukVerif(@Param("namaProduk") String namaProduk,
			@Param("isStatusVerifikasi") Boolean statusVerifikasi);

	@Query(strAllEnabled + detailProduk + statusVerifikasi + sortSearch)
	List<Map<String, Object>> findAllEnabledByDetailVerif(@Param("detailProduk") String detailProduk,
			@Param("isStatusVerifikasi") Boolean statusVerifikasi);

	@Query(strAllEnabled + kelompokKerja + produk + detailProduk + sortSearch)
	List<Map<String, Object>> findAllEnabledByUnitProdukDetail(
			@Param("listSubunitKerjaId") List<Integer> listIdKelompokKerja, @Param("namaProduk") String namaProduk,
			@Param("detailProduk") String detailProduk);

	@Query(strAllEnabled + kelompokKerja + produk + statusVerifikasi + sortSearch)
	List<Map<String, Object>> findAllEnabledByUnitProdukVerif(
			@Param("listSubunitKerjaId") List<Integer> listIdKelompokKerja, @Param("namaProduk") String namaProduk,
			@Param("isStatusVerifikasi") Boolean statusVerifikasi);

	@Query(strAllEnabled + kelompokKerja + detailProduk + statusVerifikasi + sortSearch)
	List<Map<String, Object>> findAllEnabledByUnitDetailVerif(
			@Param("listSubunitKerjaId") List<Integer> listIdKelompokKerja, @Param("detailProduk") String detailProduk,
			@Param("isStatusVerifikasi") Boolean statusVerifikasi);

	@Query(strAllEnabled + produk + detailProduk + statusVerifikasi + sortSearch)
	List<Map<String, Object>> findAllEnabledByProdukDetailVerif(@Param("namaProduk") String namaProduk,
			@Param("detailProduk") String detailProduk, @Param("isStatusVerifikasi") Boolean statusVerifikasi);

	@Query(strAllEnabled + kelompokKerja + produk + detailProduk + statusVerifikasi + sortSearch)
	List<Map<String, Object>> findAllEnabledByUnitProdukDetailVerif(
			@Param("listSubunitKerjaId") List<Integer> listIdKelompokKerja, @Param("namaProduk") String namaProduk,
			@Param("detailProduk") String detailProduk, @Param("isStatusVerifikasi") Boolean statusVerifikasi);

	String strCekDupSkoring = "select stm.noRec " + "from SkoringTindakanMedis stm " + "inner join stm.produk pd "
			+ "where stm.statusEnabled is true "
			+ "and lower(regexp_replace(pd.namaProduk,:patternText,'','g')) = :namaProduk "
			+ "and stm.kelompokKerjaId = :kelompokKerjaId "
			+ "and lower(regexp_replace(stm.detailProduk,:patternText,'','g')) = :detailProduk";

	String skor = " and stm.skor = :skor";

	String tglBerlaku = " and to_char(stm.tanggalMulaiBerlaku,'yyyy-MM-dd') = :tglMulaiBerlaku";

	String idSkoring = " and stm.noRec <> :noRec";

	String sortTglBerlaku = " order by stm.tanggalMulaiBerlaku desc";

	@Query(strCekDupSkoring + skor + sortTglBerlaku)
	List<String> findLastDupSkoring(@Param("namaProduk") String namaProduk,
			@Param("kelompokKerjaId") Integer idKelompokKerja, @Param("skor") Double skor,
			@Param("patternText") String patternText, @Param("detailProduk") String detailProduk);

	@Query(strCekDupSkoring + tglBerlaku)
	List<String> findDupSkoring(@Param("namaProduk") String namaProduk,
			@Param("kelompokKerjaId") Integer idKelompokKerja, @Param("tglMulaiBerlaku") String tglMulaiBerlaku,
			@Param("patternText") String patternText, @Param("detailProduk") String detailProduk);

	@Query(strCekDupSkoring + skor + idSkoring + sortTglBerlaku)
	List<String> findLastDupSkoring(@Param("namaProduk") String namaProduk,
			@Param("kelompokKerjaId") Integer idKelompokKerja, @Param("skor") Double skor,
			@Param("patternText") String patternText, @Param("detailProduk") String detailProduk,
			@Param("noRec") String noRec);

	@Query(strCekDupSkoring + tglBerlaku + idSkoring)
	List<String> findDupSkoring(@Param("namaProduk") String namaProduk,
			@Param("kelompokKerjaId") Integer idKelompokKerja, @Param("tglMulaiBerlaku") String tglMulaiBerlaku,
			@Param("patternText") String patternText, @Param("detailProduk") String detailProduk,
			@Param("noRec") String noRec);

	@Query("select new Map(stm.noRec as noRec,stm.detailProduk as detailProduk) " + "from SkoringTindakanMedis stm "
			+ "where stm.statusEnabled is true " + "and stm.noRec in (:listNorec)")
	List<Map<String, Object>> findAllDup(@Param("listNorec") List<String> listNorec);

	@Query("select new Map(sk.id as kelompokKerjaId,sk.name as kelompokKerja,"
			+ "stm.produkId as produkId,stm.skor as skor,"
			+ "stm.tanggalMulaiBerlaku as tglBerlaku,stm.tanggalPembaharuanData as tglPembaharuanData) "
			+ "from SkoringTindakanMedis stm " + "inner join stm.kelompokKerja sk "
			+ "where stm.statusEnabled is true and stm.statusVerifikasi is true " + "and sk.statusEnabled is true "
			+ "and lower(sk.name) like 'kk%' "
			+ "order by sk.name asc, stm.produkId asc, stm.tanggalPembaharuanData desc")
	List<Map<String, Object>> findLatestActiveSkorByKelompokKerja();

	@Query("select new Map(pg.id as pegawaiId,pg.namaLengkap as namaLengkap," + "jb.id as jabatanId,"
			+ "stm.produkId as produkId,stm.skor as skor,"
			+ "stm.tanggalMulaiBerlaku as tglBerlaku,stm.tanggalPembaharuanData as tglPembaharuanData) "
			+ "from SkoringTindakanMedis stm, MapPegawaiJabatanToUnitKerja mj " + "inner join stm.kelompokKerja sk "
			+ "inner join mj.pegawai pg " + "inner join mj.jabatan jb "
			+ "where mj.subUnitKerjaPegawaiId = stm.kelompokKerjaId " + "and mj.subUnitKerjaPegawaiId = sk.id "
			+ "and stm.statusEnabled is true " + "and stm.statusVerifikasi is true " + "and mj.statusEnabled is true "
			+ "and sk.statusEnabled is true " + "and pg.statusEnabled is true " + "and jb.statusEnabled is true "
			+ "and jb.kelompokJabatanId in (3,4) "
			+ "order by pg.namaLengkap asc, stm.produkId asc, stm.tanggalPembaharuanData desc")
	List<Map<String, Object>> findLatestActiveSkorByDokter();

	@Query("select distinct new Map(mj.pegawaiId as pegawaiId," + "pr.id as produkId,pr.namaProduk as namaProduk,"
			+ "stm.skor as skor,stm.tanggalMulaiBerlaku as tglMulaiBerlaku,stm.tanggalPembaharuanData as tglPembaharuanData) "
			+ "from SkoringTindakanMedis stm, MapPegawaiJabatanToUnitKerja mj " + "inner join stm.produk pr "
			+ "where stm.kelompokKerjaId = mj.subUnitKerjaPegawaiId "
			+ "and stm.statusEnabled is true and stm.statusVerifikasi is true " + "and pr.statusEnabled is true "
			+ "and mj.statusEnabled is true " + "and to_char(stm.tanggalMulaiBerlaku,'yyyy-MM') <= :bulan "
			+ "and mj.pegawaiId in (:listPegawaiId) and mj.unitKerjaPegawaiId in (:listKsmId) "
			+ "order by pr.namaProduk, stm.skor desc, stm.tanggalPembaharuanData desc")
	List<Map<String, Object>> findSkoringLogbookDokter(@Param("bulan") String bulan,
			@Param("listPegawaiId") List<Integer> listIdPegawai, @Param("listKsmId") List<Integer> listIdKsm);

	String strProdukScored = "select distinct new Map(stm.kelompokKerjaId as kelompokKerjaId, stm.produkId as produkId) "
			+ "from SkoringTindakanMedis stm " + "where stm.statusEnabled is true ";

	String whrKelompokKerja = "and stm.kelompokKerjaId in (:listKelompokKerjaId) ";

	String srtKkProduk = "order by stm.kelompokKerjaId, stm.produkId";

	/**
	 * @return Daftar id produk sudah dilakukan skor remunerasi
	 */
	@Query(strProdukScored + srtKkProduk)
	List<Map<String, Object>> findProdukScored();

	/**
	 * @param listIdKelompokKerja
	 *            Daftar ID Kelompok Kerja
	 * @return Daftar id produk sudah dilakukan skor remunerasi
	 */
	@Query(strProdukScored + whrKelompokKerja + srtKkProduk)
	List<Map<String, Object>> findProdukScored(@Param("listKelompokKerjaId") List<Integer> listIdKelompokKerja);

}
