package com.jasamedika.medifirst2000.service.impl;

import java.text.SimpleDateFormat;
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.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.jasamedika.medifirst2000.converter.BaseConverterImpl;
import com.jasamedika.medifirst2000.dao.KamarDao;
import com.jasamedika.medifirst2000.dao.LogAccDao;
import com.jasamedika.medifirst2000.dao.OrderPelayananDao;
import com.jasamedika.medifirst2000.dao.RunningNumberDao;
import com.jasamedika.medifirst2000.dao.StrukOrderDao;
import com.jasamedika.medifirst2000.dto.SewaAsramaDto;
import com.jasamedika.medifirst2000.entities.Kamar;
import com.jasamedika.medifirst2000.entities.LogAcc;
import com.jasamedika.medifirst2000.entities.MappingKamarAsrama;
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.StrukOrder;
import com.jasamedika.medifirst2000.enums.Status;
import com.jasamedika.medifirst2000.exception.ServiceVOException;
import com.jasamedika.medifirst2000.service.LoginUserService;
import com.jasamedika.medifirst2000.service.SewaAsramaService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.util.DateUtil;
import com.jasamedika.medifirst2000.util.StringUtil;
import com.jasamedika.medifirst2000.vo.KamarVO;
import com.jasamedika.medifirst2000.vo.MappingKamarAsramaVO;
import com.jasamedika.medifirst2000.vo.OrderPelayananVO;
import com.jasamedika.medifirst2000.vo.ProdukVO;
import com.jasamedika.medifirst2000.vo.RuanganVO;
import com.jasamedika.medifirst2000.vo.SewaAsramaVO;
import com.jasamedika.medifirst2000.vo.StrukOrderVO;

@Service("sewaAsramaService")
public class SewaAsramaServiceImpl extends BaseVoServiceImpl implements SewaAsramaService {

	@Autowired
	private StrukOrderDao strukOrderDao;

	@Autowired
	private KamarDao kamarDao;
	
	@Autowired
	private LogAccDao logAccDao;

	@Autowired
	private RunningNumberDao runningNumberDao;

	@Autowired
	private BaseConverterImpl<KamarVO, Kamar> kamarConverter;

	@Autowired
	private OrderPelayananDao orderPelayananDao;

	@Autowired
	private BaseConverterImpl<StrukOrderVO, StrukOrder> strukOrderConverter;

	@Autowired
	private BaseConverterImpl<OrderPelayananVO, OrderPelayanan> orderPelayananConverter;

	@Autowired
	private BaseConverterImpl<RuanganVO, Ruangan> ruanganConverter;

	@Autowired
	private BaseConverterImpl<ProdukVO, Produk> produkConverter;

	@Autowired
	private BaseConverterImpl<MappingKamarAsramaVO, MappingKamarAsrama> mappingKamarAsramaConverter;

	@Autowired
	private LoginUserService loginUserService;

//	@Transactional(readOnly = false)
	private String getRunningNumber(String kegunaan) {

		RunningNumber runningNumber = runningNumberDao.findByResetAndKegunaan("0", kegunaan);
		Integer number = (runningNumber.getNomerTerbaru() + (Integer) 1);
		runningNumber.setNomerTerbaru(runningNumber.getNomerTerbaru() + (Integer) 1);
		String noOrderIntern = StringUtil.formatNumber(number.toString(), 6);
		runningNumberDao.save(runningNumber);
		return noOrderIntern;
	}

	@Override
	public String getNoSurat() {
		String currentDate = null;
		Calendar calendar = Calendar.getInstance();
		if (CommonUtil.isNotNullOrEmpty(calendar)) {
			//Calendar calendar = Calendar.getInstance();
			Integer date = calendar.get(Calendar.DATE);
			String dateString = StringUtil.formatNumber(String.valueOf(date), 2);
			Integer month = calendar.get(Calendar.MONTH);
			String monthString = StringUtil.formatNumber(String.valueOf(month), 2);
			Integer year = calendar.get(Calendar.YEAR);
			Integer count=strukOrderDao.getCountSewaAsrama(new Date());
			System.out.println("Masuk kesini "+count);
			String stringKdTerima = StringUtil.formatNumber(String.valueOf(count + 1), 6);
			currentDate = "SA" + year.toString() + monthString + dateString + stringKdTerima;
		}
		return currentDate;
		
	}
	
