package com.jasamedika.medifirst2000.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
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 org.springframework.transaction.annotation.Transactional;

import com.jasamedika.medifirst2000.converter.BaseConverterImpl;
import com.jasamedika.medifirst2000.dao.OrderPelayananDao;
import com.jasamedika.medifirst2000.dao.ProdukDao;
import com.jasamedika.medifirst2000.dao.RuanganDao;
import com.jasamedika.medifirst2000.dao.StrukOrderDao;
import com.jasamedika.medifirst2000.dao.StrukPelayananDao;
import com.jasamedika.medifirst2000.dao.StrukPelayananDetailDao;
import com.jasamedika.medifirst2000.dto.PemulasaraanJenazahDetailDto;
import com.jasamedika.medifirst2000.entities.CaraBayar;
import com.jasamedika.medifirst2000.entities.HargaNettoProdukByKelas;
import com.jasamedika.medifirst2000.entities.KelompokTransaksi;
import com.jasamedika.medifirst2000.entities.MappingPelayananJenazah;
import com.jasamedika.medifirst2000.entities.OrderPelayanan;
import com.jasamedika.medifirst2000.entities.Produk;
import com.jasamedika.medifirst2000.entities.Ruangan;
import com.jasamedika.medifirst2000.entities.RunningNumber;
import com.jasamedika.medifirst2000.entities.SatuanStandar;
import com.jasamedika.medifirst2000.entities.StrukOrder;
import com.jasamedika.medifirst2000.entities.StrukPelayanan;
import com.jasamedika.medifirst2000.entities.StrukPelayananDetail;
import com.jasamedika.medifirst2000.enums.Status;
import com.jasamedika.medifirst2000.service.LoginUserService;
import com.jasamedika.medifirst2000.service.PemulasaraanJenazahService;
import com.jasamedika.medifirst2000.service.StrukOrderService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.util.DateUtil;
import com.jasamedika.medifirst2000.util.StringUtil;
import com.jasamedika.medifirst2000.vo.CaraBayarVO;
import com.jasamedika.medifirst2000.vo.HargaNettoProdukByKelasVO;
import com.jasamedika.medifirst2000.vo.MappingPelayananJenazahVO;
import com.jasamedika.medifirst2000.vo.OrderPelayananVO;
import com.jasamedika.medifirst2000.vo.PemulasaraanJenazahVO;
import com.jasamedika.medifirst2000.vo.ProdukVO;
import com.jasamedika.medifirst2000.vo.StrukOrderVO;
import com.jasamedika.medifirst2000.vo.StrukPelayananDetailVO;
import com.jasamedika.medifirst2000.vo.StrukPelayananVO;

@Service("PemulasaraanJenazahService")
public class PemulasaraanJenazahServiceImpl extends BaseVoServiceImpl implements PemulasaraanJenazahService {

	@Autowired
	private StrukOrderDao strukOrderDao;

	@Autowired
	private OrderPelayananDao orderPelayananDao;

	@Autowired
	private ProdukDao produkDao;

	@Autowired
	private RuanganDao ruanganDao;

	@Autowired
	private BaseConverterImpl<StrukOrderVO, StrukOrder> strukOrderConverter;

	@Autowired
	private BaseConverterImpl<OrderPelayananVO, OrderPelayanan> orderPelayananConverter;

	@Autowired
	private BaseConverterImpl<ProdukVO, Produk> produkConverter;

	@Autowired
	private BaseConverterImpl<CaraBayarVO, CaraBayar> caraBayarConverter;

	@Autowired
	private BaseConverterImpl<MappingPelayananJenazahVO, MappingPelayananJenazah> jenazahConverter;

	@Autowired
	private BaseConverterImpl<HargaNettoProdukByKelasVO, HargaNettoProdukByKelas> hargaConverter;
	
	@Autowired
	private StrukOrderService strukOrderService;
	
	@Autowired
	private LoginUserService loginUserService;
	
	@Autowired
	private StrukPelayananDao strukPelayananDao;
	
	@Autowired
	private StrukPelayananDetailDao strukPelayananDetailDao;

