package com.jasamedika.medifirst2000.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import com.jasamedika.medifirst2000.constants.Master;
import com.jasamedika.medifirst2000.constants.Master.SubKategoriPegawai;
import com.jasamedika.medifirst2000.constants.Master.SubUnitKerja;
import com.jasamedika.medifirst2000.converter.BaseConverterImpl;
import com.jasamedika.medifirst2000.dao.JabatanDao;
import com.jasamedika.medifirst2000.dao.KelompokJabatanDao;
import com.jasamedika.medifirst2000.dao.MapPegawaiJabatanToUnitKerjaDao;
import com.jasamedika.medifirst2000.dao.SettingDataFixedDao;
import com.jasamedika.medifirst2000.entities.Eselon;
import com.jasamedika.medifirst2000.entities.Jabatan;
import com.jasamedika.medifirst2000.entities.JenisJabatan;
import com.jasamedika.medifirst2000.entities.KelompokJabatan;
import com.jasamedika.medifirst2000.entities.UnitKerjaPegawai;
import com.jasamedika.medifirst2000.exception.ServiceVOException;
import com.jasamedika.medifirst2000.service.JabatanService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.vo.EselonVO;
import com.jasamedika.medifirst2000.vo.JabatanVO;
import com.jasamedika.medifirst2000.vo.JenisJabatanVO;
import com.jasamedika.medifirst2000.vo.KelompokJabatanVO;
import com.jasamedika.medifirst2000.vo.UnitKerjaPegawaiVO;

/**
 * Implement class for JabatanService
 * 
 * @author Generator
 * @param <T>
 */
@Service("jabatanService")
public class JabatanServiceImpl extends BaseVoServiceImpl implements JabatanService {

	@Autowired
	private BaseConverterImpl<JabatanVO, Jabatan> jabatanConverter;

	@Autowired
	private BaseConverterImpl<KelompokJabatanVO, KelompokJabatan> kelompokJabatanConverter;

	@Autowired
	private BaseConverterImpl<JenisJabatanVO, JenisJabatan> jenisJabatanConverter;

	@Autowired
	private BaseConverterImpl<UnitKerjaPegawaiVO, UnitKerjaPegawai> unitKerjaConverter;

	@Autowired
	private BaseConverterImpl<EselonVO, Eselon> eselonConverter;

	@Autowired
	private JabatanDao jabatanDao;

	@Autowired
	private KelompokJabatanDao kelompokJabatanDao;

	@Autowired
	private MapPegawaiJabatanToUnitKerjaDao mapPegawaiJabatanToUnitKerjaDao;

	@Autowired
	private SettingDataFixedDao settingDataFixedDao;

	@Override
	public Map<String, Object> saveJabatanInternal(JabatanVO vo) {
		Map<String, Object> result = new HashMap<String, Object>();
		Jabatan model = new Jabatan();
		JenisJabatan jenisJabatan = new JenisJabatan();
		jenisJabatan.setId(3);
		model.setJenisJabatan(jenisJabatan);
		model = jabatanConverter.transferVOToModel(vo, model);

		Jabatan resultDomain = jabatanDao.save(model);
		if (CommonUtil.isNotNullOrEmpty(resultDomain)) {
			result.put("noRec", resultDomain.getNoRec());
		}

		return result;
	}

	@Override
	public JabatanVO add(JabatanVO vo) throws JpaSystemException, ServiceVOException {
		Jabatan jabatan = jabatanConverter.transferVOToModel(vo, new Jabatan());

		UnitKerjaPegawai unitKerja = unitKerjaConverter.transferVOToModel(vo.getUnitKerja(), new UnitKerjaPegawai());
		JenisJabatan jenisJabatan = jenisJabatanConverter.transferVOToModel(vo.getJenisJabatan(), new JenisJabatan());
		KelompokJabatan kelompokJabatan = kelompokJabatanConverter.transferVOToModel(vo.getKelompokJabatan(),
				new KelompokJabatan());

		if (CommonUtil.isNotNullOrEmpty(vo.getEselon())) {
			Eselon eselon = eselonConverter.transferVOToModel(vo.getEselon(), new Eselon());
			jabatan.setEselon(eselon);
		}
		jabatan.setUnitKerja(unitKerja);
		jabatan.setJenisJabatan(jenisJabatan);
		jabatan.setKelompokJabatan(kelompokJabatan);
		Jabatan resultModel = jabatanDao.save(jabatan);

		JabatanVO resultVO = new JabatanVO();
		resultVO = jabatanConverter.transferModelToVO(resultModel, resultVO);

		return resultVO;
	}

