package com.jasamedika.medifirst2000.dao;

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

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
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.AntrianPasienDiPeriksa;
import com.jasamedika.medifirst2000.entities.DiagnosaPasien;

/**
 * Repository class for Pasien
 * 
 * @author Askur
 */
@Repository("AntrianPasienDiPeriksaDao")
public interface AntrianPasienDiPeriksaDao extends PagingAndSortingRepository<AntrianPasienDiPeriksa, String> {
	@Query("select p from AntrianPasienDiPeriksa p where p.pasienDaftar.noRegistrasi=:noRegistrasi ")
	List<AntrianPasienDiPeriksa> findByNoRegister(@Param("noRegistrasi") String noRegistrasi);

	@Query("select p from AntrianPasienDiPeriksa p where p.pasienDaftar.noRegistrasi=:noRegistrasi  and p.ruangan.departemen.id not  in (Select cast(s.nilaiField as int) from  SettingDataFixed s where s.namaField='KdDepartemenInstalasiRawatInap' )  ")
	List<AntrianPasienDiPeriksa> findByNoRegisterNonRawatInap(@Param("noRegistrasi") String noRegistrasi);

	@Query("select p from AntrianPasienDiPeriksa p where p.pasienDaftar.noRegistrasi=:noRegistrasi  and p.ruangan.departemen.id in (Select cast(s.nilaiField as int) from  SettingDataFixed s where s.namaField='KdDepartemenInstalasiRawatInap' )  ")
	List<AntrianPasienDiPeriksa> findByNoRegisterRawatInap(@Param("noRegistrasi") String noRegistrasi);

	@Query("select p from AntrianPasienDiPeriksa p where p.pasienDaftar.noRegistrasi=:noRegistrasi ")
	List<AntrianPasienDiPeriksa> findByNoRegisterList(@Param("noRegistrasi") String noRegistrasi);

	@Query("select p from AntrianPasienDiPeriksa p where p.pasienDaftar.noRegistrasi=:noRegistrasi and date(p.tglRegistrasi)=:dateNow and  p.ruangan.id=:idRuangan")
	AntrianPasienDiPeriksa findByNoRegisterKdRuanganAndTanggal(@Param("noRegistrasi") String noRegistrasi,
			@Param("dateNow") Date dateNow, @Param("idRuangan") Integer idRuangan);

	@Query("select max(p.noAntrian) from AntrianPasienDiPeriksa p where date(p.tglRegistrasi)=:dateNow  ")
	Integer getCountByMonthAndYear(@Param("dateNow") Date dateNow);

	@Query("select max(p.noAntrian) from AntrianPasienDiPeriksa p where date(p.tglRegistrasi)=date(:dateNow) and  p.ruangan.id=:idRuangan")
	Integer getCountByMonthAndYearRuangan(@Param("dateNow") Date dateNow, @Param("idRuangan") Integer idRuangan);

	@Query("select p from AntrianPasienDiPeriksa p where p.ruanganId=:ruanganId  ")
	Page<AntrianPasienDiPeriksa> findAllAntrianPaging(@Param("ruanganId") Integer ruanganId, Pageable pageable);

	@Query("select p from AntrianPasienDiPeriksa p where p.noRec=:noRec  ")
	AntrianPasienDiPeriksa findByNoRec(@Param("noRec") String noRec);

	@Query("select p from AntrianPasienDiPeriksa p where p.pasienDaftar.pasien.id=:pasienId and p.ruangan.id=:ruanganId ")
	List<AntrianPasienDiPeriksa> findByPasien(@Param("pasienId") Integer pasienId,
			@Param("ruanganId") Integer ruanganId);

	@Query("select p from AntrianPasienDiPeriksa p where p.pasienDaftar.pasien.id=:pasienId and p.kdProfile=:kdProfile and  p.tglRegistrasi =:tanggalPendaftaran")
	AntrianPasienDiPeriksa finByNoIdAndTglRegistrasi(@Param("kdProfile") short kdProfile,
			@Param("pasienId") Integer pasienId, @Param("tanggalPendaftaran") Date tanggalPendaftaran);

