package com.jasamedika.medifirst2000.service.impl;

import java.util.ArrayList;
import java.util.Date;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import com.jasamedika.medifirst2000.converter.KamarConverter;
import com.jasamedika.medifirst2000.converter.KasusPenyakitConverter;
import com.jasamedika.medifirst2000.converter.RegistrasiPelayananPasienConverter;
import com.jasamedika.medifirst2000.converter.RuanganConverter;
import com.jasamedika.medifirst2000.converter.TempatTidurConverter;
import com.jasamedika.medifirst2000.converter.base.BaseVoConverter;
import com.jasamedika.medifirst2000.dao.AntrianPasienDiPeriksaDao;
import com.jasamedika.medifirst2000.dao.AntrianPasienRegistrasiDao;
import com.jasamedika.medifirst2000.dao.OrderPelayananDao;
import com.jasamedika.medifirst2000.dao.PasienDaftarDao;
import com.jasamedika.medifirst2000.dao.RegistrasiPelayananPasienDao;
import com.jasamedika.medifirst2000.dao.StatusBedDao;
import com.jasamedika.medifirst2000.dao.TempatTidurDao;
import com.jasamedika.medifirst2000.dto.AntrianPasien;
import com.jasamedika.medifirst2000.entities.AntrianPasienDiPeriksa;
import com.jasamedika.medifirst2000.entities.AntrianPasienRegistrasi;
import com.jasamedika.medifirst2000.entities.HasilTriase;
import com.jasamedika.medifirst2000.entities.Kamar;
import com.jasamedika.medifirst2000.entities.KasusPenyakit;
import com.jasamedika.medifirst2000.entities.OrderPelayanan;
import com.jasamedika.medifirst2000.entities.PapKebutuhanEdukasi;
import com.jasamedika.medifirst2000.entities.Pasien;
import com.jasamedika.medifirst2000.entities.PasienDaftar;
import com.jasamedika.medifirst2000.entities.PersetujuanUmum;
import com.jasamedika.medifirst2000.entities.RegistrasiPelayananPasien;
import com.jasamedika.medifirst2000.entities.Ruangan;
import com.jasamedika.medifirst2000.entities.TempatTidur;
import com.jasamedika.medifirst2000.enums.StatusAntrianEnum;
import com.jasamedika.medifirst2000.exception.ServiceVOException;
import com.jasamedika.medifirst2000.service.PasienDaftarService;
import com.jasamedika.medifirst2000.service.PasienService;
import com.jasamedika.medifirst2000.service.PersetujuanUmumService;
import com.jasamedika.medifirst2000.service.RegistrasiPelayananPasienService;
import com.jasamedika.medifirst2000.service.SuratPermintaanMasukService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.util.DateUtil;
import com.jasamedika.medifirst2000.vo.HasilTriaseVO;
import com.jasamedika.medifirst2000.vo.MasukKamarVO;
import com.jasamedika.medifirst2000.vo.OrderPelayananCustomVO;
import com.jasamedika.medifirst2000.vo.PemeriksaanSelanjutnyaVO;
import com.jasamedika.medifirst2000.vo.PersetujuanUmumVO;
import com.jasamedika.medifirst2000.vo.RegistrasiPelayananPasienVO;
import com.jasamedika.medifirst2000.vo.RegistrasiPelayananVO;
import com.jasamedika.medifirst2000.vo.SuratPermintaanMasukVO;

/**
 * Implement class for PasienService
 * 
 * @author Adik
 * @param <T>
 */

