package com.jasamedika.medifirst2000.service.impl;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.jasamedika.medifirst2000.converter.AsalRujukanConverter;
import com.jasamedika.medifirst2000.converter.DiputuskanConverter;
import com.jasamedika.medifirst2000.converter.PasienDaftarConverter;
import com.jasamedika.medifirst2000.converter.PegawaiConverter;
import com.jasamedika.medifirst2000.dao.JadwalDokterDao;
import com.jasamedika.medifirst2000.dao.KamarDao;
import com.jasamedika.medifirst2000.dao.KelasDao;
import com.jasamedika.medifirst2000.dao.PasienDaftarDao;
import com.jasamedika.medifirst2000.dao.PersetujuanUmumDao;
import com.jasamedika.medifirst2000.dao.RuanganDao;
import com.jasamedika.medifirst2000.dao.SettingDataFixedDao;
import com.jasamedika.medifirst2000.dao.SkalaNyeriDao;
import com.jasamedika.medifirst2000.dao.SuratPermintaanMasukDao;
import com.jasamedika.medifirst2000.entities.AntrianPasienDiPeriksa;
import com.jasamedika.medifirst2000.entities.AsalRujukan;
import com.jasamedika.medifirst2000.entities.Diputuskan;
import com.jasamedika.medifirst2000.entities.DiputuskanDetail;
import com.jasamedika.medifirst2000.entities.JadwalDokter;
import com.jasamedika.medifirst2000.entities.Kamar;
import com.jasamedika.medifirst2000.entities.KelompokPasien;
import com.jasamedika.medifirst2000.entities.Pasien;
import com.jasamedika.medifirst2000.entities.PasienDaftar;
import com.jasamedika.medifirst2000.entities.Pegawai;
import com.jasamedika.medifirst2000.entities.PersetujuanUmum;
import com.jasamedika.medifirst2000.entities.Ruangan;
import com.jasamedika.medifirst2000.entities.SkalaNyeri;
import com.jasamedika.medifirst2000.entities.SuratPermintaanMasuk;
import com.jasamedika.medifirst2000.enums.StatusAntrianEnum;
import com.jasamedika.medifirst2000.enums.StatusPenyakitEnum;
import com.jasamedika.medifirst2000.enums.TipePasienEnum;
import com.jasamedika.medifirst2000.exception.ServiceVOException;
import com.jasamedika.medifirst2000.service.AntrianPasienDiPeriksaService;
import com.jasamedika.medifirst2000.service.DiagnosaPasienService;
import com.jasamedika.medifirst2000.service.LoginUserService;
import com.jasamedika.medifirst2000.service.PasienDaftarService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.util.DateUtil;
import com.jasamedika.medifirst2000.vo.DiputuskanDetailVO;
import com.jasamedika.medifirst2000.vo.MasukKamarVO;
import com.jasamedika.medifirst2000.vo.PasienDaftarVO;
import com.jasamedika.medifirst2000.vo.PegawaiVO;
import com.jasamedika.medifirst2000.vo.RegistrasiPasienGawatDaruratVO;

@Service("PasienDaftarService")
public class PasienDaftarServiceImpl implements PasienDaftarService {
	@Autowired
	private PasienDaftarConverter pasienDaftarConverter;

	@Autowired
	private AsalRujukanConverter asalRujukanConverter;

	@Autowired
	private PegawaiConverter pegawaiConverter;

	@Autowired
	private DiputuskanConverter diputuskanConverter;

	@Autowired
	private PasienDaftarDao pasienDaftarDao;

	@Autowired
	private SuratPermintaanMasukDao suratPermintaanMasukDao;

	@Autowired
	private RuanganDao ruanganDao;

	@Autowired
	private JadwalDokterDao jadwalDokterDao;

	@Autowired
	private AntrianPasienDiPeriksaService antrianPasienDiPeriksaService;

	@Autowired
	private PersetujuanUmumDao persetujuanUmumDao;

	@Autowired
	private KelasDao kelasDao;