	@Query("select p from AntrianPasienDiPeriksa p where p.pasienDaftar.pasien.id=:pasienId and p.kdProfile=:kdProfile and  p.tglRegistrasi =:tanggalPendaftaran")
	List<AntrianPasienDiPeriksa> findByNoIdAndTglRegistrasi(@Param("kdProfile") short kdProfile,
			@Param("pasienId") Integer pasienId, @Param("tanggalPendaftaran") Date tanggalPendaftaran);

	@Query("select p from AntrianPasienDiPeriksa p where p.pasienDaftar.pasien.id=:pasienId  and  date(p.tglRegistrasi) =date(:tanggalPendaftaran)")
	AntrianPasienDiPeriksa findbyNoCmAndTglRegistrasi(@Param("pasienId") Integer pasienId,
			@Param("tanggalPendaftaran") Date tanggalPendaftarani);

	AntrianPasienDiPeriksa findByStrukOrderNoRec(String noRec);

	@Query("select p from AntrianPasienDiPeriksa p where p.pasienDaftar.pasien.id=:pasienId and p.kdProfile=:kdProfile and  date(p.tglRegistrasi) =date(:tanggalPendaftaran)")
	List<AntrianPasienDiPeriksa> finByNoIdAndTglRegistrasiList(@Param("kdProfile") short kdProfile,
			@Param("pasienId") Integer pasienId, @Param("tanggalPendaftaran") Date tanggalPendaftaran);

	AntrianPasienDiPeriksa findByStrukOrderNoOrderIntern(String noOrder);

	List<AntrianPasienDiPeriksa> findByPasienDaftarNoRecAndStrukOrderNoOrderInternStartingWith(String noRec,
			String key);

	@Query("select model " + "from DiagnosaPasien model  " + "left join model.pasienDaftar antrian "
			+ "left join antrian.pegawai dokter " + "left join antrian.pasienDaftar pasienDaftar "
			+ "left join pasienDaftar.pasien pasien " + "where pasien.noCm=:noCm  "
			+ "and to_char(model.tanggalPendaftaran, 'dd-MM-yyyy')=:tglRegistrasi")
	List<DiagnosaPasien> findDiagnosaPasien(@Param("noCm") String noCm, @Param("tglRegistrasi") String tglRegistrasi);

	@Query("select NEW Map (" + "a.noRec as noRec, " + "a.ruanganId as ruangan, " + "c.id as kelasId) "
			+ "from AntrianPasienDiPeriksa a " + "left join a.pasienDaftar b " + "left join b.kelas c "
			+ "where a.pasienDaftarId=:noRec")
	Map<String, Object> findRuanganByNoRecPasienDaftar(@Param("noRec") String noRec);

	@Query("select count(*),a.ruangan.namaRuangan,to_char(a.tglRegistrasi,'yyyy-mm-dd'),a.ruangan.id "
			+ "from AntrianPasienDiPeriksa a where a.ruangan.id=:ruanganId and "
			+ "to_char(a.tglRegistrasi,'dd-mm-yyyy') = :currentDate "
			+ "group by a.ruangan.namaRuangan,to_char(a.tglRegistrasi,'yyyy-mm-dd'),a.ruangan.id "
			+ "order by to_char(a.tglRegistrasi,'yyyy-mm-dd') desc,count(*),a.ruangan.namaRuangan desc")
	List<Object[]> findRuanganByRuanganId(@Param("ruanganId") Integer ruanganId,
			@Param("currentDate") String currentDate);

	@Query("select max(p.noAntrian) from AntrianPasienDiPeriksa p where date(p.tglRegistrasi)=:dateNow and p.ruangan.id=:idRuangan")
	Integer getCountByMonthAndYearBilik(@Param("dateNow") Date dateNow, @Param("idRuangan") Integer idRuangan);

	@Query("select p from AntrianPasienDiPeriksa p where p.noRec=:noRec")
	AntrianPasienDiPeriksa setPegawaiRawatInap(@Param("noRec") String noRec);