	@Override
	public Map<String, Object> savePemulasaraanJenazah(PemulasaraanJenazahVO vo, String noRec) {

		Map<String, Object> result = new HashMap<String, Object>();

		try {
			System.out.println("==================START SAVE PEMULASARAAN JENAZAH======================");
			if (CommonUtil.isNotNullOrEmpty(vo.getStrukOrder())) {
				System.out.println(":::START STRUK ORDER:::");
				StrukOrder strukOrder = strukOrderDao.findByNoRec(noRec);
				strukOrderConverter.transferVOToModel(vo.getStrukOrder(), new StrukOrder());
				// get cara bayar
				if (CommonUtil.isNotNullOrEmpty(vo.getStrukOrder().getCaraBayarQuo())) {
					strukOrder.setCaraBayarQuo(caraBayarConverter
							.transferVOToModel(vo.getStrukOrder().getCaraBayarQuo(), new CaraBayar()));
				}
				strukOrder.setStatus(Status.MENINGGAL.getVal());
				strukOrder.setTotalHargaSatuan(vo.getStrukOrder().getTotalHargaSatuan());
				strukOrder.setTotalHarusDibayar(vo.getStrukOrder().getTotalHarusDibayar());
				strukOrder.setKeteranganOrder("Pemulasaraan Jenazah");
				StrukOrder resultModelStrukOrder = strukOrderDao.save(strukOrder);
				result.put("noRecStrukOrder", resultModelStrukOrder.getNoRec());
				System.out.println(":::END STRUK ORDER:::");
				if (CommonUtil.isNotNullOrEmpty(vo.getOrderPelayanan())) {
					System.out.println(":::START ORDER PELAYANAN:::");
					List<OrderPelayanan> listOrderPelayanan = orderPelayananDao.findByNoRec(noRec);
					OrderPelayanan orderPelayanan = orderPelayananConverter.transferVOToModel(vo.getOrderPelayanan(),
							new OrderPelayanan());
					for (int i = 0; i < listOrderPelayanan.size(); i++) {
						orderPelayanan.setProduk(listOrderPelayanan.get(i).getProduk());
						orderPelayanan.setProduk(produkDao.findById(
								Integer.parseInt((String) this.GetSettingDataFixed("KdProdukPemulasaraanJenazah"))));
						orderPelayanan.setNoOrder(listOrderPelayanan.get(i).getNoOrder());
						orderPelayanan.setStrukOrder(listOrderPelayanan.get(i).getStrukOrder());
						orderPelayanan.setRuangan(listOrderPelayanan.get(i).getRuangan());
						orderPelayanan.setRuangan(ruanganDao.findById(
								Integer.parseInt((String) this.GetSettingDataFixed("KdRuanganPemulasaraanJenazah"))));
						orderPelayanan.setRuanganTujuan(listOrderPelayanan.get(i).getRuanganTujuan());
						orderPelayanan.setRuanganTujuan(ruanganDao.findById(Integer
								.parseInt((String) this.GetSettingDataFixed("KdRuanganTujuanPemulasaraanJenazah"))));
						orderPelayanan.setIsCito(listOrderPelayanan.get(i).getIsCito());
						orderPelayanan.setQtyProduk(listOrderPelayanan.get(i).getQtyProduk());
						orderPelayanan.setQtyProdukRetur(listOrderPelayanan.get(i).getQtyProdukRetur());
						orderPelayanan.setTglPelayanan(DateUtil.getShortDate());
						orderPelayanan.getProduk().setNilaiNormal((short) 1);
						orderPelayanan.getProduk().setqProduk(1);
						orderPelayanan.getProduk().setQtyJualTerkecil(1.0);
						orderPelayanan.getProduk().setQtySatuKemasan(1);
						orderPelayanan.getProduk().setQtyTerkecil(1.0);
					}
					// set pelayanan jenazah
					Set<MappingPelayananJenazah> listPelayananJenazah = new HashSet<MappingPelayananJenazah>();
					for (MappingPelayananJenazahVO model : vo.getOrderPelayanan().getMapJenazah()) {
						MappingPelayananJenazah jenazah = jenazahConverter.transferVOToModel(model,
								new MappingPelayananJenazah());
						// get produk pelayanan jenazah
						if (CommonUtil.isNotNullOrEmpty(model.getProduk())) {
							jenazah.setProduk(produkConverter.transferVOToModel(model.getProduk(), new Produk()));
						}
						// get harga satuan pelayanan jenazah
						if (CommonUtil.isNotNullOrEmpty(model.getHarga())) {
							jenazah.setHarga(
									hargaConverter.transferVOToModel(model.getHarga(), new HargaNettoProdukByKelas()));
						}
						jenazah.setOrderPelayanan(orderPelayanan);
						listPelayananJenazah.add(jenazah);
					}
					orderPelayanan.setMapJenazah(listPelayananJenazah);
					OrderPelayanan resultModelOrderPelayanan = orderPelayananDao.save(orderPelayanan);
					result.put("noRecOrderPelayanan", resultModelOrderPelayanan.getNoRec());
					System.out.println(":::END ORDER PELAYANAN:::");
				}
			}
			System.out.println("==================END SAVE PEMULASARAAN JENAZAH======================");
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;

	}

	@Override
	public List<Produk> findPelayananPemulasaraanJenazah() {

		List<Produk> model = new ArrayList<Produk>();
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			System.out.println("==========START FIND PELAYANAN JENAZAH==========");
			model = produkDao.findPelayananPemulasaraanJenazah();
			if (CommonUtil.isNotNullOrEmpty(model)) {
				result.put("data", model);
				result.put("PelayananJenazah", true);
			} else {
				result.put("PelayananJenazah", false);
			}
			System.out.println("==========END FIND PELAYANAN JENAZAH==========");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return model;
	}

	@Override
	public String generateNoOrderByDayMonthAndYear(PemulasaraanJenazahVO vo) {

		StrukOrder strukOrder = strukOrderConverter.transferVOToModel(vo.getStrukOrder(), new StrukOrder());

		Date dateNow = strukOrder.getTglPelayananAwal();
		Integer day = getDayFromDate(dateNow);
		Integer month = DateUtil.getMonthFromDate(dateNow);
		Integer year = DateUtil.getYearFromDate(dateNow);
		Integer countByDayMonthAndYear = 0;

		countByDayMonthAndYear = strukOrderDao.getCountByDayMonthAndYear(day, month, year);

		Integer dayNow = getDayFromDate(dateNow);
		Integer monthNow = DateUtil.getMonthFromDate(dateNow);
		Integer yearNow = DateUtil.getYearFromDate(dateNow);
		String dayNowString = dayNow.toString();
		String monthNowString = monthNow.toString();
		String yearNowString = yearNow.toString().substring(2, 4);
		String countString = null;
		countByDayMonthAndYear++;

		if (CommonUtil.isNotNullOrEmpty(countByDayMonthAndYear)) {
			if (countByDayMonthAndYear.toString().length() == 1) {
				countString = "000" + countByDayMonthAndYear.toString();
			} else if (countByDayMonthAndYear.toString().length() == 2) {
				countString = "000" + countByDayMonthAndYear.toString();
			} else if (countByDayMonthAndYear.toString().length() == 3) {
				countString = "000" + countByDayMonthAndYear.toString();
			} else if (countByDayMonthAndYear.toString().length() == 4) {
				countString = "000" + countByDayMonthAndYear.toString();
			} else if (countByDayMonthAndYear.toString().length() == 5) {
				countString = "000" + countByDayMonthAndYear.toString();
			}
		}

		if ((monthNowString.length()) == 1) {
			monthNowString = "0" + monthNow;
		} else if ((monthNowString.length()) == 2) {
			monthNowString = "0" + monthNow;
		} else if ((monthNowString.length()) == 3) {
			monthNowString = "0" + monthNow;
		} else if ((monthNowString.length()) == 4) {
			monthNowString = "0" + monthNow;
		} else if ((monthNowString.length()) == 5) {
			monthNowString = "0" + monthNow;
		}

		return dayNowString + "" + monthNowString + "" + yearNowString + "" + countString;
	}

	private Integer getDayFromDate(Date date) {

		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int day = cal.get(Calendar.DAY_OF_MONTH);
		return day;
	}

	@Override
	public List<StrukOrder> findRincianBiayaPemulasaraanJenazah(String noRec) {

		List<StrukOrder> model = new ArrayList<StrukOrder>();
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			System.out.println("==========START FIND RINCIAN BIAYA PELAYANAN JENAZAH==========");
			model = strukOrderDao.findRincianBiayaPemulasaraanJenazah(noRec);
			if (CommonUtil.isNotNullOrEmpty(model)) {
				result.put("data", model);
				result.put("RincianBiaya", true);
			} else {
				result.put("RincianBiaya", false);
			}
			System.out.println("==========END FIND RINCIAN BIAYA PELAYANAN JENAZAH==========");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return model;
	}
	
	@Override
	public Map<String, Object> savePemulasaranJenazahExternal(PemulasaraanJenazahVO vo) {
		Map<String, Object> result = new HashMap<String, Object>();
	
		StrukPelayanan strukPelayanan = new StrukPelayanan();
		
		//Date tanggal = DateUtil.toDate(DateUtil.formatDate(vo.getTglStruk()));
					
		String noStruk = strukOrderService.formatNoUrut("StrukPelayanan", "PJ");
		strukPelayanan.setNostruk(noStruk);
		//Ruangan ruangan = ruanganDao.findOne(Integer.parseInt((String) this.GetSettingDataFixed("KdRuanganPemulasaraanJenazah"))); //"Ruang Pemulasaraan Jenazah"
		Ruangan ruangan = this.ruanganDao.findOne(332); //disett dulu untuk ruangan pemulasaran jenazah
		strukPelayanan.setKdruangan(ruangan);
		strukPelayanan.setKdruanganasal(ruangan);
		strukPelayanan.setKeteranganlainnya("Pemulasaraan Jenazah");
		strukPelayanan.setQtyproduk(0.0);
		strukPelayanan.setTglstruk(vo.getTglStruk());
		KelompokTransaksi kelompokTransaksi = new KelompokTransaksi();
		kelompokTransaksi.setId(Integer.parseInt(GetSettingDataFixed("KdKelompokTransaksiPemulasaraanJenazah"))); //set nilaifield =99
		strukPelayanan.setKdkelompoktransaksi(kelompokTransaksi);
		strukPelayanan.setMenyerahkan(loginUserService.getLoginUser().getPegawai());
		strukPelayanan.setNamapasien_klien(vo.getNamaPemesan());
		strukPelayanan.setNoteleponfaks(vo.getNoTelp());
		strukPelayanan.setNoKontrak(vo.getNoKtp());
		strukPelayanan.setAlamattempattujuan(vo.getAlamat());
		StrukPelayanan strukPelayananResult = this.strukPelayananDao.save(strukPelayanan);
		Double totalHarga = 0.0;
		for(PemulasaraanJenazahDetailDto item:vo.getPemulasaraaanJenazahDetail()){
			StrukPelayananDetail strukPelayananDetail = new StrukPelayananDetail();
			Double harga = item.getHarga();
			Produk produk = this.produkDao.findById(item.getProdukId());
			strukPelayananDetail.setKdproduk(produk);
			strukPelayananDetail.setNostruk(strukPelayanan);
			strukPelayananDetail.setTglpelayanan(vo.getTglStruk());
			strukPelayananDetail.setHargasatuan(harga);
			totalHarga = totalHarga+harga;
			strukPelayananDetail = this.strukPelayananDetailDao.save(strukPelayananDetail);
		}
		strukPelayananResult.setTotalhargasatuan(totalHarga);
		strukPelayananDao.save(strukPelayananResult);
		
		if(CommonUtil.isNotNullOrEmpty(strukPelayananResult)){
			result.put("noRec",	 strukPelayananResult.noRec);
		}

		return result;

	}
	
	

}
