package com.jasamedika.medifirst2000.service.impl;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.jasamedika.medifirst2000.converter.BaseConverterImpl;
import com.jasamedika.medifirst2000.dao.AntrianPasienDiPeriksaDao;
import com.jasamedika.medifirst2000.dao.DiagnosaPasienDao;
import com.jasamedika.medifirst2000.dao.MapDiagnosisToProdukDao;
import com.jasamedika.medifirst2000.dao.PelayananPasienDao;
import com.jasamedika.medifirst2000.dao.PemakaianAsuransiDao;
import com.jasamedika.medifirst2000.dao.PostingJurnalTransaksiDao;
import com.jasamedika.medifirst2000.entities.AntrianPasienDiPeriksa;
import com.jasamedika.medifirst2000.entities.ChartOfAccount;
import com.jasamedika.medifirst2000.entities.DetailDiagnosaPasien;
import com.jasamedika.medifirst2000.entities.Diagnosa;
import com.jasamedika.medifirst2000.entities.DiagnosaPasien;
import com.jasamedika.medifirst2000.entities.JenisDiagnosa;
import com.jasamedika.medifirst2000.entities.JenisJurnal;
import com.jasamedika.medifirst2000.entities.MapDiagnosaToProduk;
import com.jasamedika.medifirst2000.entities.PelayananPasien;
import com.jasamedika.medifirst2000.entities.PemakaianAsuransi;
import com.jasamedika.medifirst2000.entities.PostingJurnalTransaksi;
import com.jasamedika.medifirst2000.entities.PostingJurnalTransaksiD;
import com.jasamedika.medifirst2000.entities.Produk;
import com.jasamedika.medifirst2000.enums.StatusAntrianEnum;
import com.jasamedika.medifirst2000.enums.StatusPenyakitEnum;
import com.jasamedika.medifirst2000.service.DiagnosaPasienService;
import com.jasamedika.medifirst2000.service.ProdukService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.util.DateUtil;
import com.jasamedika.medifirst2000.util.JsonUtil;
import com.jasamedika.medifirst2000.vo.DetailDiagnosaPasienVO;
import com.jasamedika.medifirst2000.vo.DiagnosaPasienVO;
import com.jasamedika.medifirst2000.vo.DiagnosaVO;
import com.jasamedika.medifirst2000.vo.JenisDiagnosaVO;

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

@Service("diagnosaPasienService")
public class DiagnosaPasienServiceImpl extends BaseVoServiceImpl implements DiagnosaPasienService {

	@Autowired
	private BaseConverterImpl<DiagnosaPasienVO, DiagnosaPasien> diagnosaPasienConverter;

	@Autowired
	private DiagnosaPasienDao diagnosaPasienDao;

	@Autowired
	private BaseConverterImpl<DetailDiagnosaPasienVO, DetailDiagnosaPasien> detailDiagnosaPasienConverter;

	@Autowired
	private BaseConverterImpl<JenisDiagnosaVO, JenisDiagnosa> jenisDiagnosaConverter;

	@Autowired
	private BaseConverterImpl<DiagnosaVO, Diagnosa> diagnosaConverter;

	@Autowired
	private ProdukService produkService;
	@Autowired
	private AntrianPasienDiPeriksaDao antrianPasienDiPeriksaDao;
	@Autowired
	private PemakaianAsuransiDao pemakaianAsuransiDao;
	@Autowired
	private PelayananPasienDao pelayananPasienDao;
	@Autowired
	private MapDiagnosisToProdukDao mapDiagnosisToProdukDao;

	@Autowired
	private PostingJurnalTransaksiDao postingJurnalTransaksiDao;