	// gizi - sarpras Rumah Tangga
	@Query("select distinct NEW Map(jd.id as jenisDietId,jd.jenisDiet as jenisDiet) from PreskripsiDiet pd left join pd.jenisDiet jd "
			+ "left join pd.asesmenGiziAwal aga left join aga.pasienDaftar apd where apd.noRec=:noRec order by jd.id")
	List<Map<String, Object>> findJenisDiet(@Param("noRec") String noRec);

	// gizi - sarpras Rumah Tangga
	@Query("select distinct NEW Map(alg.id as alergiId,alg.namaAlergi as namaAlergi) from PapAlergi pa left join pa.alergi alg left join "
			+ "pa.pasienDaftar apd where apd.noRec =:noRec  order by alg.id")
	List<Map<String, Object>> findAlergi(@Param("noRec") String noRec);

	// gizi - sarpras Rumah Tangga
	@Query("select distinct NEW Map(dg.id as diagnosaId,dg.namaDiagnosa as namaDiagnosa) from DetailDiagnosaPasien ddp left join ddp.diagnosa dg "
			+ "left join ddp.pasienDaftar apd where apd.noRec=:noRec order by dg.id")
	List<Map<String, Object>> findDiagnosa(@Param("noRec") String noRec);

	@Query("select a from AntrianPasienDiPeriksa a " + "left join a.pasienDaftar b " + "where b.noRec=:noRec")
	List<AntrianPasienDiPeriksa> findByPasienDaftar(@Param("noRec") String noRec);

	@Query("select model " + "from AntrianPasienDiPeriksa model " + "where model.pasienDaftar.pasien.id=:idPasien "
			+ "and model.ruangan.id=:idRuangan and model.pegawai.id=:idDokter "
			+ "and model.tglRegistrasi =:tglRegistrasi")
	List<AntrianPasienDiPeriksa> findAntrianByPasienRuanganDokter(@Param("idPasien") Integer idPasien,
			@Param("idRuangan") Integer idRuangan, @Param("idDokter") Integer idDokter,
			@Param("tglRegistrasi") Date tglRegistrasi);

	@Query("select a from AntrianPasienDiPeriksa a " + "left join a.pasienDaftar b "
			+ "where b.noRec=:noRec and a.ruangan.id=:ruanganId")
	List<AntrianPasienDiPeriksa> findByPasienDaftarAndRuangan(@Param("noRec") String noRec,
			@Param("ruanganId") Integer ruanganId);

	@Query("select a from AntrianPasienDiPeriksa a " + "left join a.pasienDaftar b "
			+ "left join a.strukOrder strukorder " + "where b.noRec=:noRec and strukorder.noRec is null")
	List<AntrianPasienDiPeriksa> findByPasienDaftarAndStrukOrderNull(@Param("noRec") String noRec);

	@Query("select new map(antrian.noRec as noRec,kelPasien.id as idKelPasien,kelPasien.kelompokPasien as kelPasien,"
			+ "departemen.id as idDepartemen,departemen.namaDepartemen as namaDepartemen) "
			+ "from AntrianPasienDiPeriksa antrian left join antrian.pasienDaftar noRegistrasi "
			+ "left join noRegistrasi.rekanan rekanan left join noRegistrasi.kelompokPasien kelPasien "
			+ "left join antrian.ruangan.departemen departemen where antrian.noRec=:noRegistrasi")
	List<Map<String, Object>> getKelompokPasien(@Param("noRegistrasi") String noRegistrasi);

	@Query("select new map (produk.namaProduk as pemeriksaan," + "produk.id as idProduk ) "
			+ "from PelayananPasien pelayananPasien " + "left join pelayananPasien.produk produk "
			+ "left join produk.detailJenisProduk detailJenisProduk "
			+ "left join detailJenisProduk.jenisProduk jenisProduk "
			+ "left join jenisProduk.kelompokProduk kelompokProduk " + "left join pelayananPasien.pasienDaftar antrian "
			+ "where antrian.noRec = :noRec")
	Map<String, Object> findProdukByNoRecAntrian(@Param("noRec") String noRec);

