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.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.jasamedika.medifirst2000.converter.BaseConverterImpl;
import com.jasamedika.medifirst2000.dao.KartuPengendaliDetailDao;
import com.jasamedika.medifirst2000.dao.KelompokTransaksiDao;
import com.jasamedika.medifirst2000.dao.RunningNumberDao;
import com.jasamedika.medifirst2000.dao.StrukPelayananDao;
import com.jasamedika.medifirst2000.dao.StrukPelayananDetailDao;
import com.jasamedika.medifirst2000.dao.StrukRekapPemenangDao;
import com.jasamedika.medifirst2000.dao.custom.KartuPengendaliDaoCustom;
import com.jasamedika.medifirst2000.entities.AsalProduk;
import com.jasamedika.medifirst2000.entities.KartuPengendaliDetail;
import com.jasamedika.medifirst2000.entities.KelompokUser;
import com.jasamedika.medifirst2000.entities.Produk;
import com.jasamedika.medifirst2000.entities.Rekanan;
import com.jasamedika.medifirst2000.entities.RunningNumber;
import com.jasamedika.medifirst2000.entities.SatuanStandar;
import com.jasamedika.medifirst2000.entities.StrukPelayanan;
import com.jasamedika.medifirst2000.entities.StrukPelayananDetail;
import com.jasamedika.medifirst2000.enums.VerifikasiEnum;
import com.jasamedika.medifirst2000.service.SppbService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.util.StringUtil;
import com.jasamedika.medifirst2000.vo.AsalProdukVO;
import com.jasamedika.medifirst2000.vo.KartuPengendaliDetailVO;
import com.jasamedika.medifirst2000.vo.PenerimaanBarangDetailVO;
import com.jasamedika.medifirst2000.vo.ProdukVO;
import com.jasamedika.medifirst2000.vo.RekananVO;
import com.jasamedika.medifirst2000.vo.SatuanStandarVO;
import com.jasamedika.medifirst2000.vo.SppbVO;
import com.jasamedika.medifirst2000.vo.VerifikasiSppbVO;

@Service("sppbService")
public class SppbServiceImpl extends BaseAngaranServiceImpl implements SppbService {
	
	@Autowired
	private KartuPengendaliDaoCustom kartupengendaliDaoCustom;
	
	@Autowired
	private StrukRekapPemenangDao strukRekapPemenangDao;
	
	@Autowired
	private StrukPelayananDetailDao strukPelayananDetailDao;
	
	@Autowired
	private KartuPengendaliDetailDao kartuPengendaliDetailDao;
	
	@Autowired
	private KelompokTransaksiDao kelompokTransaksiDao;
	
	@Autowired
	private BaseConverterImpl<RekananVO, Rekanan> rekananConverter;
	
	@Autowired
	private BaseConverterImpl<ProdukVO, Produk> produkConverter;
	
	@Autowired
	private BaseConverterImpl<KartuPengendaliDetailVO, KartuPengendaliDetail> kartuPengendaliDetailConverter;
	
	@Autowired
	private BaseConverterImpl<AsalProdukVO, AsalProduk> asalProdukConverter;
	
	@Autowired
	private StrukPelayananDao strukPelayananDao;
	
	@Autowired
	private BaseConverterImpl<SatuanStandarVO, SatuanStandar> satuanStandarConverter;
	
	@Autowired
	private RunningNumberDao runningNumberDao;
	
	// Pre add Sppb
	@Override
	public Map<String, Object> preAddSppb(Integer page, Integer limit, String sort, String dir, String dateStart,String dateEnd, Integer supplierId) {
		KelompokUser kelompokUser = getKelompokUserLogin();
		int totalRow = kartupengendaliDaoCustom.preAddSppbCount(sort, dateStart, dateEnd, supplierId);
		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>();
		List<Map<String, Object>> listData = new ArrayList<Map<String, Object>>();
		for (Map<String, Object> data : kartupengendaliDaoCustom.preAddSppbGrid(dateStart, dateEnd, supplierId)) {
			Integer kdKelompokTransaksi=new Integer(GetSettingDataFixed("kdKelompokTransaksiSppb"));
			if(! kartupengendaliDaoCustom.CheckSppbTerhadapKontrak((String) data.get("noRec"),kdKelompokTransaksi)){
				if (kelompokUser.getKelompokUser().equalsIgnoreCase("logistik")) {
					data.put("jenisPenerimaan", "logistik");
				} else if (kelompokUser.getKelompokUser().equalsIgnoreCase("bagianUmum")) {
					data.put("jenisPenerimaan", "bagianUmum");
				}
				listData.add(data);
			}
			
		}
		result.put("data", listData);
		return result;
	}
	
