package com.jasamedika.medifirst2000.service.impl;

import java.text.DecimalFormat;
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 org.springframework.transaction.annotation.Transactional;

import com.jasamedika.medifirst2000.converter.base.BaseVoConverter;
import com.jasamedika.medifirst2000.dao.DetailJenisLimbahDao;
import com.jasamedika.medifirst2000.dao.DetailPerlakuanDao;
import com.jasamedika.medifirst2000.dao.NeracaLimbahDao;
import com.jasamedika.medifirst2000.dao.custom.NeracaLimbahDaoCustom;
import com.jasamedika.medifirst2000.entities.DetailJenisLimbah;
import com.jasamedika.medifirst2000.entities.DetailPerlakuan;
import com.jasamedika.medifirst2000.entities.JenisLimbahB3Masuk;
import com.jasamedika.medifirst2000.entities.NeracaLimbah;
import com.jasamedika.medifirst2000.entities.PerizinanLimbah;
import com.jasamedika.medifirst2000.entities.Perlakuan;
import com.jasamedika.medifirst2000.entities.StrukPelayanan;
import com.jasamedika.medifirst2000.service.NeracaLimbahService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.vo.DetailJenisLimbahVO;
import com.jasamedika.medifirst2000.vo.DetailPerlakuanVO;
import com.jasamedika.medifirst2000.vo.JenisLimbahB3MasukVO;
import com.jasamedika.medifirst2000.vo.NeracaLimbahVO;
import com.jasamedika.medifirst2000.vo.PerizinanLimbahVO;
import com.jasamedika.medifirst2000.vo.PerlakuanVO;

@Service("neracaLimbahService")
public class NeracaLimbahServiceImpl extends BaseAngaranServiceImpl implements NeracaLimbahService{

	@Autowired
	private NeracaLimbahDao neracaLimbahDao;
	
	@Autowired
	private DetailPerlakuanDao detailPerlakuanDao;
	
	@Autowired
	private DetailJenisLimbahDao detailJenisLimbahDao;
	
	@Autowired
	private NeracaLimbahDaoCustom neracaLimbahDaoCustom;
	
	@Autowired
	private BaseVoConverter<NeracaLimbahVO,NeracaLimbah> neracaLimbahConverter;
	
	@Autowired
	private BaseVoConverter<JenisLimbahB3MasukVO, JenisLimbahB3Masuk> jenisLimbahB3KeluarConveter;
	
	@Autowired
	private BaseVoConverter<PerlakuanVO, Perlakuan> perlakuanConveter;
	
	@Autowired
	private BaseVoConverter<PerizinanLimbahVO, PerizinanLimbah> perizinanConveter;
	
	@Autowired
	private BaseVoConverter<DetailJenisLimbahVO, DetailJenisLimbah> detailJenisLimbahConverter;
	
	@Autowired
	private BaseVoConverter<DetailPerlakuanVO, DetailPerlakuan> detailPerlakuanConverter;
	