@Service("registrasiPelayananPasienService")
public class RegistrasiPelayananPasienServiceImpl extends BaseVoServiceImpl
		implements RegistrasiPelayananPasienService {

	@Autowired
	private RegistrasiPelayananPasienDao registrasiPelayananPasienDao;
	@Autowired
	private TempatTidurDao tempatTidurDao;

	@Autowired
	private OrderPelayananDao orderPelayananDao;

	@Autowired
	private StatusBedDao statusBedDao;

	@Autowired
	private AntrianPasienRegistrasiDao antrianPasienRegistrasiDao;

	@Autowired
	private RegistrasiPelayananPasienConverter registrasiPelayananPasienConverter;

	@Autowired
	private KasusPenyakitConverter kasusPenyakitConverter;

	@Autowired
	private TempatTidurConverter tempatTidurConverter;

	@Autowired
	private AntrianPasienDiPeriksaDao antrianPasienDiPeriksaDao;

	@Autowired
	private PasienDaftarDao pasienDaftarDao;

	@Autowired
	private BaseVoConverter<HasilTriaseVO, HasilTriase> hasilTriaseConverter;

	@Autowired
	private RuanganConverter ruanganConverter;

	@Autowired
	private KamarConverter kamarConverter;

	@Autowired
	private PasienService pasienService;

	@Autowired
	private PasienDaftarService pasienDaftarService;

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

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

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

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

	@Override
	public List findAll() throws JpaSystemException {
		List<RegistrasiPelayananPasienVO> vos = new ArrayList<RegistrasiPelayananPasienVO>();
		List<RegistrasiPelayananPasien> models = (List<RegistrasiPelayananPasien>) registrasiPelayananPasienDao
				.findAll();
		registrasiPelayananPasienConverter.transferListOfModelToListOfVO(models, vos);
		return vos;
	}

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

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

		countByMonthAndYear = registrasiPelayananPasienDao.getCountByMonthAndYear(month, year);
		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;
	}

	@Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE)
	public Map<String, Object> createRegistrasiPelayananPasien(String noRegistrasi, HasilTriaseVO hasilTriaseVO) {

		RegistrasiPelayananPasien registrasiPelayananPasien = new RegistrasiPelayananPasien();
		AntrianPasienDiPeriksa antrianPasienDiPeriksa = null;
		List<AntrianPasienDiPeriksa> list = antrianPasienDiPeriksaDao.findByNoRegister(noRegistrasi);
		if (list.size() != 0) {
			antrianPasienDiPeriksa = list.get(0);
		}
		List<PasienDaftar> pasienDaftarList = pasienDaftarDao.findAll(noRegistrasi);
		PasienDaftar pasienDaftar = pasienDaftarList.get(0);

		// String noMasuk=getFormatNumberByMonthYear();

		if (CommonUtil.isNotNullOrEmpty(antrianPasienDiPeriksa)) {
			registrasiPelayananPasien.setAsalRujukan(antrianPasienDiPeriksa.getAsalRujukan());
			registrasiPelayananPasien.setKamar(antrianPasienDiPeriksa.getKamar());
			registrasiPelayananPasien.setPasienDaftar(antrianPasienDiPeriksa.getPasienDaftar());
			registrasiPelayananPasien.setKasusPenyakit(antrianPasienDiPeriksa.getKasusPenyakit());
			registrasiPelayananPasien.setRuangan(antrianPasienDiPeriksa.getRuangan());
			registrasiPelayananPasien.setNoAntrian(antrianPasienDiPeriksa.getNoAntrian());
			registrasiPelayananPasien.setNoBedTujuan(antrianPasienDiPeriksa.getNoBed());
			registrasiPelayananPasien.setTglMasuk(antrianPasienDiPeriksa.getTglRegistrasi());

		} else {
			registrasiPelayananPasien.setPasienDaftar(pasienDaftar);
			registrasiPelayananPasien.setKasusPenyakit(pasienDaftar.getKasusPenyakit());
			registrasiPelayananPasien.setRuangan(pasienDaftar.getRuangan());
			registrasiPelayananPasien.setKelompokPasien(pasienDaftar.getKelompokPasien());
			registrasiPelayananPasien.setTglMasuk(pasienDaftar.getTglRegistrasi());
		}
		if (CommonUtil.isNotNullOrEmpty(hasilTriaseVO)) {
			registrasiPelayananPasien
					.setHasilTriase(hasilTriaseConverter.transferVOToModel(hasilTriaseVO, new HasilTriase()));
		}

		RegistrasiPelayananPasien hasil = registrasiPelayananPasienDao.save(registrasiPelayananPasien);
		Map<String, Object> result = new HashMap<String, Object>();
		if (CommonUtil.isNotNullOrEmpty(hasil)) {
			result.put("noRec", hasil.getNoRec());
			result.put("noAntrian", hasil.getNoAntrian());
			result.put("message",
					"Silahkan Mengantri Di ruangan Tujuan dengan Nomor Antrian : " + hasil.getNoAntrian());
			if (CommonUtil.isNotNullOrEmpty(hasil.getPasienDaftar())) {
				if (CommonUtil.isNotNullOrEmpty(hasil.getPasienDaftar().getPasien())) {
					result.put("noCm", hasil.getPasienDaftar().getPasien().getNoCm());
				}
				result.put("noRegistrasi", hasil.getPasienDaftar().getNoRegistrasi());
			}
		}
		// edit by askur 03082016
		// int num1=30, num2=0;
		// int output=num1/num2;
		// System.out.println ("Result = " +output);
		//
		return result;
	}

	@Override
	public Map<String, Object> updateRegistrasiPelayananPasien(PemeriksaanSelanjutnyaVO vo) {
		RegistrasiPelayananPasien registrasiPelayananPasien = registrasiPelayananPasienDao
				.finByNoCm(vo.getPasien().getNoCm(), (short) 0, vo.getTglMasuk());

		registrasiPelayananPasien.setTglPeriksaNext(vo.getTglPeriksaNext());
		registrasiPelayananPasien.setKeteranganLainnyaPeriksaNext(vo.getKeteranganLainnyaPeriksaNext());
		registrasiPelayananPasien.setTglMasuk(vo.getTglMasuk());

		if (CommonUtil.isNotNullOrEmpty(vo.getKasusPenyakit())) {
			registrasiPelayananPasien.setKasusPenyakit(
					kasusPenyakitConverter.transferVOToModel(vo.getKasusPenyakit(), new KasusPenyakit()));
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getRuangan())) {
			registrasiPelayananPasien.setRuangan(ruanganConverter.transferVOToModel(vo.getRuangan(), new Ruangan()));
		}
		Map<String, Object> result = new HashMap<String, Object>();
		RegistrasiPelayananPasien hasil = registrasiPelayananPasienDao.save(registrasiPelayananPasien);

		if (CommonUtil.isNotNullOrEmpty(hasil)) {
			result.put("noRec", hasil.getNoRec());
			result.put("noAntrian", hasil.getNoAntrian());
			if (CommonUtil.isNotNullOrEmpty(hasil.getPasienDaftarId())) {
				if (CommonUtil.isNotNullOrEmpty(hasil.getPasienDaftar().getPasienId())) {
					result.put("noCm", hasil.getPasienDaftar().getPasien().getNoCm());
				}
				result.put("noRegistrasi", hasil.getPasienDaftar().getNoRegistrasi());
			}
		}
		return result;
	}

	@Autowired
	private SuratPermintaanMasukService suratPermintaanMasukService;

	@Override
	public Map<String, Object> createRegistrasiPelayananPasienFromMasukRuangan(PasienDaftar pasienDaftar,
			MasukKamarVO vo) {
		RegistrasiPelayananPasien registrasiPelayananPasien = new RegistrasiPelayananPasien();

		registrasiPelayananPasien.setPasienDaftar(pasienDaftar);
		registrasiPelayananPasien.setKasusPenyakit(pasienDaftar.getKasusPenyakit());
		registrasiPelayananPasien.setRuangan(pasienDaftar.getRuangan());
		registrasiPelayananPasien.setKelompokPasien(pasienDaftar.getKelompokPasien());
		registrasiPelayananPasien.setTglMasuk(new Date());
		if (CommonUtil.isNotNullOrEmpty(vo.getKamar())) {
			registrasiPelayananPasien.setKamar(kamarConverter.transferVOToModel(vo.getKamar(), new Kamar()));
		}
		if (CommonUtil.isNotNullOrEmpty(vo.getTempatTidur())) {
			registrasiPelayananPasien
					.setTempatTidur(tempatTidurConverter.transferVOToModel(vo.getTempatTidur(), new TempatTidur()));
			TempatTidur tempatTidur = tempatTidurDao.findOne(registrasiPelayananPasien.getTempatTidur().getId());
			if (tempatTidur != null)
				tempatTidur.setStatusBed(statusBedDao.findOne((Integer) 1));
			tempatTidurDao.save(tempatTidur);

		}
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("registrasiPelayananPasien", registrasiPelayananPasienDao.save(registrasiPelayananPasien));
		SuratPermintaanMasukVO persetujuanUmum = new SuratPermintaanMasukVO();
		persetujuanUmum.setNoRec(vo.getNoRec());
		RegistrasiPelayananPasienVO register = new RegistrasiPelayananPasienVO();
		register.setNoRec(registrasiPelayananPasien.getNoRec());
		persetujuanUmum.setNoMasukTujuan(register);
		suratPermintaanMasukService.updateStatusRegistrasi(persetujuanUmum);
		return result;

	}

	@Override
	public RegistrasiPelayananPasien findByNoCm(String noCm) {
		RegistrasiPelayananPasien model = registrasiPelayananPasienDao.findPasienByNoCM(noCm);
		return model;
	}

	// @Override
	// public Map findNoCm(String noCm) {
	// Map<String,Object> result=new HashMap<String,Object>();
	// RegistrasiPelayananPasien resultModel=
	// registrasiPelayananPasienDao.finByNoCM(noCm);
	// if(CommonUtil.isNotNullOrEmpty(resultModel)){
	// result.put("noRec", resultModel.getNoRec());
	//
	// result.put("dataFound", true);
	// if(CommonUtil.isNotNullOrEmpty(resultModel.getPasien().getId())){
	// result.put("pasien.noCm", resultModel.getPasien().getNoCm());
	// }
	// } else {
	// result.put("dataFound", false);
	// }
	// return result;
	// }

	@Override
	public Map<String, Object> findNoCm(String noCm) {
		try {
			return registrasiPelayananPasienDao.findPasienByNoCM(noCm).ToMap();
		} catch (IllegalArgumentException | IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public RegistrasiPelayananPasien findByNoRec(String noRec) {
		return null;
	}

	@Override
	public List findPasien(Integer id) {
		List<Pasien> list = new ArrayList<Pasien>();
		Pasien pasien = pasienService.findPasienById(id);
		list.add(pasien);
		return list;
	}

	@Override
	public List findAllPasien(String startDate, String endDate) {
		List<PasienDaftar> data = pasienDaftarService.findAllPasienDaftar(startDate, endDate);
		List<PasienDaftar> list = new ArrayList<PasienDaftar>();
		list.addAll(data);
		return list;
	}

	@Override
	public List findAntrian(String noRec) {
		AntrianPasienRegistrasi antrianPasienRegistrasi = antrianPasienRegistrasiDao.findByNoRec(noRec);
		List list = new ArrayList();
		Long count = (long)0;
		AntrianPasien antrian = new AntrianPasien();
		if (antrianPasienRegistrasi != null) {
			// list.add(antrianPasienRegistrasi);
			antrian.setJenis(antrianPasienRegistrasi.getJenis());
			antrian.setNoUrut(antrianPasienRegistrasi.getNoAntrian());

			antrian.setNoAntrian(antrian.getJenis() + "-" + antrian.getNoUrut());
			count = antrianPasienRegistrasiDao.getCount(antrian.getJenis());
			antrian.setTotalAntrian(count.toString());
			list.add(antrian);
		} else {
			AntrianPasienRegistrasi local = new AntrianPasienRegistrasi();
			local.setNoAntrian(1);
			antrian.setJenis("A");
			antrian.setNoUrut(1);
			antrian.setNoAntrian("A-1");
			count = antrianPasienRegistrasiDao.getCount(antrian.getJenis());
			antrian.setTotalAntrian(count.toString());
			list.add(antrian);
			// list.add(local);
		}
		
		return list;
	}

	@Override
	public AntrianPasien getNomorUrutPasienbyJenis(String jenis) {
		Integer noUrut = antrianPasienRegistrasiDao.getCurrentAntrian(jenis);

		AntrianPasien antrian = new AntrianPasien();
		antrian.setJenis(jenis);
		antrian.setNoUrut(noUrut);
		antrian.setNoAntrian(jenis + "-" + noUrut);

		return antrian;

	}

	 @Transactional(readOnly = false)
	 @Override
	 public void updateNomorUrutPasienbyJenis(Integer noAntrian, String jenis) {
		 antrianPasienRegistrasiDao.updateSudahNoAntrian(jenis);
	 antrianPasienRegistrasiDao.updatePanggilNoAntrian(noAntrian, jenis);
	 }

	// @PersistenceContext
	// protected EntityManager em;
	//
	// @Transactional(readOnly = false)
	// @Override
	// public void updateNomorUrutPasienbyJenis(Integer noAntrian, String jenis) {
	// Query query = em.createQuery("Update AntrianPasienRegistrasi p set
	// p.statusPanggil = '2' "
	// + "Where p.statusPanggil = '1' and p.jenis=?1");
	//
	// query.setParameter(1, jenis);
	// query.executeUpdate();
	//
	// query = em.createQuery("Update AntrianPasienRegistrasi p set p.statusPanggil
	// = '1' "
	// + "Where p.noAntrian = ?1 and p.jenis=?2");
	//
	// query.setParameter(1, noAntrian);
	// query.setParameter(2, jenis);
	//
	// query.executeUpdate();
	//
	// }

}
