package com.jasamedika.medifirst2000.service.impl;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Service;

import com.jasamedika.medifirst2000.converter.BaseConverterImpl;
import com.jasamedika.medifirst2000.dao.MapProdukKelompokKerjaDao;
import com.jasamedika.medifirst2000.dao.SubUnitKerjaDao;
import com.jasamedika.medifirst2000.entities.MapProdukKelompokKerja;
import com.jasamedika.medifirst2000.entities.Produk;
import com.jasamedika.medifirst2000.entities.SubUnitKerjaPegawai;
import com.jasamedika.medifirst2000.exception.ServiceVOException;
import com.jasamedika.medifirst2000.service.MapProdukKelompokKerjaService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.vo.MapProdukKelompokKerjaVO;
import com.jasamedika.medifirst2000.vo.ProdukVO;
import com.jasamedika.medifirst2000.vo.SubUnitKerjaPegawaiVO;

/**
 * @author salmanoe
 * @since Mar 9, 2022
 */
@Service("mapProdukKelompokKerjaService")
public class MapProdukKelompokKerjaServiceImpl extends BaseVoServiceImpl implements MapProdukKelompokKerjaService {

	@Autowired
	private BaseConverterImpl<MapProdukKelompokKerjaVO, MapProdukKelompokKerja> mappingConverter;

	@Autowired
	private BaseConverterImpl<ProdukVO, Produk> produkConverter;

	@Autowired
	private BaseConverterImpl<SubUnitKerjaPegawaiVO, SubUnitKerjaPegawai> subunitKerjaConverter;

	@Autowired
	private MapProdukKelompokKerjaDao mapProdukKelompokKerjaDao;

	@Autowired
	private SubUnitKerjaDao subUnitKerjaDao;

	@Override
	public MapProdukKelompokKerjaVO add(MapProdukKelompokKerjaVO vo) throws JpaSystemException, ServiceVOException {
		Produk produk = produkConverter.transferVOToModel(vo.getProduk(), new Produk());
		SubUnitKerjaPegawai kelompokKerja = subunitKerjaConverter.transferVOToModel(vo.getKelompokKerja(),
				new SubUnitKerjaPegawai());

		MapProdukKelompokKerja mapping = mappingConverter.transferVOToModel(vo, new MapProdukKelompokKerja());
		mapping.setProduk(produk);
		mapping.setKelompokKerja(kelompokKerja);

		MapProdukKelompokKerja resultModel = mapProdukKelompokKerjaDao.save(mapping);

		MapProdukKelompokKerjaVO resultVO = new MapProdukKelompokKerjaVO();
		resultVO = mappingConverter.transferModelToVO(resultModel, resultVO);

		return resultVO;
	}

	@Override
	public List<String> addAll(List<MapProdukKelompokKerjaVO> vos) throws JpaSystemException, ServiceVOException {
		List<String> result = new ArrayList<>();

		List<MapProdukKelompokKerja> mappings = new ArrayList<>();
		for (MapProdukKelompokKerjaVO vo : vos) {
			Produk produk = produkConverter.transferVOToModel(vo.getProduk(), new Produk());
			SubUnitKerjaPegawai kelompokKerja = subunitKerjaConverter.transferVOToModel(vo.getKelompokKerja(),
					new SubUnitKerjaPegawai());

			MapProdukKelompokKerja mapping = mappingConverter.transferVOToModel(vo, new MapProdukKelompokKerja());
			mapping.setProduk(produk);
			mapping.setKelompokKerja(kelompokKerja);

			mappings.add(mapping);
		}

		List<MapProdukKelompokKerja> addAll = new ArrayList<>();
		List<MapProdukKelompokKerja> removeAll = new ArrayList<>();
		for (MapProdukKelompokKerja mapping : mappings) {
			if (mapping.getStatusEnabled()) {
				addAll.add(mapping);
			} else {
				removeAll.add(mapping);
			}
		}

		// save all mapping
		Iterable<MapProdukKelompokKerja> models = mapProdukKelompokKerjaDao.save(addAll);
		for (MapProdukKelompokKerja model : models) {
			MapProdukKelompokKerjaVO vo = new MapProdukKelompokKerjaVO();
			vo = mappingConverter.transferModelToVO(model, vo);
			result.add("MapProdukKelompokKerja(" + vo.getNoRec() + ") added");
		}

		// delete all mapping
		mapProdukKelompokKerjaDao.delete(removeAll);
		for (MapProdukKelompokKerja model : removeAll) {
			result.add("Produk(" + model.getProduk().getId() + ") - SubUnitKerjaPegawai("
					+ model.getKelompokKerja().getId() + ") removed");
		}

		return result;
	}