	@Autowired
	private KamarDao kamarDao;

	@Autowired
	private SettingDataFixedDao settingDataFixedDao;

	@Autowired
	private DiagnosaPasienService diagnosaPasienService;

	@Autowired
	private LoginUserService loginUserService;

	@Autowired
	private SkalaNyeriDao skalaNyeri;

	@Override
	public PasienDaftarVO add(PasienDaftarVO vo) throws JpaSystemException, ServiceVOException {
		return null;
	}

	@Override
	public PasienDaftarVO update(PasienDaftarVO vo) throws JpaSystemException, ServiceVOException {
		return null;
	}

	@Override
	public Boolean delete(String key) throws JpaSystemException {
		return null;
	}

	@Override
	public PasienDaftarVO findById(String key) throws JpaSystemException {
		return null;
	}

	@Override
	public Map<String, Object> findAllWithPageAndLimitAndSortByAndDirectionParameter(Integer page, Integer limit,
			String sort, String dir) {
		return null;
	}

	@Override
	public List<PasienDaftar> findAllPasienDaftar(String startDate, String endDate) {
		return null;
	}

	@Override
	public List<PasienDaftarVO> findAll() throws JpaSystemException {
		List<PasienDaftarVO> vos = new ArrayList<PasienDaftarVO>();
		List<PasienDaftar> models = (List<PasienDaftar>) pasienDaftarDao.findAll();
		pasienDaftarConverter.transferListOfModelToListOfVO(models, vos);
		return vos;
	}

	@Override
	public String getFormatNumberByMonthYear() {
		Date dateNow = new Date();
		Integer year = DateUtil.getYearFromDate(dateNow);
		Integer month = DateUtil.getMonthFromDate(dateNow);
		Integer countByMonthAndYear = 0;

		countByMonthAndYear = pasienDaftarDao.getCountByMonthAndYear(month, year);
		if (countByMonthAndYear == 0) {
			countByMonthAndYear++;
		} else {
			countByMonthAndYear++;
		}
		Integer monthNow = DateUtil.getMonthFromDate(dateNow);
		Integer yearNow = DateUtil.getYearFromDate(dateNow);
		String yearNowString = yearNow.toString().substring(2, 4);
		String dateNowString = monthNow.toString();
		String countString = null;
		if (com.jasamedika.medifirst2000.util.CommonUtil.isNotNullOrEmpty(countByMonthAndYear)) {
			if (countByMonthAndYear.toString().length() == 1) {
				countString = "00000" + countByMonthAndYear.toString();
			} else if (countByMonthAndYear.toString().length() == 2) {
				countString = "0000" + countByMonthAndYear.toString();
			} else if (countByMonthAndYear.toString().length() == 3) {
				countString = "000" + countByMonthAndYear.toString();
			} else if (countByMonthAndYear.toString().length() == 4) {
				countString = "00" + countByMonthAndYear.toString();
			} else if (countByMonthAndYear.toString().length() == 5) {
				countString = "0" + countByMonthAndYear.toString();
			}
		}

		if ((dateNowString.length()) == 1) {
			dateNowString = "0" + monthNow;
		}
		return yearNowString + "" + dateNowString + "" + countString;
	}

	@Override
	public List<PasienDaftar> findPelayananRawatJalan(Short kdProfile, String noCm) {
		return pasienDaftarDao.findPelayananRawatJalan(kdProfile, noCm);
	}