	@Override
	public Map<String, Object> saveSewaAsrama(SewaAsramaVO vo) throws JpaSystemException, ServiceVOException {

		Map<String, Object> result = new HashMap<String, Object>();
		SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");

		try {
			System.out.println("==================START SAVE SEWA ASRAMA======================");
			if (CommonUtil.isNotNullOrEmpty(vo.getStrukOrder())) {
				System.out.println(":::START STRUK ORDER:::");
				StrukOrder strukOrder = strukOrderConverter.transferVOToModel(vo.getStrukOrder(), new StrukOrder());
				// set status
				strukOrder.setStatus(Status.TERISI.getVal());
				// set no order
				//strukOrder.setNoOrder(StringUtil
				//		.formatNumber(String.valueOf(strukOrderDao.getCountByMonthAndYear(new Date()) + 1), 10));
				//strukOrder.setNoOrderIntern("SA" + generateNoOrderByDayMonthAndYear(vo));
				strukOrder.setNoOrder(getNoSurat());
				strukOrder.setNoOrderIntern(getNoSurat());
				// Konversi dari string ke tanggal
				Date TglCheckIn = df.parse(df.format(strukOrder.getTglPelayananAwal()));
				Date tglCheckOut = df.parse(df.format(strukOrder.getTglPelayananAkhir()));
				// Tanggal di konversi ke milidetik
				long Hari1 = TglCheckIn.getTime();
				long Hari2 = tglCheckOut.getTime();
				long diff = Hari2 - Hari1;
				long Lama = diff / (24 * 60 * 60 * 1000);
				strukOrder.setLamaSewa(Long.toString(Lama) + "" + " Hari");

				strukOrder.setTglOrder(DateUtil.getShortDate());
				strukOrder.setQtyJenisProduk(1.0);
				strukOrder.setQtyProduk(1.0);
				strukOrder.setTotalBeaMaterai(0.0);
				strukOrder.setTotalBiayaKirim(0.0);
				strukOrder.setTotalBiayaTambahan(0.0);
				strukOrder.setTotalDiscount(0.0);
				strukOrder.setTotalHarusDibayar(0.0);
				strukOrder.setTotalPph(0.0);
				strukOrder.setTotalPpn(0.0);
				strukOrder.setPegawaiOrder(loginUserService.getLoginUser().getPegawai());
				strukOrder.setIsDelivered((byte) 1);
				strukOrder.setKeteranganOrder("Sewa Asrama");
				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:::");
					OrderPelayanan orderPelayanan = orderPelayananConverter.transferVOToModel(vo.getOrderPelayanan(),
							new OrderPelayanan());
					orderPelayanan.setStrukOrder(strukOrder);// set strukorderfk
					orderPelayanan.setNoOrder(strukOrder);// set noOrderfk
					// set kamar asrama
					Set<MappingKamarAsrama> list = new HashSet<MappingKamarAsrama>();
					for (MappingKamarAsramaVO model : vo.getOrderPelayanan().getMapKamarAsrama()) {
						MappingKamarAsrama mappingKamarAsrama = mappingKamarAsramaConverter.transferVOToModel(model,
								new MappingKamarAsrama());
						if (CommonUtil.isNotNullOrEmpty(model.getKamar())) {
							mappingKamarAsrama
									.setKamar(kamarConverter.transferVOToModel(model.getKamar(), new Kamar()));
						}
						if (CommonUtil.isNotNullOrEmpty(model.getRuangan())) {
							mappingKamarAsrama
									.setRuangan(ruanganConverter.transferVOToModel(model.getRuangan(), new Ruangan()));
							orderPelayanan.setRuangan(ruanganConverter
									.transferVOToModel(vo.getOrderPelayanan().getRuangan(), new Ruangan()));
							orderPelayanan.setRuanganTujuan(ruanganConverter
									.transferVOToModel(vo.getOrderPelayanan().getRuanganTujuan(), new Ruangan()));
						}
						mappingKamarAsrama.setOrderPelayanan(orderPelayanan);
						list.add(mappingKamarAsrama);
					}
					orderPelayanan.setMapKamarAsrama(list);

					orderPelayanan.setIsCito((byte) 1);
					orderPelayanan.setQtyProduk(1.0);
					orderPelayanan.setQtyProdukRetur(1.0);
					orderPelayanan.setTglPelayanan(strukOrder.getTglOrder());
					if (CommonUtil.isNotNullOrEmpty(vo.getOrderPelayanan().getProduk())) {
						orderPelayanan.setProduk(
								produkConverter.transferVOToModel(vo.getOrderPelayanan().getProduk(), new Produk()));
						orderPelayanan.getProduk().setNilaiNormal((short) 1);
						orderPelayanan.getProduk().setqProduk(1);
						orderPelayanan.getProduk().setQtyJualTerkecil(1.0);
						orderPelayanan.getProduk().setQtySatuKemasan(1);
						orderPelayanan.getProduk().setQtyTerkecil(1.0);
					}
					OrderPelayanan resultModelOrderPelayanan = orderPelayananDao.save(orderPelayanan);
					result.put("noRecOrderPelayanan", resultModelOrderPelayanan.getNoRec());
					System.out.println(":::END ORDER PELAYANAN:::");
					
					// implement pencatatan jurnal (LogAcc) jika data berhasil disimpan
					if(CommonUtil.isNotNullOrEmpty(orderPelayanan.getNoRec())) {
						LogAcc log = new LogAcc();
						log.setTanggal(orderPelayanan.getTglPelayanan());
						log.setNoReff(orderPelayanan.getNoRec());
						log.setJenisTransaksi("save sewa asrama");
						if(CommonUtil.isNotNullOrEmpty(log)) {
							logAccDao.save(log);
						}
					}
					
				}
			}
			System.out.println("==================END SAVE SEWA ASRAMA======================");
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;

	}

