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.List;
import java.util.Map;

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.converter.ProdukConverter;
import com.jasamedika.medifirst2000.dao.LogAccDao;
import com.jasamedika.medifirst2000.dao.OrderPelayananDao;
import com.jasamedika.medifirst2000.dao.ProdukDao;
import com.jasamedika.medifirst2000.dao.RunningNumberDao;
import com.jasamedika.medifirst2000.dao.StrukOrderDao;
import com.jasamedika.medifirst2000.dto.SewaLahanDto;
import com.jasamedika.medifirst2000.entities.LogAcc;
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.SatuanWaktu;
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.SewaLahanService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.util.DateUtil;
import com.jasamedika.medifirst2000.util.StringUtil;
import com.jasamedika.medifirst2000.vo.OrderPelayananVO;
import com.jasamedika.medifirst2000.vo.RuanganVO;
import com.jasamedika.medifirst2000.vo.SatuanWaktuVO;
import com.jasamedika.medifirst2000.vo.SewaLahanVO;
import com.jasamedika.medifirst2000.vo.StrukOrderVO;

@Service("sewaLahanService")
public class SewaLahanServiceImpl extends BaseVoServiceImpl implements SewaLahanService {

	@Autowired
	private StrukOrderDao strukOrderDao;

	@Autowired
	private OrderPelayananDao orderPelayananDao;

	@Autowired
	private ProdukDao produkDao;

	@Autowired
	private RunningNumberDao runningNumberDao;
	
	@Autowired
	private LogAccDao logAccDao;

	@Autowired
	private BaseConverterImpl<StrukOrderVO, StrukOrder> strukOrderConverter;

	@Autowired
	private BaseConverterImpl<OrderPelayananVO, OrderPelayanan> orderPelayananConverter;

	@Autowired
	private LoginUserService loginUserService;

	@Autowired
	private ProdukConverter produkConverter;

	@Autowired
	private BaseConverterImpl<SatuanWaktuVO, SatuanWaktu> satuanWaktuConverter;

	@Autowired
	private BaseConverterImpl<RuanganVO, Ruangan> ruanganConverter;

//	@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 Map<String, Object> saveSewaLahan(SewaLahanVO vo) throws JpaSystemException, ServiceVOException {

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

		try {
			System.out.println("==================START SAVE SEWA LAHAN======================");
			if (CommonUtil.isNotNullOrEmpty(vo.getStrukOrder())) {
				System.out.println(":::START STRUK ORDER:::");
				StrukOrder strukOrder = strukOrderConverter.transferVOToModel(vo.getStrukOrder(), new StrukOrder());
				// set no order sewa lahan
				strukOrder.setNoOrder(StringUtil
						.formatNumber(String.valueOf(strukOrderDao.getCountByMonthAndYear(new Date()) + 1), 10));
				strukOrder.setNoOrderIntern("SL" + generateNoOrderByDayMonthAndYear(vo));
				// set status sewa lahan
				strukOrder.setStatus(Status.DIPAKAI.getVal());
				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 Lahan");
				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 satuan waktu
					if (CommonUtil.isNotNullOrEmpty(vo.getOrderPelayanan().getSatuanWaktu())) {
						orderPelayanan.setSatuanWaktu(satuanWaktuConverter
								.transferVOToModel(vo.getOrderPelayanan().getSatuanWaktu(), new SatuanWaktu()));
					}
					orderPelayanan.setIsCito((byte) 1);
					orderPelayanan.setQtyProduk(1.0);
					orderPelayanan.setQtyProdukRetur(1.0);
					orderPelayanan.setTglPelayanan(strukOrder.getTglOrder());
					if (CommonUtil.isNotNullOrEmpty(vo.getOrderPelayanan().getRuangan())) {
						orderPelayanan.setRuangan(
								ruanganConverter.transferVOToModel(vo.getOrderPelayanan().getRuangan(), new Ruangan()));
					}
					if (CommonUtil.isNotNullOrEmpty(vo.getOrderPelayanan().getRuanganTujuan())) {
						orderPelayanan.setRuanganTujuan(ruanganConverter
								.transferVOToModel(vo.getOrderPelayanan().getRuanganTujuan(), new Ruangan()));
					}
					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);
					}
					StrukOrder resultModelStrukOrder = strukOrderDao.save(strukOrder);
					result.put("noRecStrukOrder", resultModelStrukOrder.getNoRec());
					System.out.println(":::END STRUK ORDER:::");
					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 Pphp");
						if(CommonUtil.isNotNullOrEmpty(log)) {
							logAccDao.save(log);
						}
					}
					
				}
			}
			System.out.println("==================END SAVE SEWA LAHAN======================");
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;
	}

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

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

	@Override
	public String generateNoOrderByDayMonthAndYear(SewaLahanVO 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<SewaLahanDto> findProdukSewaLahan() {

		List<SewaLahanDto> model = new ArrayList<SewaLahanDto>();
		try {
			System.out.println("==================START FIND PRODUK(SEWA LAHAN)======================");
			model = produkDao.findProdukSewaLahan();
			System.out.println("==================END FIND PRODUK(SEWA LAHAN)======================");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return model;
	}

	@Override
	public Map<String, Object> findStatusLahan(String periodeAwal, String periodeAkhir, Integer idProduk) {

		List<SewaLahanDto> model = new ArrayList<SewaLahanDto>();
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			System.out.println("==========START FIND STATUS LAHAN==========");
			model = produkDao.findStatusLahan(periodeAwal, periodeAkhir, idProduk);
			if (CommonUtil.isNotNullOrEmpty(model)) {
				result.put("data", model);
				result.put("StatusLahan", true);
			} else {
				result.put("StatusLahan", false);
			}
			System.out.println("==========END FIND STATUS LAHAN==========");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

}
