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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jasamedika.medifirst2000.converter.BaseConverterImpl;
import com.jasamedika.medifirst2000.dao.AdmisiRencanaPindahRuanganDao;
import com.jasamedika.medifirst2000.dao.AntrianPasienDiPeriksaDao;
import com.jasamedika.medifirst2000.dao.KamarDao;
import com.jasamedika.medifirst2000.dao.RegistrasiPelayananPasienDao;
import com.jasamedika.medifirst2000.dao.TempatTidurDao;
import com.jasamedika.medifirst2000.dao.custom.AdmisiRencanaPindahRuanganDaoCustom;
import com.jasamedika.medifirst2000.entities.AdmisiRencanaPindahRuangan;
import com.jasamedika.medifirst2000.entities.AntrianPasienDiPeriksa;
import com.jasamedika.medifirst2000.entities.Kamar;
import com.jasamedika.medifirst2000.entities.Kelas;
import com.jasamedika.medifirst2000.entities.RegistrasiPelayananPasien;
import com.jasamedika.medifirst2000.entities.Ruangan;
import com.jasamedika.medifirst2000.entities.StatusBed;
import com.jasamedika.medifirst2000.entities.StatusKeluar;
import com.jasamedika.medifirst2000.entities.TempatTidur;
import com.jasamedika.medifirst2000.service.AdmisiRencanaPindahRuanganService;
import com.jasamedika.medifirst2000.service.RegistrasiPelayananService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.vo.AdmisiRencanaPindahRuanganVO;
import com.jasamedika.medifirst2000.vo.AntrianPasienDiPeriksaVO;
import com.jasamedika.medifirst2000.vo.KamarVO;
import com.jasamedika.medifirst2000.vo.KelasVO;
import com.jasamedika.medifirst2000.vo.RegistrasiPelayananPasienVO;
import com.jasamedika.medifirst2000.vo.RuanganVO;
import com.jasamedika.medifirst2000.vo.StatusKeluarVO;

@Service("admisiRencanaPindahRuanganService")
public class AdmisiRencanaPindahRuanganServiceImpl implements AdmisiRencanaPindahRuanganService{

	@Autowired
	private AdmisiRencanaPindahRuanganDao admisiRencanaPindahRuanganDao;
	
	@Autowired
	private RegistrasiPelayananPasienDao registrasiPelayananPasienDao;
	
	@Autowired
	private KamarDao kamarDao;
	
	@Autowired
	private TempatTidurDao tempatTidurDao;
	
	@Autowired
	private BaseConverterImpl<AdmisiRencanaPindahRuanganVO, AdmisiRencanaPindahRuangan> admisiRencanaPindahRuanganConverter;
	
	@Autowired
	private BaseConverterImpl<AntrianPasienDiPeriksaVO, AntrianPasienDiPeriksa> registrasiPelayananPasienConverter;
	
	@Autowired
	private BaseConverterImpl<KelasVO, Kelas> kelasConverter;
	
	@Autowired
	private BaseConverterImpl<RuanganVO, Ruangan> ruanganConverter;
	
	@Autowired
	private BaseConverterImpl<KamarVO, Kamar> kamarConverter;
	
	@Autowired
	private BaseConverterImpl<StatusKeluarVO, StatusKeluar> statusKeluarConverter;
	
	@Autowired
	private AdmisiRencanaPindahRuanganDaoCustom admisiRencanaPindahRuanganDaoCustom;
	
	@Autowired
	private AntrianPasienDiPeriksaDao antrianPasienDiPeriksaDao;
	