	// get Struk Rekap
	@Override
	public Map<String, Object> detailKontrak(String noRec) {
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("headKontrak", strukRekapPemenangDao.findByNoRecSppb(noRec));
		List<Map<String,Object>>listData=new ArrayList<Map<String,Object>>();
		for(Map<String,Object> data:kartuPengendaliDetailDao.getKartuPengendaliDetailStrukRekapKontrak(noRec)){
			if(CommonUtil.isNotNullOrEmpty(data.get("sisa"))){
				data.put("sisaPenerimaan", kartuPengendaliDetailDao.getSisaPenerimaan((String) data.get("noRec")));
				data.remove("sisa");
			}else{
				data.put("sisaPenerimaan",  data.get("jumlahOrder"));
				data.remove("sisa");
			}
			listData.add(data);
		}
		result.put("detailKontrak", listData);
		return result;
	}

	@Override
	@Transactional(readOnly=false)
	public Map<String, Object> saveSppb(SppbVO vo) {
		StrukPelayanan strukPelayanan=new StrukPelayanan();
		strukPelayanan.setTglstruk(new Date());
		strukPelayanan.setVerifikasi(VerifikasiEnum.NEW_SPPB.getVal());
		strukPelayanan.setNostruk("Sppb"+getRunningNumber("Sppb"));
		strukPelayanan.setKdkelompoktransaksi(kelompokTransaksiDao.findById(Integer.parseInt((String) this.GetSettingDataFixed("kdKelompokTransaksiSppb"))));
		if(CommonUtil.isNotNullOrEmpty(vo.getSupplier())){
			strukPelayanan.setKdrekanan(rekananConverter.transferVOToModel(vo.getSupplier(), new Rekanan()));
		}
		
		if(CommonUtil.isNotNullOrEmpty(vo.getPenerimaanBarangDetail())){
			for(PenerimaanBarangDetailVO penerimaanBarangDetailVO:vo.getPenerimaanBarangDetail()){
				StrukPelayananDetail strukPelayananDetail=new StrukPelayananDetail();
				if(CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO)){
					if(CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getDiscount()) && CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getHarga())){
						strukPelayananDetail.setHargadiscount(penerimaanBarangDetailVO.getHarga()-((penerimaanBarangDetailVO.getDiscount()/100)*penerimaanBarangDetailVO.getHarga()));
					}
					
					if(CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getPpn()) && CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getHarga())){
						strukPelayananDetail.setHargappn(penerimaanBarangDetailVO.getHarga()+((penerimaanBarangDetailVO.getPpn()/100)*penerimaanBarangDetailVO.getHarga()));
					}
				}
				strukPelayananDetail.setHargasatuan(penerimaanBarangDetailVO.getHarga());
				strukPelayananDetail.setQtyproduk(penerimaanBarangDetailVO.getVolumeMinta());
				strukPelayananDetail.setQtyKontrak(penerimaanBarangDetailVO.getQtyKontrak());
				strukPelayananDetail.setTglKadaluarsa(penerimaanBarangDetailVO.getTanggalKadaluarsa());
				strukPelayananDetail.setNobatch(penerimaanBarangDetailVO.getNoBatch());
				strukPelayananDetail.setPersendiscount(penerimaanBarangDetailVO.getDiscount());
				strukPelayananDetail.setNostruk(strukPelayanan);
				strukPelayananDetail.setHargadiscountgive(0.0);
				strukPelayananDetail.setHargadiscountsave(0.0);
				strukPelayananDetail.setHarganetto(0.0);
				strukPelayananDetail.setHargapph(0.0);
				strukPelayananDetail.setHargasatuandijamin(0.0);
				strukPelayananDetail.setHargasatuanppenjamin(0.0);
				strukPelayananDetail.setHargasatuanpprofile(0.0);
				strukPelayananDetail.setHargatambahan(0.0);
				strukPelayananDetail.setHargatambahan(0.0);
				strukPelayananDetail.setQtyorang((byte)0);
				strukPelayananDetail.setIsonsiteservice((byte)0);
				strukPelayananDetail.setQtyprodukoutext(0.0);
				strukPelayananDetail.setQtyprodukoutint(0.0);
				strukPelayananDetail.setQtyprodukretur(0.0);
				strukPelayananDetail.setSatuan("");
				strukPelayananDetail.setTglpelayanan(strukPelayanan.getTglstruk());
				
				strukPelayananDetail.setHargasatuanpprofile(0.0);
				strukPelayananDetail.setHargasatuanpprofile(0.0);
				
				
				if(CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getProduk())){
					strukPelayananDetail.setKdproduk(produkConverter.transferVOToModel(penerimaanBarangDetailVO.getProduk(), new Produk()));
				}
				if(CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getAsalProduk())){
					strukPelayananDetail.setKdasalproduk(asalProdukConverter.transferVOToModel(penerimaanBarangDetailVO.getAsalProduk(),new AsalProduk()));
				}
				if(CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getSatuan())){
					strukPelayananDetail.setKdsatuanstandar(satuanStandarConverter.transferVOToModel(penerimaanBarangDetailVO.getSatuan(), new SatuanStandar()));
				}
				if(CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getKartuPengendaliDetail())){
					strukPelayananDetail.setKartuPengendaliDetail(kartuPengendaliDetailConverter.transferVOToModel(penerimaanBarangDetailVO.getKartuPengendaliDetail(), new KartuPengendaliDetail()));
				}
				strukPelayanan.getStrukPelayananDetail().add(strukPelayananDetail);
				
				
			}
		}
		strukPelayananDao.save(strukPelayanan);
		Map<String,Object>result=new HashMap<String,Object>();
		result.put("noRec", strukPelayanan.getNoRec());
		return result;
		
	}
	
	@Override
	@Transactional(readOnly=false)
	public Map<String, Object> updateSppb(SppbVO vo) {
		StrukPelayanan strukPelayanan=strukPelayananDao.findOne(vo.getNoRec());
		if(CommonUtil.isNotNullOrEmpty(vo.getPenerimaanBarangDetail())){
			for(PenerimaanBarangDetailVO penerimaanBarangDetailVO:vo.getPenerimaanBarangDetail()){
				if(CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getNoRec())){
					StrukPelayananDetail strukPelayananDetail=strukPelayananDetailDao.findOne(penerimaanBarangDetailVO.getNoRec());
					if(CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO)){
						if(CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getDiscount()) && CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getHarga())){
							strukPelayananDetail.setHargadiscount(penerimaanBarangDetailVO.getHarga()-((penerimaanBarangDetailVO.getDiscount()/100)*penerimaanBarangDetailVO.getHarga()));
						}
						if(CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getPpn()) && CommonUtil.isNotNullOrEmpty(penerimaanBarangDetailVO.getHarga())){
							strukPelayananDetail.setHargappn(penerimaanBarangDetailVO.getHarga()+((penerimaanBarangDetailVO.getPpn()/100)*penerimaanBarangDetailVO.getHarga()));
						}
					}
					strukPelayananDetail.setHargasatuan(penerimaanBarangDetailVO.getHarga());
					strukPelayananDetail.setQtyproduk(penerimaanBarangDetailVO.getVolumeMinta());
					strukPelayananDetailDao.save(strukPelayananDetail);
				}
			}
		}
		strukPelayananDao.save(strukPelayanan);
		Map<String,Object>result=new HashMap<String,Object>();
		result.put("noRec", strukPelayanan.getNoRec());
		return result;
		
	}
	
	@Transactional(readOnly=false)
	private String getRunningNumber(String kegunaan) {
		RunningNumber runningNumber = runningNumberDao.findByResetAndKegunaan("0", kegunaan);
		Integer number =0;
		if(CommonUtil.isNotNullOrEmpty(runningNumber)){
			number=(runningNumber.getNomerTerbaru() + (Integer) 1);
		}
		
		runningNumber.setNomerTerbaru(number+ (Integer) 1);
		String noOrderIntern = StringUtil.formatNumber(number.toString(), 6);
		runningNumberDao.save(runningNumber);
		return noOrderIntern;
	}
	
	// List Sppb
	@Override
	public Map<String, Object> daftarSppb(Integer page, Integer limit, String sort, String dir, String dateStart,String dateEnd, Integer supplierId) {
		KelompokUser kelompokUser=new KelompokUser();
		int totalRow = kartupengendaliDaoCustom.sppbCount(sort, dateStart, dateEnd, supplierId);
		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>();
		List<Map<String, Object>> listData = new ArrayList<Map<String, Object>>();
		result.put("data", kartupengendaliDaoCustom.sppbList(rowStart,rowEnd,dateStart, dateEnd, supplierId));
		return result;
	}
	
	// get Struk Rekap
	@Override
	public Map<String, Object> detailSppb(String noRec) {
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("sppb", strukRekapPemenangDao.findSppbByNoRec(noRec));
		result.put("detailSppb", strukRekapPemenangDao.findSppbDetail(noRec));
		return result;
	}

	@Override
	public Map<String, Object> verifikasiSppb(VerifikasiSppbVO vo) {
		StrukPelayanan strukPelayanan=strukPelayananDao.findOne(vo.getNoRec());
		strukPelayanan.setVerifikasi(VerifikasiEnum.VERIF_SPPB_PPK.getVal());
		strukPelayananDao.save(strukPelayanan);
		Map<String,Object> result=new HashMap<String,Object>();
		result.put("noRec", strukPelayanan.getNoRec());
		return result;
	}
	
	@Override
	public Map<String, Object> unverifikasiSppb(VerifikasiSppbVO vo) {
		StrukPelayanan strukPelayanan=strukPelayananDao.findOne(vo.getNoRec());
		strukPelayanan.setVerifikasi(VerifikasiEnum.UNVERIF_SPPB_PPK.getVal());
		strukPelayanan.setKeteranganlainnya(vo.getKeterangan());
		strukPelayananDao.save(strukPelayanan);
		Map<String,Object> result=new HashMap<String,Object>();
		result.put("noRec", strukPelayanan.getNoRec());
		return result;
	}
		
}