	@Override
	@Transactional
	public Map<String, Object> add(NeracaLimbahVO vo) {
		NeracaLimbah neracaLimbah=new NeracaLimbah();
		neracaLimbah=neracaLimbahConverter.transferVOToModel(vo, new NeracaLimbah());
		Set<DetailPerlakuan> detailPerlakuanList=new HashSet<DetailPerlakuan>();
		Set<DetailJenisLimbah> detailJenisLimbahList=new HashSet<DetailJenisLimbah>();
		if(CommonUtil.isNotNullOrEmpty(vo.getDetailJenisLimbah())){
			for(DetailJenisLimbahVO detailJenisLimbahVO:vo.getDetailJenisLimbah()){
				DetailJenisLimbah detailJenisLimbah=new DetailJenisLimbah();
				detailJenisLimbah=detailJenisLimbahConverter.transferVOToModel(detailJenisLimbahVO, new DetailJenisLimbah());
				detailJenisLimbah.setNeracaLimbah(neracaLimbah);
				if(CommonUtil.isNotNullOrEmpty(detailJenisLimbahVO.getJenisLimbahB3Masuk())){
					detailJenisLimbah.setJenisLimbahB3Masuk(jenisLimbahB3KeluarConveter.transferVOToModel(detailJenisLimbahVO.getJenisLimbahB3Masuk(), new JenisLimbahB3Masuk()));
				}
				detailJenisLimbahList.add(detailJenisLimbah);
			}
		}
		
		if(CommonUtil.isNotNullOrEmpty(vo.getDetailPerlakuan())){
			for(DetailPerlakuanVO detailPerlakuanVO:vo.getDetailPerlakuan()){
				DetailPerlakuan detailPerlakuan=new DetailPerlakuan();
				detailPerlakuan=detailPerlakuanConverter.transferVOToModel(detailPerlakuanVO, new DetailPerlakuan());
				detailPerlakuan.setNeracaLimbah(neracaLimbah);
				if(CommonUtil.isNotNullOrEmpty(detailPerlakuanVO.getPerlakuan())){
					detailPerlakuan.setPerlakuan(perlakuanConveter.transferVOToModel(detailPerlakuanVO.getPerlakuan(), new Perlakuan()));
				}
				if(CommonUtil.isNotNullOrEmpty(detailPerlakuanVO.getPerizinanLimbah())){
					detailPerlakuan.setPerizinanLimbah(perizinanConveter.transferVOToModel(detailPerlakuanVO.getPerizinanLimbah(), new PerizinanLimbah()));
				}
				detailPerlakuanList.add(detailPerlakuan);
			}
		}
		neracaLimbah.getDetailJenisLimbah().clear();
		neracaLimbah.getDetailPerlakuan().clear();
		neracaLimbah.getDetailJenisLimbah().addAll(detailJenisLimbahList);
		neracaLimbah.getDetailPerlakuan().addAll(detailPerlakuanList);
		neracaLimbah=neracaLimbahDao.save(neracaLimbah);
		Map<String,Object> result=new HashMap<String,Object>();
		result.put("noRec",neracaLimbah.getNoRec());
		
		return result;
	}
	
	@Override
	@Transactional
	public Map<String, Object> update(NeracaLimbahVO vo) {
		NeracaLimbah neracaLimbah=new NeracaLimbah();
		neracaLimbah=neracaLimbahDao.findOne(vo.getNoRec());
		neracaLimbah.setPeriodeAwal(vo.getPeriodeAwal());
		neracaLimbah.setPeriodeAhir(vo.getPeriodeAhir());
		neracaLimbah.setResidu(vo.getResidu());
		neracaLimbah.setKinerjaPengelolaan(vo.getKinerjaPengelolaan());
		neracaLimbah.setJumlahYangBelumTerkelola(vo.getJumlahYangBelumTerkelola());
		neracaLimbah.setTotalLimbahMasuk(vo.getTotalLimbahMasuk());
		neracaLimbah.setCatatan(vo.getCatatan());
		neracaLimbah=neracaLimbahDao.save(neracaLimbah);
		
//		if(CommonUtil.isNotNullOrEmpty(vo.getDetailJenisLimbah())){
//			for(DetailJenisLimbahVO detailJenisLimbahVO:vo.getDetailJenisLimbah()){
//				DetailJenisLimbah detailJenisLimbah=new DetailJenisLimbah();
//				detailJenisLimbah = detailJenisLimbahDao.findOne(detailJenisLimbahVO.getNoRec());
//				if(CommonUtil.isNotNullOrEmpty(detailJenisLimbahVO.getJenisLimbahB3Masuk())){
//					detailJenisLimbah.setJenisLimbahB3Masuk(jenisLimbahB3KeluarConveter.transferVOToModel(detailJenisLimbahVO.getJenisLimbahB3Masuk(), new JenisLimbahB3Masuk()));
//				}
//				detailJenisLimbah.setJumlah(detailJenisLimbahVO.getJumlah());
//				detailJenisLimbahDao.save(detailJenisLimbah);
//			}
//		}
		
		if(CommonUtil.isNotNullOrEmpty(vo.getDetailPerlakuan())){
			for(DetailPerlakuanVO detailPerlakuanVO:vo.getDetailPerlakuan()){
				DetailPerlakuan detailPerlakuan=new DetailPerlakuan();
				detailPerlakuan = detailPerlakuanDao.findOne(detailPerlakuanVO.getNoRec());
				if(CommonUtil.isNotNullOrEmpty(detailPerlakuanVO.getPerizinanLimbah())){
					detailPerlakuan.setPerizinanLimbah(perizinanConveter.transferVOToModel(detailPerlakuanVO.getPerizinanLimbah(), new PerizinanLimbah()));
				}
				detailPerlakuan.setJumlah(detailPerlakuanVO.getJumlah());
				detailPerlakuan.setJenisLimbahYangDikelola(detailPerlakuanVO.getJenisLimbahYangDikelola());
				detailPerlakuanDao.save(detailPerlakuan);
			}
		}
		
		
		
		Map<String,Object> result=new HashMap<String,Object>();
		result.put("noRec",neracaLimbah.getNoRec());
		
		return result;
	}
	