	@Override
	public Map<String, Object> savePasienDaftarFromRegistrasiPasienGawatDarurat(Pasien model,
			RegistrasiPasienGawatDaruratVO vo) {

		Map<String, Object> resultSavePasienDaftar = new HashMap<String, Object>();
		PasienDaftar pasienDaftar = new PasienDaftar();
		pasienDaftar.setRuangan(ruanganDao.findRuanganGawatDarurat());
		pasienDaftar.setStatusKasusPenyakit(true);
		if (CommonUtil.isNotNullOrEmpty(model)) {
			pasienDaftar.setPasien(model);
			List<PasienDaftar> listPasienDaftar = null;
			try {
				listPasienDaftar = pasienDaftarDao.findByPasienNoCm(model.getNoCm());
			} catch (Exception e) {
				System.out.println(e.toString());
			}

			if (listPasienDaftar == null) {
				pasienDaftar.setIsKajianAwal(true);
			} else {
				if (listPasienDaftar.size() == 0) {
					pasienDaftar.setIsKajianAwal(true);
				} else {

					PasienDaftar pasienDaftarTemp = listPasienDaftar.get(0);

					long diff = new Date().getTime() - pasienDaftarTemp.getTglRegistrasi().getTime();
					long diffMonth = diff / 1000 / 60 / 60 / 24 / 30;
					pasienDaftar.setIsKajianAwal(diffMonth >= 3);
				}
			}
		}
		if (checkStatusPasien(model.getId())) {
			pasienDaftar.setStatusPasien(TipePasienEnum.LAMA.getVal());
		} else {
			pasienDaftar.setStatusPasien(TipePasienEnum.BARU.getVal());
		}

		pasienDaftar.setIsOnSiteService((byte) 0);
		pasienDaftar.setIsRegistrasiLengkap((byte) 0);
		pasienDaftar.setTglRegistrasi(DateUtil.getShortDate());
		pasienDaftar.setKelas(kelasDao.findKelas3());
		KelompokPasien kelompokPasien = new KelompokPasien();
		kelompokPasien.setId(vo.getKelompokPasien().getId());
		pasienDaftar.setKelompokPasien(kelompokPasien);
		pasienDaftar.setNoRegistrasi(getFormatNumberByMonthYear());

		AntrianPasienDiPeriksa antrianPasienDiPeriksa = new AntrianPasienDiPeriksa();
		if (CommonUtil.isNotNullOrEmpty(vo.getRuangan())) {
			antrianPasienDiPeriksa.setRuangan(ruanganDao.findRuanganGawatDarurat());
		}

		if (CommonUtil.isNotNullOrEmpty(vo.getAsalRujukan())) {
			antrianPasienDiPeriksa
					.setAsalRujukan(asalRujukanConverter.transferVOToModel(vo.getAsalRujukan(), new AsalRujukan()));
		}

		if (CommonUtil.isNotNullOrEmpty(vo.getPegawai())) {
			if (CommonUtil.isNotNullOrEmpty(vo.getPegawai().getId())) {
				//
				PegawaiVO pegawaiVo = new PegawaiVO();

				// pilih dokter yang otomatis dan per quota
				List<JadwalDokter> jadwalDokters = jadwalDokterDao
						.findJadwalByTanggalRuangan(pasienDaftar.getRuangan().getId(), pasienDaftar.getTglRegistrasi());
				Integer maxQuota = 0;
				for (JadwalDokter jadwalDokter : jadwalDokters) {
					if (jadwalDokter.getQuota() != null && jadwalDokter.getQuota() > maxQuota) {
						maxQuota = jadwalDokter.getQuota();
					}
				}
				Boolean valid = false;
				for (JadwalDokter jadwalDokter : jadwalDokters) {
					if (jadwalDokter.getQuota() != null && jadwalDokter.getQuota() < maxQuota) {
						valid = true;
						jadwalDokter.setQuota(jadwalDokter.getQuota() + 1);
						jadwalDokterDao.save(jadwalDokter);
						pegawaiVo.setId(jadwalDokter.getDokter().getId());
						vo.setPegawai(pegawaiVo);
						break;
					}
				}
				if (!valid) {
					for (JadwalDokter jadwalDokter : jadwalDokters) {
						if (jadwalDokter.getQuota() == null || jadwalDokter.getQuota() == maxQuota) {
							valid = true;
							if (jadwalDokter.getQuota() == null)
								jadwalDokter.setQuota(0);
							jadwalDokter.setQuota(jadwalDokter.getQuota() + 1);
							jadwalDokterDao.save(jadwalDokter);
							pegawaiVo.setId(jadwalDokter.getDokter().getId());
							vo.setPegawai(pegawaiVo);
							break;
						}
					}
				}

			}

		} else {
			PegawaiVO pegawaiVo = new PegawaiVO();

			// pilih dokter yang otomatis dan per quota
			List<JadwalDokter> jadwalDokters = jadwalDokterDao
					.findJadwalByTanggalRuangan(pasienDaftar.getRuangan().getId(), pasienDaftar.getTglRegistrasi());
			Integer maxQuota = 0;
			for (JadwalDokter jadwalDokter : jadwalDokters) {
				if (jadwalDokter.getQuota() != null && jadwalDokter.getQuota() > maxQuota) {
					maxQuota = jadwalDokter.getQuota();
				}
			}
			Boolean valid = false;
			for (JadwalDokter jadwalDokter : jadwalDokters) {
				if (jadwalDokter.getQuota() != null && jadwalDokter.getQuota() < maxQuota) {
					valid = true;
					jadwalDokter.setQuota(jadwalDokter.getQuota() + 1);
					jadwalDokterDao.save(jadwalDokter);
					pegawaiVo.setId(jadwalDokter.getDokter().getId());
					vo.setPegawai(pegawaiVo);
					break;
				}
			}
			if (!valid) {
				for (JadwalDokter jadwalDokter : jadwalDokters) {
					if (jadwalDokter.getQuota() == null || jadwalDokter.getQuota() == maxQuota) {
						valid = true;
						if (jadwalDokter.getQuota() == null)
							jadwalDokter.setQuota(0);
						jadwalDokter.setQuota(jadwalDokter.getQuota() + 1);
						jadwalDokterDao.save(jadwalDokter);
						pegawaiVo.setId(jadwalDokter.getDokter().getId());
						vo.setPegawai(pegawaiVo);
						break;
					}
				}
			}

		}

		antrianPasienDiPeriksa.setPegawai(pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai()));
		pasienDaftar.setDokterPenanggungJawab(pegawaiConverter.transferVOToModel(vo.getPegawai(), new Pegawai()));