	@Override
	public Map<String, Object> saveDiagnosaPasien(DiagnosaPasienVO vo) {
		Map<String, Object> result = new HashMap<>();
		
		String pattern = "yyyy-MM-dd";
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		
		if(CommonUtil.isNotNullOrEmpty(vo.getNoRec())) {		
			DiagnosaPasien diagnosaPasien = diagnosaPasienDao.findOne(vo.getNoRec());
			
			Set<DetailDiagnosaPasien> detailDiagnosaPasienSet = new HashSet<>();
			for (DetailDiagnosaPasienVO detailDiagnosaPasienVO : vo.getDiagnosis()) {
				if(detailDiagnosaPasienVO.getJenisDiagnosa().getId()==1) {
					
					for (DetailDiagnosaPasien detailDiagnosaPasien : diagnosaPasien.getDiagnosis()) {
						if(detailDiagnosaPasien.getJenisDiagnosa().getId()==1) {
					
							if(CommonUtil.isNotNullOrEmpty(detailDiagnosaPasienVO.getDiagnosa())) {
								detailDiagnosaPasien.setDiagnosa(diagnosaConverter.transferVOToModel(detailDiagnosaPasienVO.getDiagnosa(), new Diagnosa()));
							}
						}
					}
				} else {
					DetailDiagnosaPasien detailDiagnosaPasien = new DetailDiagnosaPasien();
					
					if (CommonUtil.isNotNullOrEmpty(detailDiagnosaPasienVO)) {
						detailDiagnosaPasien = detailDiagnosaPasienConverter.transferVOToModel(detailDiagnosaPasienVO, new DetailDiagnosaPasien());
						detailDiagnosaPasien.setDiagnosaPasien(diagnosaPasien);
						detailDiagnosaPasien.setTglInputDiagnosa(new Date());
					}
					if (CommonUtil.isNotNullOrEmpty(detailDiagnosaPasienVO.getDiagnosa())) {
						detailDiagnosaPasien.setDiagnosa(diagnosaConverter.transferVOToModel(detailDiagnosaPasienVO.getDiagnosa(), new Diagnosa()));
					}
					if (CommonUtil.isNotNullOrEmpty(detailDiagnosaPasienVO.getJenisDiagnosa())) {
						detailDiagnosaPasien.setJenisDiagnosa(jenisDiagnosaConverter.transferVOToModel(detailDiagnosaPasienVO.getJenisDiagnosa(), new JenisDiagnosa()));
					}
					if (CommonUtil.isNotNullOrEmpty(diagnosaPasien.getPasien())) {
						detailDiagnosaPasien.setPasien(diagnosaPasien.getPasien());
					}
					if (CommonUtil.isNullOrEmpty(detailDiagnosaPasienVO.getNoRec())) {
						List<MapDiagnosaToProduk> listProduk = mapDiagnosisToProdukDao.findProdukByDiagnosa(detailDiagnosaPasien.getDiagnosa().getKdDiagnosa());
	
						if (CommonUtil.isNotNullOrEmpty(listProduk)) {
							Produk produk = listProduk.get(0).getProduk();
	
							if (CommonUtil.isNotNullOrEmpty(produk)) {
								List<PelayananPasien> abc = pelayananPasienDao.findPelayananPasien(diagnosaPasien.getPasien().getNoRec(),
										produk.getId(), format.format(new Date()));
	
								if ((abc.isEmpty())) {
									produkService.postDiagnosa(detailDiagnosaPasien.getDiagnosa().getId().toString(), diagnosaPasien.getPasien());
								}
							}
						}
					}
					if (CommonUtil.isNotNullOrEmpty(detailDiagnosaPasien)) {
						detailDiagnosaPasienSet.add(detailDiagnosaPasien);
					}
				}
				if (CommonUtil.isNotNullOrEmpty(detailDiagnosaPasienSet)) {
					diagnosaPasien.setDiagnosis(detailDiagnosaPasienSet);
				}
			}
			if(CommonUtil.isNotNullOrEmpty(diagnosaPasien)) {
				DiagnosaPasien resultPasien = diagnosaPasienDao.save(diagnosaPasien);
				result.put("noRec", resultPasien.noRec);
				result.put("namaPasien", resultPasien.getPasien().getPasienDaftar().getPasien().getNamaPasien());
				result.put("noCm", resultPasien.getPasien().getPasienDaftar().getPasien().getNoCm());
			}
		}else {
			DiagnosaPasien diagnosaPasien = new DiagnosaPasien();
			// ----------------------------------------------------------------
			AntrianPasienDiPeriksa pasienDaftar = new AntrianPasienDiPeriksa();
			// ----------------------------------------------------------------
	
			if (CommonUtil.isNotNullOrEmpty(vo)) {
				diagnosaPasien = diagnosaPasienConverter.transferVOToModel(vo, new DiagnosaPasien());
				pasienDaftar = antrianPasienDiPeriksaDao.findByNoRec(vo.getNoRecPasienDaftar());
				diagnosaPasien.setTanggalPendaftaran(vo.getTanggalPendaftaran());
			}
	
			if (CommonUtil.isNotNullOrEmpty(pasienDaftar)) {
				diagnosaPasien.setPasien(pasienDaftar);
			}
	
			if (CommonUtil.isNotNullOrEmpty(vo.getDiagnosis())) {
				Set<DetailDiagnosaPasien> detailDiagnosaPasienSet = new HashSet<>();
	
				int count = 0;
				for(DetailDiagnosaPasienVO detailDiagnosaPasienVO : vo.getDiagnosis()) {
					DetailDiagnosaPasien detailDiagnosaPasien = new DetailDiagnosaPasien();
	
					if (CommonUtil.isNotNullOrEmpty(detailDiagnosaPasienVO)) {
						detailDiagnosaPasien = detailDiagnosaPasienConverter.transferVOToModel(detailDiagnosaPasienVO,new DetailDiagnosaPasien());
						detailDiagnosaPasien.setDiagnosaPasien(diagnosaPasien);
						detailDiagnosaPasien.setTglInputDiagnosa(new Date());
					}
					if (CommonUtil.isNotNullOrEmpty(detailDiagnosaPasienVO.getDiagnosa())) {
						detailDiagnosaPasien.setDiagnosa(diagnosaConverter.transferVOToModel(detailDiagnosaPasienVO.getDiagnosa(), new Diagnosa()));
					}
					if (CommonUtil.isNotNullOrEmpty(detailDiagnosaPasienVO.getJenisDiagnosa())) {
						detailDiagnosaPasien.setJenisDiagnosa(jenisDiagnosaConverter.transferVOToModel(detailDiagnosaPasienVO.getJenisDiagnosa(), new JenisDiagnosa()));
					}
					if (CommonUtil.isNotNullOrEmpty(pasienDaftar)) {
						detailDiagnosaPasien.setPasien(pasienDaftar);
					}
					if (CommonUtil.isNullOrEmpty(detailDiagnosaPasienVO.getNoRec())) {
						List<MapDiagnosaToProduk> listProduk = mapDiagnosisToProdukDao.findProdukByDiagnosa(detailDiagnosaPasien.getDiagnosa().getKdDiagnosa());
	
						if (CommonUtil.isNotNullOrEmpty(listProduk)) {
							Produk produk = listProduk.get(0).getProduk();
	
							if (CommonUtil.isNotNullOrEmpty(produk)) {
								List<PelayananPasien> abc = pelayananPasienDao.findPelayananPasien(pasienDaftar.getNoRec(), produk.getId(), format.format(new Date()));
	
								if (count == 0 && (abc.isEmpty())) {
									produkService.postDiagnosa(detailDiagnosaPasien.getDiagnosa().getId().toString(), pasienDaftar);
								}
							}
						}
					}
					if (CommonUtil.isNotNullOrEmpty(detailDiagnosaPasien)) {
						detailDiagnosaPasienSet.add(detailDiagnosaPasien);
					}
					count++;
				}
				if (CommonUtil.isNotNullOrEmpty(detailDiagnosaPasienSet)) {
					diagnosaPasien.setDiagnosis(detailDiagnosaPasienSet);
				}
			}
	
			// ------------------------------------------------------------------
			if (checkDiagnosaPasien(vo.getPasien().getId())) {
				pasienDaftar.setStatusPenyakit(StatusPenyakitEnum.LAMA.getVal());
			} else {
				pasienDaftar.setStatusPenyakit(StatusPenyakitEnum.BARU.getVal());
			}
			// ------------------------------------------------------------------
	
			if (CommonUtil.isNotNullOrEmpty(pasienDaftar)) {
				pasienDaftar.setStatusAntrian(StatusAntrianEnum.SELESAI_DIPERIKSA.getVal());
				antrianPasienDiPeriksaDao.save(pasienDaftar);
			}
			if (CommonUtil.isNotNullOrEmpty(diagnosaPasien)) {
				DiagnosaPasien resultPasien = diagnosaPasienDao.save(diagnosaPasien);
				result.put("noRec", resultPasien.noRec);
				result.put("namaPasien", resultPasien.getPasien().getPasienDaftar().getPasien().getNamaPasien());
				result.put("noCm", resultPasien.getPasien().getPasienDaftar().getPasien().getNoCm());
			}
		}

		return result;
	}