	@Override
	public Map<String, Object> listNeracaLimbah(Integer page, Integer limit, String sort, String dir) {
		
		int totalRow = neracaLimbahDaoCustom.findCount();
		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", neracaLimbahDaoCustom.findList(rowStart, rowEnd, sort, dir));
		result.put("totalPages", totalPages);
		result.put("totalRow", totalRow);
		return result;
	}
	

	@Override
	public Map<String, Object> neracaLimbahDetail(String noRec) {
		Map<String,Object> result=new HashMap<String,Object>();
		
		Map<String,Object> neracaLimbah = neracaLimbahDao.findNeracaById(noRec);		
		Double ttlLimbahMasuk = this.neracaLimbahDao.getTotalB3MasukByPeriode((String)neracaLimbah.get("periodeAwal"), (String)neracaLimbah.get("periodeAhir"));
		result.put("totalLimbahMasuk", ttlLimbahMasuk);
		result.put("neracaLimbah", neracaLimbah);
		result.put("detailPerlakuan",detailPerlakuanDao.findNeracaById(noRec));
		result.put("detailJenisLimbah", detailJenisLimbahDao.findNeracaById(noRec));
		return result;
	}


	@Override
	public Map<String, Object> getJumlahJenisLimbahB3ByPeriode(String startDate, String endDate) {
		Map<String, Object> result = new HashMap<>();
		
		Double ttlLimbahMasuk = this.neracaLimbahDao.getTotalB3MasukByPeriode(startDate, endDate);
		Double ttlLimbahKeluar = this.neracaLimbahDao.getTotalB3KeluarByPeriode(startDate, endDate);
		Double ttlLimbahTersisah = ttlLimbahMasuk-ttlLimbahKeluar;
		
		DecimalFormat df = new DecimalFormat("###.##");
		String strTtlLimbahTersisah = df.format(ttlLimbahTersisah);
		ttlLimbahTersisah = Double.parseDouble(strTtlLimbahTersisah);
		
		result.put("dataJenisLimbahMasuk", this.neracaLimbahDao.getB3MasukJenisLimbahByPeriode(startDate, endDate));
		result.put("totalLimbahMasuk", ttlLimbahMasuk);
//		result.put("totalLimbahKeluarPerlakuan", this.neracaLimbahDao.getB3KeluarByPerlakuan(startDate, endDate));
		result.put("totalLimbahKeluarPerlakuan", this.neracaLimbahDaoCustom.getB3KeluarByPerlakuan(startDate, endDate));
		result.put("totalLimbahKeluar", ttlLimbahKeluar);
		result.put("limbahDiSimpan", ttlLimbahTersisah);
		return result;
		
	}


	@Override
	public Map<String, Object> findReportNeracaLimbahB3(String noRec) {
		Map<String, Object> result = new HashMap<>();
		
		result.put("limbahMasuk", this.neracaLimbahDao.getReportLimbahB3Masuk(noRec));
		result.put("limbahKeluar", this.neracaLimbahDao.getReportLimbahB3Keluar(noRec));
		
		return result;
	}


	@Override
	public Map<String, Object> findReportDetailNeracaLimbahB3(String noRec) {
		Map<String, Object> result = neracaLimbahDao.getReportNeracaLimbahB3(noRec);
		return result;
	}
	
	@Override
	@Transactional(readOnly = false)
	public Boolean deleteNeracaLimbah(String noRec) throws IllegalAccessException {
		if(CommonUtil.isNotNullOrEmpty(noRec)){
			NeracaLimbah neracaLimbah = new NeracaLimbah();
			neracaLimbah=neracaLimbahDao.findOne(noRec);
//			neracaLimbahDao.delete(neracaLimbah);
			neracaLimbah.setStatusEnabled(false);
			neracaLimbahDao.save(neracaLimbah);
			return true;
		}

		return false;
	}
	
}