	@Override
	public MapProdukKelompokKerjaVO update(MapProdukKelompokKerjaVO vo) throws JpaSystemException, ServiceVOException {
		MapProdukKelompokKerja mappingLama = mapProdukKelompokKerjaDao.findOne(vo.getNoRec());

		Produk produk = produkConverter.transferVOToModel(vo.getProduk(), new Produk());
		SubUnitKerjaPegawai kelompokKerja = subunitKerjaConverter.transferVOToModel(vo.getKelompokKerja(),
				new SubUnitKerjaPegawai());

		MapProdukKelompokKerja mappingBaru = mappingConverter.transferVOToModel(vo, mappingLama);
		mappingBaru.setProduk(produk);
		mappingBaru.setKelompokKerja(kelompokKerja);

		MapProdukKelompokKerja resultModel = mapProdukKelompokKerjaDao.save(mappingBaru);

		MapProdukKelompokKerjaVO resultVO = new MapProdukKelompokKerjaVO();
		resultVO = mappingConverter.transferModelToVO(resultModel, resultVO);

		return resultVO;
	}

	@Override
	public Boolean delete(String key) throws JpaSystemException {
		mapProdukKelompokKerjaDao.delete(key);

		return true;
	}

	@Override
	public MapProdukKelompokKerjaVO findById(String key) throws JpaSystemException {
		MapProdukKelompokKerjaVO result = new MapProdukKelompokKerjaVO();

		MapProdukKelompokKerja mapping = mapProdukKelompokKerjaDao.findOne(key);
		if (CommonUtil.isNotNullOrEmpty(mapping)) {
			result = mappingConverter.transferModelToVO(mapping, result);
		}

		return result;
	}

	@Override
	public List<MapProdukKelompokKerjaVO> findAll() throws JpaSystemException {
		List<MapProdukKelompokKerjaVO> result = new ArrayList<MapProdukKelompokKerjaVO>();

		Iterable<MapProdukKelompokKerja> models = mapProdukKelompokKerjaDao.findAll();
		if (CommonUtil.isNotNullOrEmpty(models)) {
			for (MapProdukKelompokKerja model : models) {
				MapProdukKelompokKerjaVO vo = new MapProdukKelompokKerjaVO();
				vo = mappingConverter.transferModelToVO(model, vo);
				result.add(vo);
			}
		}

		return result;
	}

	@Override
	public Map<String, Object> findAllWithPageAndLimitAndSortByAndDirectionParameter(Integer page, Integer limit,
			String sort, String dir) {

		return null;
	}

	@Override
	public List<Map<String, Object>> getAllProduk() throws JpaSystemException {
		List<Map<String, Object>> result = mapProdukKelompokKerjaDao.findProdukMapping();

		return result;
	}

	@Override
	public List<Map<String, Object>> getAllKelompokKerja(Integer idProduk) throws JpaSystemException {
		List<Map<String, Object>> result = new ArrayList<>();

		List<Map<String, Object>> kelompokKerja = subUnitKerjaDao.findAllKelompokKerjaMedis();
		List<Map<String, Object>> mapping = mapProdukKelompokKerjaDao.findMappingByProduk(idProduk);

		for (Map<String, Object> mapRs : kelompokKerja) {
			mapRs.put("noRec", null);
			mapRs.put("statusMapping", false);
			for (Map<String, Object> map : mapping) {
				if (mapRs.get("subunitKerjaId").equals(map.get("kelompokKerjaId"))
						&& CommonUtil.isNotNullOrEmpty(map.get("noRec"))) {
					mapRs.put("noRec", map.get("noRec").toString());
					mapRs.put("statusMapping", true);
				}
			}
			result.add(mapRs);
		}

		result = result.stream().sorted(Comparator.comparing(o1 -> o1.get("subunitKerja").toString()))
				.sorted(Comparator.comparing(o2 -> o2.get("unitKerja").toString())).collect(Collectors.toList());

		return result;
	}

}
