package com.jasamedika.medifirst2000.service.impl;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
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.RuanganConverter;
import com.jasamedika.medifirst2000.converter.StrukOrderConverter;
import com.jasamedika.medifirst2000.dao.HistoryAlatDao;
import com.jasamedika.medifirst2000.dao.RegistrasiAsetDao;
import com.jasamedika.medifirst2000.dao.RuanganDao;
import com.jasamedika.medifirst2000.dao.StrukPelayananDetailDao;
import com.jasamedika.medifirst2000.dao.custom.StrukPelayananDetailDaoCustom;
import com.jasamedika.medifirst2000.entities.DetailJenisProduk;
import com.jasamedika.medifirst2000.entities.DetailSpekAnggaran;
import com.jasamedika.medifirst2000.entities.HistoryAlat;
import com.jasamedika.medifirst2000.entities.JenisProduk;
import com.jasamedika.medifirst2000.entities.KelompokAset;
import com.jasamedika.medifirst2000.entities.MerkProduk;
import com.jasamedika.medifirst2000.entities.Produk;
import com.jasamedika.medifirst2000.entities.RegistrasiAset;
import com.jasamedika.medifirst2000.entities.Rekanan;
import com.jasamedika.medifirst2000.entities.RekananSkKontrak;
import com.jasamedika.medifirst2000.entities.Ruangan;
import com.jasamedika.medifirst2000.entities.SatuanStandar;
import com.jasamedika.medifirst2000.entities.StrukOrder;
import com.jasamedika.medifirst2000.entities.TypeProduk;
import com.jasamedika.medifirst2000.exception.ServiceVOException;
import com.jasamedika.medifirst2000.service.RegistrasiAsetService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.vo.DetailJenisProdukVO;
import com.jasamedika.medifirst2000.vo.DistribusiBarangInvestasiVO;
import com.jasamedika.medifirst2000.vo.GridDetailAnggaran;
import com.jasamedika.medifirst2000.vo.GridRegisterAset;
import com.jasamedika.medifirst2000.vo.HistoryAlatVO;
import com.jasamedika.medifirst2000.vo.JenisProdukVO;
import com.jasamedika.medifirst2000.vo.KelompokAsetVO;
import com.jasamedika.medifirst2000.vo.MerkProdukVO;
import com.jasamedika.medifirst2000.vo.RegistrasiAsetVO;
import com.jasamedika.medifirst2000.vo.RekananSkKontrakVO;
import com.jasamedika.medifirst2000.vo.RekananVO;
import com.jasamedika.medifirst2000.vo.SatuanStandarVO;
import com.jasamedika.medifirst2000.vo.StrukOrderVO;
import com.jasamedika.medifirst2000.vo.TypeProdukVO;


/**
 * 
 * @author adik
 */
@Service("RegistrasiAsetService")
public class RegistrasiAsetServiceImpl extends BaseAngaranServiceImpl implements RegistrasiAsetService<RegistrasiAsetVO>{
	
	@Value("${reportDirectory}")
	String reportDirectory;
	
	@Autowired
	private BaseConverterImpl<RegistrasiAsetVO, RegistrasiAset> registrasiAsetConverter;
	
	@Autowired
	private BaseConverterImpl<StrukOrderVO,StrukOrder> strukOrderConverter;
	
	@Autowired
	private BaseConverterImpl<KelompokAsetVO, KelompokAset> kelompokAsetConverter;
	
	@Autowired
	private BaseConverterImpl<HistoryAlatVO, HistoryAlat> historyAlatConverter;
	
	@Autowired
	private BaseConverterImpl<TypeProdukVO, TypeProduk> typeProdukConverter;
	
	@Autowired
	private BaseConverterImpl<RekananVO, Rekanan> rekananConverter;
	
	@Autowired
	private BaseConverterImpl<SatuanStandarVO, SatuanStandar> satuanStandarConverter;
	
	@Autowired
	private BaseConverterImpl<DetailJenisProdukVO, DetailJenisProduk> detailJenisProdukConverter;
	
	@Autowired
	private BaseConverterImpl<JenisProdukVO, JenisProduk> jenisProdukConverter;
	
	@Autowired
	private BaseConverterImpl<MerkProdukVO, MerkProduk> merkProdukConverter;
	
	
	@Autowired
	private RuanganConverter ruanganConverter;
	
	@Autowired
	private HistoryAlatDao historyAlatDao;
	
	@Autowired
	private RuanganDao ruanganDao;
	
	@Autowired
	private BaseConverterImpl<RegistrasiAsetVO, RegistrasiAset> regitrasiAsetConverter;
	
	@Autowired
	private RegistrasiAsetDao registrasiAsetDao;
	
	@Autowired
	private StrukPelayananDetailDao strukPelayananDetailDao;
	
	@Autowired
	private StrukPelayananDetailDaoCustom strukPelayananDetailDaoCustom;

	@Override
	public RegistrasiAsetVO add(RegistrasiAsetVO vo) throws JpaSystemException, ServiceVOException {
		return null;
	}