	@Override
	public String generateNoOrderByDayMonthAndYear(SewaAsramaVO 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);
		//cal.sett
		int day = cal.get(Calendar.DAY_OF_MONTH);
		return day;
	}

	@Override
	public Map<String, Object> findByNoOrder(String noOrder) {

		Map<String, Object> result = new HashMap<String, Object>();
		try {
			System.out.println("==========START FIND SEWA ASRAMA BY NO ORDER==========");
			StrukOrder resultModel = strukOrderDao.findByNoOrder(noOrder);
			if (CommonUtil.isNotNullOrEmpty(resultModel)) {
				result.put("data", resultModel);
				result.put("SewaAsramaByNoOrder", true);
			} else {
				result.put("SewaAsramaByNoOrder", false);
			}
			System.out.println("==========END FIND SEWA ASRAMA BY NO ORDER==========");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	@Override
	public Map<String, Object> findStatusKamar(String periodeAwal, String periodeAkhir, Integer idKamar) {

		List<SewaAsramaDto> model = new ArrayList<SewaAsramaDto>();
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			System.out.println("==========START FIND STATUS KAMAR ASRAMA==========");
			model = kamarDao.findStatusKamar(periodeAwal, periodeAkhir, idKamar);
			if (CommonUtil.isNotNullOrEmpty(model)) {
				result.put("data", model);
				result.put("StatusKamar", true);
			} else {
				result.put("StatusKamar", false);
			}
			System.out.println("==========END FIND STATUS KAMAR ASRAMA==========");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	@Override
	public Map<String, Object> findKamar(String namaRuangan) {

		List<Kamar> model = new ArrayList<Kamar>();
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			System.out.println("==========START FIND KAMAR ASRAMA==========");
			model = kamarDao.findKamar(namaRuangan);
			if (CommonUtil.isNotNullOrEmpty(model)) {
				result.put("data", model);
				result.put("KamarAsrama", true);
			} else {
				result.put("KamarAsrama", false);
			}
			System.out.println("==========END FIND KAMAR ASRAMA==========");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

}