	@Query("select new map (antrian.noRec as noRec, " + "pasienDaftar.noRec as noRecPasienDaftar, "
			+ "ruangan.id as idRuangan, " + "antrian.statusAntrian as statusAntrian, "
			+ "strukOrder.noRec as noRecStrukOrder, " + "antrian.statusPasien as statusPasien, "
			+ "asalRujukan.id as asalRujukan, " + "antrian.tglRegistrasi as tglRegistrasi) "
			+ "from AntrianPasienDiPeriksa antrian  " + "left join antrian.asalRujukan asalRujukan "
			+ "left join antrian.pasienDaftar pasienDaftar " + "left join antrian.ruangan ruangan "
			+ "left join antrian.strukOrder strukOrder " + "where antrian.noRec=:noRec  ")
	Map<String, Object> findAntrianByNoRec(@Param("noRec") String noRec);

	@Query("select model from AntrianPasienDiPeriksa model " + "left join model.pasienDaftar a where a.noRec=:noRec")
	AntrianPasienDiPeriksa getByPasienDaftar(@Param("noRec") String noRec);

	@Query("select p from AntrianPasienDiPeriksa p where p.pasienDaftar.noRec=:noRec and (p.statusEnabled is null or p.statusEnabled is true)")
	List<AntrianPasienDiPeriksa> findByNoRecPasienDaftar(@Param("noRec") String noRec);

	@Query("select p.ruangan.id from AntrianPasienDiPeriksa p where p.pasienDaftar.noRec=:noRec and p.ruanganAsal= null and (p.statusEnabled is null or p.statusEnabled is true) ")
	List<Integer> findByNoRecPasienDaftarAndRuanganAsal(@Param("noRec") String noRec);

	@Query("select new map (antrian.noRec as noRec, " + "pasienDaftar.noRec as noRecPasienDaftar, "
			+ "ruangan.id as idRuangan, " + "antrian.statusAntrian as statusAntrian, "
			+ "strukOrder.noRec as noRecStrukOrder, " + "antrian.statusPasien as statusPasien, "
			+ "asalRujukan.id as asalRujukan, kelas.id as idKelas, " + "antrian.tglRegistrasi as tglRegistrasi) "
			+ "from AntrianPasienDiPeriksa antrian  " + "left join antrian.asalRujukan asalRujukan "
			+ "left join antrian.pasienDaftar pasienDaftar " + "left join antrian.ruangan ruangan "
			+ "left join antrian.kelas kelas " + "left join antrian.strukOrder strukOrder "
			+ "where pasienDaftar.noRec=:noRec and ruangan.id = :idRuangan "
			+ "and (antrian.statusEnabled is null or antrian.statusEnabled is true)")
	List<Map<String, Object>> findAntrianByNoRecPasienDaftar(@Param("noRec") String noRec,
			@Param("idRuangan") Integer idRuangan);

	@Query("select antrian " + "from AntrianPasienDiPeriksa antrian " + "left join antrian.pasienDaftar pasienDaftar "
			+ "left join antrian.ruangan ruangan " + "where pasienDaftar.noRec=:noRec and  "
			+ "ruangan.id= :idRuangan and (antrian.statusEnabled is null or antrian.statusEnabled is true) "
			+ "and antrian.tglKeluar is null order by antrian.tglRegistrasi desc")
	List<AntrianPasienDiPeriksa> findAntrianBefore(@Param("noRec") String noRec, @Param("idRuangan") Integer idRuangan);

	@Query("select distinct new Map(pd.noRec as noRec,pd.kelompokPasienId as kpId) "
			+ "from AntrianPasienDiPeriksa apd " + "inner join apd.pasienDaftar pd "
			+ "where apd.statusEnabled is true " + "and pd.statusEnabled is true "
			+ "and apd.tglMasuk between :tglAwal and :tglAkhir " + "and apd.ruanganId = :ruanganId")
	List<Map<String, Object>> findAntreanByRuangan(@Param("tglAwal") Date tglAwal,
			@Param("tglAkhir") Date tglAkhir, @Param("ruanganId") Integer ruanganId);
}