	@Override
	public RegistrasiAsetVO update(RegistrasiAsetVO vo) throws JpaSystemException, ServiceVOException {
		return null;
	}

	@Override
	public Boolean delete(String key) throws JpaSystemException {
		return null;
	}

	@Override
	public RegistrasiAsetVO findById(String key) throws JpaSystemException {
		return null;
	}

	@Override
	public List<RegistrasiAsetVO> findAll() throws JpaSystemException {
		return null;
	}

	@Override
	public Map<String, Object> findAllWithPageAndLimitAndSortByAndDirectionParameter(Integer page, Integer limit,
			String sort, String dir) {
		return null;
	}
	
	@Transactional(readOnly=false)
	public Map<String, Object> saveDistribusiBarang(DistribusiBarangInvestasiVO vo) {
		ArrayList<String> resultStringArray = new ArrayList<String>();
		for(RegistrasiAsetVO registrasiAsetVO:vo.getRegistrasiAset()){
			RegistrasiAset registrasiAset=registrasiAsetDao.findByNoRec(registrasiAsetVO.getNoRec());
			if(CommonUtil.isNotNullOrEmpty(registrasiAsetVO.getRuangan())){
				registrasiAset.setRuangan(ruanganConverter.transferVOToModel(registrasiAsetVO.getRuangan(), new Ruangan()));
				if(resultStringArray.contains(registrasiAsetVO.getRuangan().getId())){
					
				}
			}
				resultStringArray.add(registrasiAset.getNoRec());
				registrasiAsetDao.save(registrasiAset);
			
		}
		
		Map<String,Object>result=new HashMap<String,Object>();
		result.put("result", resultStringArray);
		return result;
	}

	@Override
	public Map<String, Object> gridListAset(Integer page, Integer limit, String sort, String dir,String periodeAwal,String periodeAhir,Integer ruanganId) {
		int totalRow = strukPelayananDetailDaoCustom.findAsetByRuanganCount(periodeAwal,periodeAhir,ruanganId);
		int totalPages = 0;

		int pageRequested = page;

		if (totalRow > 0) {
			totalPages = (int) Math.ceil((double) totalRow / (double) limit);
		} else {
			totalPages = 0;
		}

		if (pageRequested > totalPages)
			pageRequested = totalPages;
		int rowStart = pageRequested * limit - limit;
		if (rowStart < 0) {
			rowStart = 0;
		}
		int rowEnd = limit;
		Map<String, Object> result=new HashMap<String,Object>();
		result.put("data", strukPelayananDetailDaoCustom.findAsetByRuanganList(rowStart, rowEnd, sort,dir,periodeAwal,periodeAhir,ruanganId));
		result.put("totalPages", totalPages);
		result.put("totalRow", totalRow);
		return result;
		
	}

	@Override
	public Map<String, Object> detailAset(String noRec) {
		Map<String,Object> data=new HashMap<String,Object>();
		data.put("detail", registrasiAsetDao.findByNoRecDetail(noRec));
		data.put("historyAlat", registrasiAsetDao.findHistoryPerbaikan(noRec,getRuanganByUserLogin().getId()));
		data.put("historySertifikat", registrasiAsetDao.historySertifikat(noRec,"History Sertifikat"));
		data.put("manualBook", registrasiAsetDao.historySertifikat(noRec,"Manual Book"));
		data.put("sop", registrasiAsetDao.historySertifikat(noRec,"SOP"));
		return data;
	}
	
	@Override
	public Map<String, Object> getFormatDownload(Integer noRec) {
		Map<String,Object> data=registrasiAsetDao.getFormatDownload(noRec);
		Map<String,Object> data2=new HashMap<String,Object>();
		data2.put("format", data.get("format"));
		data2.put("namaFile",reportDirectory+data.get("namaFile"));
		return data2;
	}