		if (diagnosaPasienService.checkDiagnosaPasien(model.getId())) {
			antrianPasienDiPeriksa.setStatusPenyakit(StatusPenyakitEnum.LAMA.getVal());
		} else {
			antrianPasienDiPeriksa.setStatusPenyakit(StatusPenyakitEnum.BARU.getVal());
		}

		antrianPasienDiPeriksa.setTglRegistrasi(new Date());
		antrianPasienDiPeriksa.setNoMasuk(StatusAntrianEnum.MENUNGGU.getVal());
		antrianPasienDiPeriksa.setStatusPasien((byte) 1);
		antrianPasienDiPeriksa.setPasienDaftar(pasienDaftar);
		antrianPasienDiPeriksa.setNoAntrian(antrianPasienDiPeriksaService.getFormatNumberByMonthYearRuangan(null,
				ruanganDao.findRuanganGawatDarurat().getId()));
		antrianPasienDiPeriksa.setStatusAntrian(StatusAntrianEnum.DIPANGGIL_SUSTER.getVal());
		pasienDaftar.getAntrianPasienDiPeriksaSet().add(antrianPasienDiPeriksa);

		if (CommonUtil.isNotNullOrEmpty(vo.getDiputuskanDetailSet())) {
			for (DiputuskanDetailVO diputuskanDetailVO : vo.getDiputuskanDetailSet()) {
				DiputuskanDetail diputuskanDetail = new DiputuskanDetail();
				diputuskanDetail.setDiputuskan(
						diputuskanConverter.transferVOToModel(diputuskanDetailVO.getDiputuskan(), new Diputuskan()));
				diputuskanDetail.setPasienDaftar(pasienDaftar);
				pasienDaftar.getDiputuskanDetailSet().add(diputuskanDetail);
			}
		}