	@Override
	public JabatanVO update(JabatanVO vo) throws JpaSystemException, ServiceVOException {
		Jabatan jabatanLama = jabatanDao.findOne(vo.getId());
		Jabatan jabatanBaru = jabatanConverter.transferVOToModel(vo, jabatanLama);

		if (CommonUtil.isNotNullOrEmpty(vo.getUnitKerja())) {
			UnitKerjaPegawai unitKerja = unitKerjaConverter.transferVOToModel(vo.getUnitKerja(),
					new UnitKerjaPegawai());
			jabatanBaru.setUnitKerja(unitKerja);
		}

		if (CommonUtil.isNotNullOrEmpty(vo.getJenisJabatan())) {
			JenisJabatan jenisJabatan = jenisJabatanConverter.transferVOToModel(vo.getJenisJabatan(),
					new JenisJabatan());
			jabatanBaru.setJenisJabatan(jenisJabatan);
		}

		if (CommonUtil.isNotNullOrEmpty(vo.getKelompokJabatan())) {
			KelompokJabatan kelompokJabatan = kelompokJabatanConverter.transferVOToModel(vo.getKelompokJabatan(),
					new KelompokJabatan());
			jabatanBaru.setKelompokJabatan(kelompokJabatan);
		}

		if (CommonUtil.isNotNullOrEmpty(vo.getEselon())) {
			Eselon eselon = eselonConverter.transferVOToModel(vo.getEselon(), new Eselon());
			jabatanBaru.setEselon(eselon);
		} else if (CommonUtil.isNullOrEmpty(vo.getEselon()) && CommonUtil.isNotNullOrEmpty(jabatanBaru.getEselon())) {
			// hapus eselon
			jabatanBaru.setEselon(null);
		}

		Jabatan resultModel = jabatanDao.save(jabatanBaru);

		JabatanVO resultVO = new JabatanVO();
		resultVO = jabatanConverter.transferModelToVO(resultModel, resultVO);

		return resultVO;
	}

	@Override
	public Boolean delete(Integer key) throws JpaSystemException {
		jabatanDao.delete(key);

		return true;
	}

	@Override
	public JabatanVO findById(Integer key) throws JpaSystemException {
		JabatanVO result = new JabatanVO();

		Jabatan jabatan = jabatanDao.findOne(key);
		if (CommonUtil.isNotNullOrEmpty(jabatan)) {
			result = jabatanConverter.transferModelToVO(jabatan, result);
		}

		return result;
	}

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