	@Override
	public Map<String, Object> findByNoCmAndTglInput(String noCm, Date tglInput) {
		Map<String, Object> result = new HashMap<String, Object>();
		List<DiagnosaPasien> resultModel = diagnosaPasienDao.findDiagnosaPasienByNoCmAndTglInput(noCm, tglInput);
		if (CommonUtil.isNotNullOrEmpty(resultModel)) {
			result.put("diagnosaPasien", resultModel);
			result.put("dataFound", true);
		} else {
			result.put("dataFound", false);
		}
		return result;
	}

	@Override
	public Boolean checkDiagnosaPasien(Integer pasienId) {
		Boolean result = false;
		List<DiagnosaPasien> diagnosaPasienList = diagnosaPasienDao.findByPasien(pasienId);
		if (CommonUtil.isNotNullOrEmpty(diagnosaPasienList)) {
			result = true;
		}
		return result;
	}

	@Override
	public Map<String, Object> findByNoCm(String noCm) {
		Map<String, Object> result = new HashMap<String, Object>();
		List<DiagnosaPasien> resultModel = diagnosaPasienDao.findDiagnosaPasienByNoCm(noCm);
		if (CommonUtil.isNotNullOrEmpty(resultModel)) {
			try {
				result.put("diagnosaPasien", JsonUtil.ToMaps(resultModel));
				result.put("dataFound", true);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		} else {
			result.put("dataFound", false);
		}
		return result;
	}

	@Override
	public Map<String, Object> findAll() {
		Map<String, Object> result = new HashMap<String, Object>();
		List<DiagnosaPasien> resultModel = (List<DiagnosaPasien>) diagnosaPasienDao.findAll();
		if (CommonUtil.isNotNullOrEmpty(resultModel)) {
			try {
				result.put("diagnosaPasien", JsonUtil.ToMaps(resultModel));
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
			result.put("dataFound", true);
		} else {
			result.put("dataFound", false);
		}
		return result;
	}

	@Override
	public Map<String, Object> findDiagnosaPasienByAntrian(String noRec) {
		Map<String, Object> result = new HashMap<String, Object>();
		List<DiagnosaPasien> list = diagnosaPasienDao.findDiagnosaPasienByAntrian(noRec);
		if (CommonUtil.isNotNullOrEmpty(list)) {
			try {
				result.put("diagnosaPasien", JsonUtil.ToMaps(list));
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
			result.put("dataFound", true);
		} else {
			result.put("dataFound", false);
		}
		return result;
	}
}