		PasienDaftar passienDaftarResult = pasienDaftarDao.save(pasienDaftar);
		if (CommonUtil.isNotNullOrEmpty(passienDaftarResult)) {
			resultSavePasienDaftar.put("antrianPasienDiPeriksa", antrianPasienDiPeriksa);
			resultSavePasienDaftar.put("pasienDaftar", pasienDaftar);
		}

		return resultSavePasienDaftar;

	}

	@Override
	public String getFormatNumberByMonthYearByParameter(Date tglRegistrasi) {
		Date dateNow = tglRegistrasi;
		Integer year = DateUtil.getYearFromDate(dateNow);
		String tahun = year.toString();
		Integer month = DateUtil.getMonthFromDate(dateNow);
		Integer countByMonthAndYear = 0;
		System.out.println(tahun.substring(2, 4));
		String lastNoRegistrasi = pasienDaftarDao.getMaxNoRegistrasiByMonthAndYear(month,
				Integer.valueOf(tahun.substring(2, 4)));
		if (CommonUtil.isNotNullOrEmpty(lastNoRegistrasi)) {
			String temp = lastNoRegistrasi.substring(4, 10);
			countByMonthAndYear = Integer.valueOf(temp);
		}
		if (countByMonthAndYear == 0) {
			countByMonthAndYear++;
		} else {
			countByMonthAndYear++;
		}
		Integer monthNow = DateUtil.getMonthFromDate(dateNow);
		Integer yearNow = DateUtil.getYearFromDate(dateNow);
		String yearNowString = yearNow.toString().substring(2, 4);
		String dateNowString = monthNow.toString();
		String countString = null;
		if (com.jasamedika.medifirst2000.util.CommonUtil.isNotNullOrEmpty(countByMonthAndYear)) {
			if (countByMonthAndYear.toString().length() == 1) {
				countString = "00000" + countByMonthAndYear.toString();
			} else if (countByMonthAndYear.toString().length() == 2) {
				countString = "0000" + countByMonthAndYear.toString();
			} else if (countByMonthAndYear.toString().length() == 3) {
				countString = "000" + countByMonthAndYear.toString();
			} else if (countByMonthAndYear.toString().length() == 4) {
				countString = "00" + countByMonthAndYear.toString();
			} else if (countByMonthAndYear.toString().length() == 5) {
				countString = "0" + countByMonthAndYear.toString();
			}
		}

		if ((dateNowString.length()) == 1) {
			dateNowString = "0" + monthNow;
		}
		return yearNowString + "" + dateNowString + "" + countString;
	}

	@Override
	public Map<String, Object> updatePasienDaftarFromMasukKamar(MasukKamarVO masukKamarVO) {
		Map<String, Object> resultPasienDaftar = new HashMap<String, Object>();
		if (CommonUtil.isNotNullOrEmpty(masukKamarVO.getPasienDaftar())) {
			PasienDaftar model = pasienDaftarDao.findOne(masukKamarVO.getPasienDaftar().getNoRec());
			model.setTglPulang(null);
			Kamar kamar1 = kamarDao.findOne(masukKamarVO.getKamar().getId());
			Ruangan ruangan = new Ruangan();
			ruangan.setId(kamar1.getRuangan().getId());
			model.setRuangan(ruangan);
			List<SuratPermintaanMasuk> dpjp = suratPermintaanMasukDao
					.finByNoRecAntrianPasienDiPeriksa(masukKamarVO.getPasienDaftar().getNoRec());
			if (!dpjp.isEmpty()) {
				SuratPermintaanMasuk spm = dpjp.get(0);
				model.setDokterPenanggungJawab(spm.getDokterPenanggungJawab());
				Kamar kamar = kamarDao.findOne(masukKamarVO.getKamar().getId());
				if (kamar != null)
					spm.setUnit(kamar.getRuangan());
				if (CommonUtil.isNotNullOrEmpty(masukKamarVO.getPemberiInformasi()))
					spm.setPemberiInformasi(masukKamarVO.getPemberiInformasi());
				if (CommonUtil.isNotNullOrEmpty(masukKamarVO.getPetugas()))
					spm.setPetugas(pegawaiConverter.transferVOToModel(masukKamarVO.getPetugas(), new Pegawai()));
				else
					spm.setPetugas(loginUserService.getLoginUser().getPegawai());
				suratPermintaanMasukDao.save(spm);
			}
			if (CommonUtil.isNotNullOrEmpty(model)) {
				List<PersetujuanUmum> listPersetujuanUmum = persetujuanUmumDao
						.findByPasienDaftar(masukKamarVO.getPasienDaftar().getNoRec(), (short) 0);
				if (CommonUtil.isNotNullOrEmpty(listPersetujuanUmum)) {
					PersetujuanUmum persetujuanUmum = listPersetujuanUmum.get(0);
					model.setKelompokPasien(persetujuanUmum.getJenisPembayaran());
					pasienDaftarDao.save(model);
				}
				resultPasienDaftar.put("pasienDaftar", model);
			}
		}
		return resultPasienDaftar;

	}

	@Override
	@Transactional
	public PasienDaftar findbyNoCmAndTglRegistrasi(Integer id, Date tglRegistrasi) {
		PasienDaftar model = pasienDaftarDao.finByNoIdAndTglRegistrasi(Short.parseShort("0"), id, tglRegistrasi);
		return model;
	}

	@Override
	public void updateTanggalMeninggal(PasienDaftar pasienDaftar) {
		pasienDaftarDao.save(pasienDaftar);
	}

	@Override
	@Transactional
	public PasienDaftar findbyNoCmLast(String noCm) {
		List<PasienDaftar> pasienDaftars = pasienDaftarDao.findByPasienNoCm(noCm);
		if (pasienDaftars.size() == 0)
			return new PasienDaftar();
		PasienDaftar model = pasienDaftars.get(pasienDaftars.size() - 1);
		return model;
	}

	public List<SkalaNyeri> getSkalaNyeri() {
		List<SkalaNyeri> listData = (List<SkalaNyeri>) skalaNyeri.findAll();
		return listData;
	}

	public Boolean checkStatusPasien(Integer pasienId) {
		Boolean result = false;
		List<PasienDaftar> pasienDaftarList = pasienDaftarDao.findByPasienId(pasienId);
		if (CommonUtil.isNotNullOrEmpty(pasienDaftarList)) {
			result = true;
		}
		return result;
	}

	@Override
	public List<PasienDaftar> getFindSchedule(Integer idRuangan) {

		return pasienDaftarDao.findByRuanganNextScheduleId(idRuangan);
	}

	@Override
	public Map<String, Object> calculateIndikatorPelayanan(String tglAwal, String tglAkhir) {
		Map<String, Object> result = new HashMap<>();

		DecimalFormat df = new DecimalFormat("###.##");

		Long tlosPeriod = 0L;
		Long tlosPlgPeriod = 0L;
		Long lengthPeriod = ChronoUnit.DAYS.between(LocalDate.parse(tglAwal.substring(0, 10)),
				LocalDate.parse(tglAkhir.substring(0, 10))) + 1;
		Integer jumlahTempatTidur = Integer.valueOf(settingDataFixedDao.getSettingDataFixed("totalkamarranapaktif"));

		List<Map<String, Object>> borData = pasienDaftarDao.getPasienRanap(tglAwal, tglAkhir);
		for (Map<String, Object> bor : borData) {
			tlosPeriod = tlosPeriod
					+ ChronoUnit.DAYS.between(LocalDate.parse(bor.get("tglRegistrasiPeriode").toString()),
							LocalDate.parse(bor.get("tglPulangPeriode").toString()))
					+ 1;
		}

		Double bor = tlosPeriod.doubleValue() * 100 / (jumlahTempatTidur * lengthPeriod.doubleValue());

		List<Map<String, Object>> othData = pasienDaftarDao.getPasienRanapPulang(tglAwal, tglAkhir);
		Integer tpm = 0;
		Integer tpm2 = 0;
		for (Map<String, Object> oth : othData) {
			tlosPlgPeriod = tlosPlgPeriod
					+ ChronoUnit.DAYS.between(LocalDate.parse(oth.get("tglRegistrasiPeriode").toString()),
							LocalDate.parse(oth.get("tglPulangPeriode").toString()))
					+ 1;
			if (CommonUtil.isNotNullOrEmpty(oth.get("tglMeninggal"))) {
				tpm = tpm + 1;
			}
			if (CommonUtil.isNotNullOrEmpty(oth.get("tglMeninggal"))) {
				if (ChronoUnit.DAYS.between(LocalDate.parse(oth.get("tglRegistrasiPeriode").toString()),
						LocalDate.parse(oth.get("tglMeninggal").toString())) + 1 > 2) {
					tpm2 = tpm2 + 1;
				}
			}
		}

		Double gdr = tpm.doubleValue() / othData.size() * 1000;
		Double ndr = tpm2.doubleValue() / othData.size() * 1000;
		Double alos = tlosPlgPeriod.doubleValue() / othData.size();
		Double bto = othData.size() / jumlahTempatTidur.doubleValue();
		Double toi = (jumlahTempatTidur.doubleValue() * lengthPeriod.doubleValue() - tlosPeriod.doubleValue())
				/ othData.size();

		result.put("totalLos", tlosPeriod);
		result.put("totalLosPulang", tlosPlgPeriod);
		result.put("totalPasPulang", othData.size());
		result.put("periode", lengthPeriod);
		result.put("totalBed", jumlahTempatTidur);
		result.put("totalBedPeriod", jumlahTempatTidur * lengthPeriod);
		result.put("totalPasienMeninggal", tpm);
		result.put("totalPasienMeninggal48Jam", tpm2);
		result.put("bor", df.format(bor));
		result.put("alos", df.format(alos));
		result.put("bto", df.format(bto));
		result.put("toi", df.format(toi));
		result.put("gdr", df.format(gdr));
		result.put("ndr", df.format(ndr));

		return result;
	}

	@Override
	public List<Map<String, Object>> findIndikatorPelayanan(String tahun) {
		List<Map<String, Object>> result = new ArrayList<>();

		SimpleDateFormat month = new SimpleDateFormat("MMMM", new Locale("in", "ID"));
		SimpleDateFormat year = new SimpleDateFormat("yyyy");
		SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		Date today = new Date();

		String strEnd = "";
		String strStart = "";
		if (year.format(today).equals(tahun)) {
			strEnd = formater.format(today);
			strStart = year.format(today) + "-01-01 00:00:00";
		} else {
			strEnd = tahun + "-12-31 23:59:59";
			strStart = tahun + "-01-01 00:00:00";
		}

		Calendar beginCalendar = Calendar.getInstance();
		Calendar endCalendar = Calendar.getInstance();

		try {
			beginCalendar.setTime(formater.parse(strStart));
			endCalendar.setTime(formater.parse(strEnd));
		} catch (ParseException e) {
			e.printStackTrace();
		}

		List<String> listDateParam = new ArrayList<>();

		while (beginCalendar.before(endCalendar)) {
			String date = formater.format(beginCalendar.getTime());
			listDateParam.add(date);
			beginCalendar.add(Calendar.MONTH, 1);
		}

		Date bulan = new Date();
		int i = 0;
		for (String tglAwal : listDateParam) {
			String tglAkhir = "";

			Calendar cal = Calendar.getInstance();
			if (year.format(today).equals(tahun)) {
				bulan = cal.getTime();

				if (listDateParam.size() - 1 != i) {
					try {
						cal.setTime(formater.parse(tglAwal));
						bulan = cal.getTime();
					} catch (ParseException e) {
						e.printStackTrace();
					}
					cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
					cal.add(Calendar.HOUR_OF_DAY, 24);
					cal.set(Calendar.SECOND, (cal.get(Calendar.SECOND) - 1));
				}

				tglAkhir = formater.format(cal.getTime());
			} else {
				bulan = cal.getTime();

				try {
					cal.setTime(formater.parse(tglAwal));
					bulan = cal.getTime();
				} catch (ParseException e) {
					e.printStackTrace();
				}
				cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
				cal.add(Calendar.HOUR_OF_DAY, 24);
				cal.set(Calendar.SECOND, (cal.get(Calendar.SECOND) - 1));

				tglAkhir = formater.format(cal.getTime());
			}

			Map<String, Object> mapRs = calculateIndikatorPelayanan(tglAwal, tglAkhir);
			mapRs.put("bulan", month.format(bulan));

			i++;

			result.add(mapRs);
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findKunjunganHarianPasienRuangan(String tglAwal, String tglAkhir,
			Integer idDepartemen, Integer idRuangan) throws ParseException {
		List<Map<String, Object>> result = new ArrayList<>();
		List<Map<String, Object>> data = new ArrayList<>();
		List<String> listTglRegistrasi = new ArrayList<>();

		DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date beginDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(tglAwal);
		Date endDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(tglAkhir);

		if (CommonUtil.isNullOrEmpty(idDepartemen) && CommonUtil.isNullOrEmpty(idRuangan)) {
			data = pasienDaftarDao.getKunjunganHarianPasien(beginDate, endDate);
		} else if (CommonUtil.isNotNullOrEmpty(idDepartemen) && CommonUtil.isNullOrEmpty(idRuangan)) {
			data = pasienDaftarDao.getKunjunganHarianPasienDepartemen(beginDate, endDate, idDepartemen);
		} else if (CommonUtil.isNotNullOrEmpty(idDepartemen) && CommonUtil.isNotNullOrEmpty(idRuangan)) {
			data = pasienDaftarDao.getKunjunganHarianPasienRuangan(beginDate, endDate, idDepartemen, idRuangan);
		}

		for (Map<String, Object> map : data) {
			if (!listTglRegistrasi.contains(map.get("tglRegistrasi").toString())) {
				listTglRegistrasi.add(map.get("tglRegistrasi").toString());
			}
		}

		for (String tglRegis : listTglRegistrasi) {
			Map<String, Object> mapRs = new HashMap<>();
			for (Map<String, Object> map : data) {
				if (tglRegis.equals(map.get("tglRegistrasi").toString())) {
					mapRs.put("tglRegistrasi", new SimpleDateFormat("dd MMMM yyyy", new java.util.Locale("id"))
							.format(sdf.parse(map.get("tglRegistrasi").toString())));
					if (map.get("statusPasien").toString().equals("BARU")) {
						mapRs.put("pasienBaru", map.get("jumlahKunjungan"));
					} else if (map.get("statusPasien").toString().equals("LAMA")) {
						mapRs.put("pasienLama", map.get("jumlahKunjungan"));
					}
				}
			}
			if (CommonUtil.isNullOrEmpty(mapRs.get("pasienBaru"))) {
				mapRs.put("pasienBaru", 0);
			}
			if (CommonUtil.isNullOrEmpty(mapRs.get("pasienLama"))) {
				mapRs.put("pasienLama", 0);
			}
			mapRs.put("total", Integer.parseInt(mapRs.get("pasienBaru").toString())
					+ Integer.parseInt(mapRs.get("pasienLama").toString()));
			result.add(mapRs);
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findRekapDiskon(Long periode) {
		Date start = DateUtil.startMonth(periode);
		Date end = DateUtil.endMonth(periode);
		List<Map<String, Object>> result = pasienDaftarDao.findRekapDiskon(start, end);

		return result;
	}

	@Override
	public List<Map<String, Object>> findLogRekapDiskon(String norecPd, String norecSp) {
		List<Map<String, Object>> result = pasienDaftarDao.findLogRekapDiskon(norecPd, "Verifikasi Order Laboratorium",
				norecSp, "Verifikasi TataRekening");

		return result;
	}
}