	@Override
	@Transactional(readOnly=false)
	public Map<String, Object> updateAset(RegistrasiAsetVO vo) {
		

		
		RegistrasiAset registrasiAset=registrasiAsetDao.findById(vo.getNoRec());
		String targetFile =null;
		if (CommonUtil.isNotNullOrEmpty(vo.getImage())) {
			try {
				byte[] decodedBytes = Base64.decodeBase64(vo.getImage());
				String fileName = UUID.randomUUID().toString().replaceAll("-", "") + ".jpg";
				targetFile = reportDirectory + fileName;
				writeByteArraysToFile(targetFile, decodedBytes);
				registrasiAset.setImage(fileName);
			} catch (IOException e) {
				System.out.println(e.toString());
			}

		}
		
		if(CommonUtil.isNotNullOrEmpty(vo.getKelompokAset())){
			if(CommonUtil.isNotNullOrEmpty(vo.getKelompokAset().getId())){
				registrasiAset.setKelompokAset(kelompokAsetConverter.transferVOToModel(vo.getKelompokAset(), new KelompokAset()));
			}
		}if(CommonUtil.isNotNullOrEmpty(vo.getTypeProduk())){
			if(CommonUtil.isNotNullOrEmpty(vo.getTypeProduk().getId())){
				registrasiAset.setTypeProduk(typeProdukConverter.transferVOToModel(vo.getTypeProduk(), new TypeProduk()));
			}
		}
		registrasiAset.setNoRegisterAset(vo.getNoRegisterAset());
		if(CommonUtil.isNotNullOrEmpty(vo.getSupplier())){
			if(CommonUtil.isNotNullOrEmpty(vo.getSupplier().getId())){
				registrasiAset.setSupplier(rekananConverter.transferVOToModel(vo.getSupplier(), new Rekanan()));
			}
			
		}
		
		registrasiAset.setUsiaTeknis(vo.getUsiaTeknis());
		if(CommonUtil.isNotNullOrEmpty(vo.getSatuanStandar())){
			if(CommonUtil.isNotNullOrEmpty(vo.getSatuanStandar().getId())){
				registrasiAset.setSatuanStandar(satuanStandarConverter.transferVOToModel(vo.getSatuanStandar(), new SatuanStandar()));
			}
			
		}
		registrasiAset.setNoSeri(vo.getNoSeri());
		registrasiAset.setDayaListrik(vo.getDayaListrik());
		if(CommonUtil.isNotNullOrEmpty(vo.getDetailJenisProduk())){
			if(CommonUtil.isNotNullOrEmpty(vo.getDetailJenisProduk().getId())){
				registrasiAset.setDetailJenisProduk(detailJenisProdukConverter.transferVOToModel(vo.getDetailJenisProduk(), new DetailJenisProduk()));
			}
		}
		if(CommonUtil.isNotNullOrEmpty(vo.getJenisProduk())){
			if(CommonUtil.isNotNullOrEmpty(vo.getJenisProduk().getId())){
				registrasiAset.setJenisProduk(jenisProdukConverter.transferVOToModel(vo.getJenisProduk(), new JenisProduk()));
			}
		}
		registrasiAset.setKlasifikasiTeknologi(vo.getKlasifikasiTeknologi());
		registrasiAset.setKdBmn(vo.getKdBmn());
		registrasiAset.setKeteranganLainnya(vo.getKeteranganLainnya());
		registrasiAset.setKdRsabhk(vo.getKdRsabhk());
		registrasiAset.setUsiaPakai(vo.getUsiaPakai());
		registrasiAset.setSisaUmur(vo.getSisaUmur());
		registrasiAset.setTahunPerolehan(vo.getTahunPerolehan());
		if(CommonUtil.isNotNullOrEmpty(vo.getMerkProduk())){
			if(CommonUtil.isNotNullOrEmpty(vo.getMerkProduk().getId())){
				registrasiAset.setMerkProduk(merkProdukConverter.transferVOToModel(vo.getMerkProduk(), new MerkProduk()));
			}
		}
		registrasiAset.setKdAspac(vo.getKdAspac());
		registrasiAset=registrasiAsetDao.save(registrasiAset);
		Map<String,Object>data=new HashMap<String,Object>();
		data.put("noRec", registrasiAset.getNoRec());
		return data;
	}
	
	public static void writeByteArraysToFile(String fileName, byte[] content) throws IOException {

		File file = new File(fileName);
		BufferedOutputStream writer = new BufferedOutputStream(new FileOutputStream(file));
		writer.write(content);
		writer.flush();
		writer.close();

	}
	
	@Override
	public Map<String, Object> saveDokumen(HistoryAlatVO vo) {
		HistoryAlat historyAlat=historyAlatConverter.transferVOToModel(vo, new HistoryAlat());
		if(CommonUtil.isNotNullOrEmpty(vo.getRegistrasiAset())){
			historyAlat.setRegistrasiAset(registrasiAsetConverter.transferVOToModel(vo.getRegistrasiAset(), new RegistrasiAset()));
		}
		historyAlat.setStatusEnabled(true);
		historyAlat.setKdProfile((short) 0);
		String targetFile =null;
		if (CommonUtil.isNotNullOrEmpty(vo.getNamaFile())) {
			try {
				byte[] decodedBytes = Base64.decodeBase64(vo.getNamaFile());
				String fileName = UUID.randomUUID().toString().replaceAll("-", "") + "."+vo.getFormat();
				targetFile = reportDirectory + fileName;
				writeByteArraysToFile(targetFile, decodedBytes);
				historyAlat.setNamaFile(fileName);
			} catch (IOException e) {
				System.out.println(e.toString());
			}

		}
		historyAlatDao.save(historyAlat);
		Map<String,Object> result=new HashMap<String,Object>();
		result.put("data",historyAlat.getNoRec());
		return result;
	}

	@Override
	public Map<String, Object> daftarDokumen(String noRec, String kategori) {
		Map<String, Object> result=new HashMap<String,Object>();
		result.put("data", registrasiAsetDao.findAsetByRuanganList(noRec,kategori));
		return result;
	}

	@Override
	public Map<String, Object> daftarDokumen(String noRec) {
		Map<String, Object> result=new HashMap<String,Object>();
		result.put("historyAlat", registrasiAsetDao.findAsetByRuanganList(noRec));
		return result;
	}
	
}