		Iterable<Jabatan> models = jabatanDao.findAll();
		if (CommonUtil.isNotNullOrEmpty(models)) {
			for (Jabatan model : models) {
				JabatanVO vo = new JabatanVO();
				vo = jabatanConverter.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 Map<String, Object> saveJabatan(JabatanVO vo) {
		Map<String, Object> result = new HashMap<String, Object>();

		// organization business validation
		if ((vo.getLevelJabatan() == 1 || vo.getLevelJabatan() == 5)
				&& CommonUtil.isNotNullOrEmpty(vo.getSubLevelJabatan())) {
			/**
			 * direktur utama dan staf/ ketua tim tidak memiliki level direksi
			 */
			vo.setSubLevelJabatan(null);
		}

		if (CommonUtil.isNullOrEmpty(vo.getId())) {
			Jabatan model = new Jabatan();
			BeanUtils.copyProperties(vo, model);

			JenisJabatan jenisJabatan = new JenisJabatan();
			jenisJabatan.setId(vo.getJenisJabatan().getId());
			model.setJenisJabatan(jenisJabatan);

			Eselon eselon = new Eselon();
			eselon.setId(vo.getEselon().getId());
			model.setEselon(eselon);

			if (CommonUtil.isNotNullOrEmpty(vo.getUnitKerja())) {
				UnitKerjaPegawai unitKerja = new UnitKerjaPegawai();
				unitKerja.setId(vo.getUnitKerja().getId());
				model.setUnitKerja(unitKerja);
			}

			if (CommonUtil.isNotNullOrEmpty(vo.getLevelJabatan())) {
				model.setLevelJabatan(vo.getLevelJabatan());
			}
			if (CommonUtil.isNotNullOrEmpty(vo.getSubLevelJabatan())) {
				model.setSubLevelJabatan(vo.getSubLevelJabatan());
			}
			model = jabatanDao.save(model);
			if (CommonUtil.isNotNullOrEmpty(model)) {
				result.put("noRec", model.getNoRec());
			}
		} else {
			result.put("noRec", update(vo).getNoRec());
		}
		return result;
	}

	@Override
	public List<Map<String, Object>> getJabatanStruktural() {
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		List<Jabatan> temp = jabatanDao.getJabatanStruktural(2);
		for (Jabatan jab : temp) {
			try {
				result.add(jab.ToMap());
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	@Override
	public List<Map<String, Object>> findModelJabatan(Integer idJenisJabatan) {
		List<Map<String, Object>> result = jabatanDao.getJabatanByJenisJabatan(idJenisJabatan);

		return result;
	}

	@Override
	public List<Map<String, Object>> findModelJabatan(Integer idJenisJabatan, Integer idUnitKerja) {
		List<Map<String, Object>> result = jabatanDao.findModelJabatanByJenisUnit(idJenisJabatan, idUnitKerja);

		return result;
	}

	@Override
	public Map<String, Object> saveKelompokJabatan(KelompokJabatanVO vo) {
		Map<String, Object> result = new HashMap<String, Object>();
		if (CommonUtil.isNotNullOrEmpty(vo)) {
			KelompokJabatan kelompokJabatan = kelompokJabatanConverter.transferVOToModel(vo, new KelompokJabatan());
			if (CommonUtil.isNotNullOrEmpty(kelompokJabatan)) {
				KelompokJabatan model = kelompokJabatanDao.save(kelompokJabatan);
				result.put("id", model.getId());
			}
		}
		return result;
	}

	@Override
	public List<Map<String, Object>> getKelompokJabatan() {
		List<Map<String, Object>> result = kelompokJabatanDao.getAllByStatusEnabled();
		return result;
	}

	@Override
	public JabatanVO deleteJabatan(JabatanVO vo) {
		Jabatan jabatan = jabatanDao.findOne(vo.getId());
		if (CommonUtil.isNotNullOrEmpty(jabatan)) {
			jabatan.setStatusEnabled(false);
			jabatanDao.save(jabatan);
			return vo;
		}
		return vo;
	}

	@Override
	public List<Map<String, Object>> getListJabatanFungsionalStruktural() {
		List<Map<String, Object>> result = jabatanDao.getListJabatanFungsionalStruktural();
		return result;
	}

	@Override
	public Map<String, Object> validateNamaJabatan(Integer idJabatan, String namaJabatan, Integer idJenisJabatan,
			Integer idUnitKerja) throws JpaSystemException {
		Map<String, Object> result = new HashMap<>();

		String patternText = settingDataFixedDao.getSettingDataFixed("patternTextDuplicate");
		String replacedNamaJabatan = namaJabatan.replaceAll(patternText, "").toLowerCase();
		List<Map<String, Object>> listNamaJabatan = new ArrayList<>();
		if (CommonUtil.isNotNullOrEmpty(idJabatan) && CommonUtil.isNotNullOrEmpty(idUnitKerja)) {
			listNamaJabatan = jabatanDao.checkNamaJabatan(idJabatan, replacedNamaJabatan, idJenisJabatan, idUnitKerja);
		} else if (CommonUtil.isNotNullOrEmpty(idJabatan) && CommonUtil.isNullOrEmpty(idUnitKerja)) {
			listNamaJabatan = jabatanDao.checkNamaJabatan(idJabatan, replacedNamaJabatan, idJenisJabatan);
		} else if (CommonUtil.isNullOrEmpty(idJabatan) && CommonUtil.isNotNullOrEmpty(idUnitKerja)) {
			listNamaJabatan = jabatanDao.checkNamaJabatan(replacedNamaJabatan, idJenisJabatan, idUnitKerja);
		} else if (CommonUtil.isNullOrEmpty(idJabatan) && CommonUtil.isNullOrEmpty(idUnitKerja)) {
			listNamaJabatan = jabatanDao.checkNamaJabatan(replacedNamaJabatan, idJenisJabatan);
		}

		if (CommonUtil.isNotNullOrEmpty(listNamaJabatan)) {
			result.put("msg", "Jabatan " + namaJabatan + " sudah tersedia!");
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findJabatan(String namaJabatan, Integer idJenisJabatan, Integer idUnitKerja) {
		List<Map<String, Object>> result = new ArrayList<>();

		if (CommonUtil.isNullOrEmpty(namaJabatan.toLowerCase()) && CommonUtil.isNullOrEmpty(idJenisJabatan)
				&& CommonUtil.isNullOrEmpty(idUnitKerja)) {
			result = jabatanDao.findJabatan();
		} else if (CommonUtil.isNotNullOrEmpty(namaJabatan.toLowerCase()) && CommonUtil.isNullOrEmpty(idJenisJabatan)
				&& CommonUtil.isNullOrEmpty(idUnitKerja)) {
			result = jabatanDao.findJabatanByNama(namaJabatan.toLowerCase());
		} else if (CommonUtil.isNullOrEmpty(namaJabatan.toLowerCase()) && CommonUtil.isNotNullOrEmpty(idJenisJabatan)
				&& CommonUtil.isNullOrEmpty(idUnitKerja)) {
			result = jabatanDao.findJabatanByJenis(idJenisJabatan);
		} else if (CommonUtil.isNullOrEmpty(namaJabatan.toLowerCase()) && CommonUtil.isNullOrEmpty(idJenisJabatan)
				&& CommonUtil.isNotNullOrEmpty(idUnitKerja)) {
			result = jabatanDao.findJabatanByUnit(idUnitKerja);
		} else if (CommonUtil.isNotNullOrEmpty(namaJabatan.toLowerCase()) && CommonUtil.isNotNullOrEmpty(idJenisJabatan)
				&& CommonUtil.isNullOrEmpty(idUnitKerja)) {
			result = jabatanDao.findJabatanByNamaJenis(namaJabatan.toLowerCase(), idJenisJabatan);
		} else if (CommonUtil.isNotNullOrEmpty(namaJabatan.toLowerCase()) && CommonUtil.isNullOrEmpty(idJenisJabatan)
				&& CommonUtil.isNotNullOrEmpty(idUnitKerja)) {
			result = jabatanDao.findJabatanByNamaUnit(namaJabatan.toLowerCase(), idUnitKerja);
		} else if (CommonUtil.isNullOrEmpty(namaJabatan.toLowerCase()) && CommonUtil.isNotNullOrEmpty(idJenisJabatan)
				&& CommonUtil.isNotNullOrEmpty(idUnitKerja)) {
			result = jabatanDao.findJabatanByJenisUnit(idJenisJabatan, idUnitKerja);
		} else if (CommonUtil.isNotNullOrEmpty(namaJabatan.toLowerCase()) && CommonUtil.isNotNullOrEmpty(idJenisJabatan)
				&& CommonUtil.isNotNullOrEmpty(idUnitKerja)) {
			result = jabatanDao.findJabatanByNamaJenisUnit(namaJabatan.toLowerCase(), idJenisJabatan, idUnitKerja);
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findPegawaiByJabatan(Integer idJabatan) throws JpaSystemException {
		List<Map<String, Object>> result = mapPegawaiJabatanToUnitKerjaDao.findPegawaiByJabatan(idJabatan);

		return result;
	}

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

		List<Map<String, Object>> dataPeringkat = jabatanDao
				.findPeringkatJabatan(Arrays.asList(Master.KelompokJabatan.RANGE_REMUN));
		List<Map<String, Object>> dataJabatan = jabatanDao.findJabatan(idJenisJabatan, idUnitKerja);
		for (Map<String, Object> jabatan : dataJabatan) {
			Integer nilaiTerendah = null;
			Integer nilaiTertinggi = null;
			for (Map<String, Object> peringkat : dataPeringkat) {
				if (CommonUtil.isNotNullOrEmpty(jabatan.get("kelompokJabatanId"))
						&& jabatan.get("kelompokJabatanId").equals(peringkat.get("kelompokJabatanId"))) {
					nilaiTerendah = Integer.valueOf(peringkat.get("nilaiTerendah").toString());
					nilaiTertinggi = Integer.valueOf(peringkat.get("nilaiTertinggi").toString());

					break;
				}
			}
			jabatan.put("nilaiTerendah", nilaiTerendah);
			jabatan.put("nilaiTertinggi", nilaiTertinggi);

			result.add(jabatan);
		}

		return result;
	}

	@Override
	public Map<String, Object> findAksesLogbookSkoring(Integer idPegawai) throws JpaSystemException {
		Map<String, Object> result = new HashMap<>();

		List<Map<String, Object>> data = kelompokJabatanDao.findIdByLoginLogbookSkor(idPegawai);
		if (CommonUtil.isNotNullOrEmpty(data)) {
			result.put("kategori", data.get(0).get("kelompokJabatanId"));
			if (SubUnitKerja.KK_FARMAKOLOGI.equals(data.get(0).get("subunitKerjaId"))) {
				result.put("subKategori", SubKategoriPegawai.DOKTER_FARMAKOLOGI);
			} else {
				result.put("subKategori", 0);
			}
		}

		return result;
	}

	@Override
	public List<Map<String, Object>> findByUnitKerja(Integer idUnitKerja) throws JpaSystemException {
		List<Map<String, Object>> result = jabatanDao.findByUnitKerja(idUnitKerja);

		return result;
	}

}