	@Override
	public Map<String, Object> save(AdmisiRencanaPindahRuanganVO vo){
		Map<String, Object> result = new HashMap<>();
		AdmisiRencanaPindahRuangan admisiRencanaPindahRuangan = admisiRencanaPindahRuanganConverter.transferVOToModel(vo, new AdmisiRencanaPindahRuangan());
		//----------------------------------------------------
		if(CommonUtil.isNotNullOrEmpty(vo.getRegistrasiPelayananPasien())){
			admisiRencanaPindahRuangan.setRegistrasiPelayananPasien(registrasiPelayananPasienConverter.transferVOToModel(vo.getRegistrasiPelayananPasien(), new AntrianPasienDiPeriksa()));
		}
		if(CommonUtil.isNotNullOrEmpty(vo.getKelasAwal())){
			admisiRencanaPindahRuangan.setKelasAwal(kelasConverter.transferVOToModel(vo.getKelasAwal(), new Kelas()));
		}
		if(CommonUtil.isNotNullOrEmpty(vo.getRuanganAwal())){
			admisiRencanaPindahRuangan.setRuanganAwal(ruanganConverter.transferVOToModel(vo.getRuanganAwal(), new Ruangan()));
		}
		if(CommonUtil.isNotNullOrEmpty(vo.getKelasKamarAwal())){
			admisiRencanaPindahRuangan.setKelasKamarAwal(kamarConverter.transferVOToModel(vo.getKelasKamarAwal(), new Kamar()));
		}
		//----------------------------------------------------
		if(CommonUtil.isNotNullOrEmpty(vo.getKelasRencana())){
			admisiRencanaPindahRuangan.setKelasRencana(kelasConverter.transferVOToModel(vo.getKelasRencana(), new Kelas()));
		}
		if(CommonUtil.isNotNullOrEmpty(vo.getRuanganRencana())){
			admisiRencanaPindahRuangan.setRuanganRencana(ruanganConverter.transferVOToModel(vo.getRuanganRencana(), new Ruangan()));
		}
		if(CommonUtil.isNotNullOrEmpty(vo.getKelasKamarRencana())){
			admisiRencanaPindahRuangan.setKelasKamarRencana(kamarConverter.transferVOToModel(vo.getKelasKamarRencana(), new Kamar()));
		}
		if(CommonUtil.isNotNullOrEmpty(vo.getNoBedRencana())){
			admisiRencanaPindahRuangan.setNoBedRencana(vo.getNoBedRencana());
		}
		if(CommonUtil.isNotNullOrEmpty(vo.getKeteranganLainya())){
			admisiRencanaPindahRuangan.setKeteranganLainya(vo.getKeteranganLainya());
		}
		admisiRencanaPindahRuangan.setStatusKeluarRencana(null);
		//----------------------------------------------------
		if(CommonUtil.isNotNullOrEmpty(admisiRencanaPindahRuangan)){
			AdmisiRencanaPindahRuangan paketKunjunganPasienResult = admisiRencanaPindahRuanganDao.save(admisiRencanaPindahRuangan);
			result.put("noRec", paketKunjunganPasienResult.noRec);
		}
		return result; 	
		
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> update(AdmisiRencanaPindahRuanganVO vo){
		Map<String, Object> result = new HashMap<>();
		
		AdmisiRencanaPindahRuangan admisiRencanaPindahRuangan = admisiRencanaPindahRuanganDao.findOne(vo.getNoRec());
		
		if(CommonUtil.isNotNullOrEmpty(admisiRencanaPindahRuangan)) {
			if(CommonUtil.isNotNullOrEmpty(admisiRencanaPindahRuangan.getRegistrasiPelayananPasien())) {
				AntrianPasienDiPeriksa antrianPasienDiperiksaBefore = antrianPasienDiPeriksaDao.findOne(admisiRencanaPindahRuangan.getRegistrasiPelayananPasien().getNoRec());
				RegistrasiPelayananPasien registrasiPelayananPasien = registrasiPelayananPasienDao.findPasien(vo.getNoRecRegistrasiPelayananPasien());
				AntrianPasienDiPeriksa antrianPasienDiperiksa = new AntrianPasienDiPeriksa();
				//set statusenabled antrianPasienDiperiksaBefore as false and set tgl keluar and then save it
				antrianPasienDiperiksaBefore.setStatusEnabled(false);
				antrianPasienDiperiksaBefore.setTglKeluar(new Date());				
				//set norec of antrianPasienDiperiksa is null to create the new antrianPasienDiperiksa
				antrianPasienDiperiksa.setNoAntrian(antrianPasienDiperiksaBefore.getNoAntrian());
				antrianPasienDiperiksa.setAsalRujukan(antrianPasienDiperiksaBefore.getAsalRujukan());
				antrianPasienDiperiksa.setPegawai(antrianPasienDiperiksaBefore.getPegawai());
				antrianPasienDiperiksa.setStatusAntrian(antrianPasienDiperiksaBefore.getStatusAntrian());
				antrianPasienDiperiksa.setStatusKunjungan(antrianPasienDiperiksaBefore.getStatusKunjungan());
				antrianPasienDiperiksa.setStatusPasien(antrianPasienDiperiksaBefore.getStatusPasien());
				antrianPasienDiperiksa.setTglRegistrasi(antrianPasienDiperiksaBefore.getTglRegistrasi());
				antrianPasienDiperiksa.setPasienDaftar(antrianPasienDiperiksaBefore.getPasienDaftar());
				antrianPasienDiperiksa.setStatusEnabled(true);
				antrianPasienDiperiksa.setTglMasuk(new Date());
				if(CommonUtil.isNotNullOrEmpty(vo.getKelasRencana())) {
					admisiRencanaPindahRuangan.setKelasRencana(kelasConverter.transferVOToModel(vo.getKelasRencana(), new Kelas()));
					antrianPasienDiperiksa.setKelas(kelasConverter.transferVOToModel(vo.getKelasRencana(), new Kelas()));
					if(CommonUtil.isNotNullOrEmpty(antrianPasienDiperiksa.getPasienDaftar())) {
						antrianPasienDiperiksa.getPasienDaftar().setKelas(kelasConverter.transferVOToModel(vo.getKelasRencana(), new Kelas()));
					}
				}
				if(CommonUtil.isNotNullOrEmpty(vo.getRuanganRencana())) {
					admisiRencanaPindahRuangan.setRuanganRencana(ruanganConverter.transferVOToModel(vo.getRuanganRencana(), new Ruangan()));
					antrianPasienDiperiksa.setRuangan(ruanganConverter.transferVOToModel(vo.getRuanganRencana(), new Ruangan()));
					if(CommonUtil.isNotNullOrEmpty(antrianPasienDiperiksa.getPasienDaftar())) {
						antrianPasienDiperiksa.getPasienDaftar().setRuangan(ruanganConverter.transferVOToModel(vo.getRuanganRencana(), new Ruangan()));
					}
				}
				if(CommonUtil.isNotNullOrEmpty(vo.getKelasKamarRencana())){
					admisiRencanaPindahRuangan.setKelasKamarRencana(kamarConverter.transferVOToModel(vo.getKelasKamarRencana(), new Kamar()));
					antrianPasienDiperiksa.setKamar(kamarConverter.transferVOToModel(vo.getKelasKamarRencana(), new Kamar()));
				}
				StatusKeluar statusKeluar = new StatusKeluar();
				statusKeluar.setId(2);
				if(CommonUtil.isNotNullOrEmpty(statusKeluar)){					
					admisiRencanaPindahRuangan.setStatusKeluarRencana(statusKeluar);
				}
				if(CommonUtil.isNotNullOrEmpty(vo.getNoBedRencana())){
					admisiRencanaPindahRuangan.setNoBedRencana(vo.getNoBedRencana());
					antrianPasienDiperiksa.setNoBed(vo.getNoBedRencana());
				}
				if(CommonUtil.isNotNullOrEmpty(vo.getKeteranganLainya())){
					admisiRencanaPindahRuangan.setKeteranganLainya(vo.getKeteranganLainya());
				}
				if(CommonUtil.isNotNullOrEmpty(vo.getKelasKamarRencana())){
					Kamar kamar = kamarDao.findOne(vo.getKelasKamarRencana().getId());
					if (CommonUtil.isNotNullOrEmpty(kamar)) {
						Integer jumlahKamarIsi = kamar.getJumlaKamarIsi() + 1;
						if (CommonUtil.isNotNullOrEmpty(jumlahKamarIsi)) {
							kamar.setJumlaKamarIsi(jumlahKamarIsi);
						}
						Integer jumlahKamarKosong = kamar.getJumlaKamarKosong() - 1;
						if (CommonUtil.isNotNullOrEmpty(jumlahKamarKosong)) {
							kamar.setJumlaKamarKosong(jumlahKamarKosong);
						}
						if (CommonUtil.isNotNullOrEmpty(kamar)) {
							Kamar resultKamar = kamarDao.save(kamar);
							if(CommonUtil.isNotNullOrEmpty(resultKamar) && CommonUtil.isNotNullOrEmpty(registrasiPelayananPasien))
							{
								if(CommonUtil.isNotNullOrEmpty(registrasiPelayananPasien.getKamar()))
								{
									tambahKamarKosong(registrasiPelayananPasien.getKamarId(),result);
								}
							}
						}
					}
				}
				if(CommonUtil.isNotNullOrEmpty(vo.getTempatTidur())){
					TempatTidur tempatTidur = tempatTidurDao.findOne(vo.getTempatTidur().getId());
					StatusBed statusBed = new StatusBed();
					statusBed.setId(1);

					if (CommonUtil.isNotNullOrEmpty(tempatTidur)) {
						tempatTidur.setStatusBed(statusBed);
						TempatTidur resultTempatTidur = tempatTidurDao.save(tempatTidur);
						if(CommonUtil.isNotNullOrEmpty(resultTempatTidur)&& CommonUtil.isNotNullOrEmpty(registrasiPelayananPasien))
						{
							if(CommonUtil.isNotNullOrEmpty(registrasiPelayananPasien.getTempatTidur()))
							{
								tambahBedKosong(registrasiPelayananPasien.getTempatTidur().getId(), result);
							}
						}
					}
				}
				if(CommonUtil.isNotNullOrEmpty(admisiRencanaPindahRuangan)){
					AdmisiRencanaPindahRuangan paketKunjunganPasienResult = admisiRencanaPindahRuanganDao.save(admisiRencanaPindahRuangan);
					AntrianPasienDiPeriksa newAntrianPasienDiPeriksa = antrianPasienDiPeriksaDao.save(antrianPasienDiperiksa);
					AntrianPasienDiPeriksa lastAntrianPasienDiPeriksa = antrianPasienDiPeriksaDao.save(antrianPasienDiperiksaBefore);
					result.put("noRec", paketKunjunganPasienResult.noRec);
					result.put("noRecAntrianLama", lastAntrianPasienDiPeriksa.noRec);
					result.put("noRecAntrianBaru", newAntrianPasienDiPeriksa.noRec);
				}
			}
			
		}
		return result; 
	}
	
	@Override
	public Map<String, Object> getDataGrid(String startDate, String endDate){
		Map<String, Object> result = new HashMap<>();
		
		List<Map<String, Object>> listData = new ArrayList<>();
		for(Map<String, Object> data : admisiRencanaPindahRuanganDao.getDataGrid(startDate,endDate)){
			if(data.get("status")==null){
				data.put("status", "Pengajuan Pindah");
			}
			listData.add(data);
		}
		if(CommonUtil.isNotNullOrEmpty(listData)){
			result.put("listData", listData);
		}
		return result; 
	}
	
	@Override
	public Map<String, Object> getOneDataGrid(String noRec){
		Map<String, Object> result = new HashMap<>();
		
		if(CommonUtil.isNotNullOrEmpty(noRec)) {
			AdmisiRencanaPindahRuangan admisiRencanaPindahRuangan = admisiRencanaPindahRuanganDao.findOne(noRec);
			try {
				result.put("admisiRencanaPindahRuangan", admisiRencanaPindahRuangan.ToMap());
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		
		return result;
	}

	@Override
	public Map<String, Object> findAdmisiRencana(Integer page, Integer limit, String sort, String dir, String tanggalAwal,
			String tanggalAhir) {

		int totalRow = admisiRencanaPindahRuanganDaoCustom.findCountAdmisi(tanggalAwal, tanggalAhir);
		int totalPages = 0;

		int pageRequested = page;

		if (totalRow > 0) {
			totalPages = (int) Math.ceil((double) totalRow / (double) limit);
		} else {
			totalPages = 0;
		}

		if (pageRequested > totalPages)
			pageRequested = totalPages;
		int rowStart = pageRequested * limit - limit;
		if (rowStart < 0) {
			rowStart = 0;
		}
		int rowEnd = limit;
		Map<String, Object> result=new HashMap<String,Object>();
		result.put("data", admisiRencanaPindahRuanganDaoCustom.findListAdmisi(rowStart, rowEnd, sort, dir, tanggalAwal, tanggalAhir));
		result.put("totalPages", totalPages);
		result.put("totalRow", totalRow);
		return result;
	}
	
	public void tambahKamarKosong(Integer id,Map<String, Object> result)
	{
		Kamar kamar = kamarDao.findOne(id);

		if (CommonUtil.isNotNullOrEmpty(kamar)) {
			Integer jumlahKamarIsi = kamar.getJumlaKamarIsi() - 1;
			if (CommonUtil.isNotNullOrEmpty(jumlahKamarIsi)) {
				kamar.setJumlaKamarIsi(jumlahKamarIsi);
			}
			Integer jumlahKamarKosong = kamar.getJumlaKamarKosong() + 1;
			if (CommonUtil.isNotNullOrEmpty(jumlahKamarKosong)) {
				kamar.setJumlaKamarKosong(jumlahKamarKosong);
			}
			if (CommonUtil.isNotNullOrEmpty(kamar)) {
				Kamar model = kamarDao.save(kamar);
				result.put("idKamarLama", model.getId());
			}
		}
	}
	public void tambahBedKosong(Integer id,Map<String, Object> result)
	{
		TempatTidur tempatTidur = tempatTidurDao.findOne(id);
		if(CommonUtil.isNotNullOrEmpty(tempatTidur))
		{
			StatusBed statusBed = new StatusBed();
			statusBed.setId(2);
	
			if (CommonUtil.isNotNullOrEmpty(statusBed)) {
				tempatTidur.setStatusBed(statusBed);
			}
			if (CommonUtil.isNotNullOrEmpty(statusBed)) {
				TempatTidur model = tempatTidurDao.save(tempatTidur);
				result.put("idTempatTidurLama", model.getId());
			}
		}
	}

	
	
}
