package com.eactive.eai.rms.onl.manage.serviceinfo.b2bextractor;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.eactive.eai.common.dao.DAOException;
import com.eactive.eai.common.dao.DAOFactory;
import com.eactive.eai.common.property.PropGroupVO;
import com.eactive.eai.common.property.PropertyDAO;
import com.eactive.eai.common.util.StringUtil;
import com.eactive.eai.common.util.SystemUtil;
import com.eactive.eai.data.entity.onl.b2bextractor.B2BExtract;
import com.eactive.eai.data.entity.onl.b2bextractor.B2BExtractId;
import com.eactive.eai.rms.common.base.BaseService;
import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
import com.eactive.eai.rms.common.datasource.DataSourceType;
import com.eactive.eai.rms.data.entity.onl.b2bextract.B2bExtractService;
import com.eactive.eai.rms.data.entity.onl.eaimsg.EAIMessageService;
import com.eactive.eai.rms.onl.common.exception.BizException;
import com.eactive.eai.rms.onl.common.exception.EMSRuntimeException;
import com.eactive.eai.rms.onl.common.util.FileWriteUtil;
import com.eactive.eai.rms.onl.loader.service.TransactionLoaderService;
import com.eactive.eai.rms.onl.manage.rule.transform.TransformDao;
import com.eactive.eai.rms.onl.manage.serviceinfo.eaimsg.EaiMsgCmFtpService;

@Service
@Transactional
public class B2bExtractorManService extends BaseService {

	@Autowired
	@Qualifier("transformDao")
	private TransformDao transformDao;

	@Autowired
	@Qualifier("monitoringContext")
	private MonitoringContext monitoringContext;

	@Autowired
	private EaiMsgCmFtpService eaiMsgCmFtpService;

	@Autowired
	private TransactionLoaderService loaderService;

	@Autowired
	private B2bExtractService b2bExtractService;

	@Autowired
	private EAIMessageService eaiMessageService;

	@Autowired
	private B2bExtractorUIMapper b2bExtractorUIMapper;

	public Page<B2bExtractorUI> selectList(Pageable pageable, String searchEaiSvcName) {
		Page<B2BExtract> page = b2bExtractService.findAll(pageable, searchEaiSvcName);
		return page.map(b2bExtractorUIMapper::toVo);
	}

	public List<Map<String, Object>> selectListToExcel(String searchEaiSvcName) {
		return StreamSupport.stream(b2bExtractService.findAll(searchEaiSvcName).spliterator(), false).map(b -> {
			Map<String, Object> map = new HashMap<>();
			map.put("EAISVCNAME", b.getId().getEaisvcname());
			map.put("SVCPRCSSNO", b.getId().getSvcprcssno());
			map.put("SVCROUTCLSNAME", b.getSvcroutclsname());
			map.put("ADPTRROUTCLSNAME", b.getAdptrroutclsname());
			return map;
		}).collect(Collectors.toList());
	}

	public B2bExtractorUI selectDetail(String eaiSvcName, Integer svcPrcssNo) {
		B2BExtract b2bExtract = b2bExtractService.getById(new B2BExtractId(eaiSvcName, svcPrcssNo));
		B2bExtractorUI b2bExtractorUI = b2bExtractorUIMapper.toVo(b2bExtract);

		String eaiSvcDesc = eaiMessageService.getById(eaiSvcName).getEaisvcdesc();
		b2bExtractorUI.setEaiSvcDesc(eaiSvcDesc);
		return b2bExtractorUI;
	}

	public void update(B2bExtractorUI b2bExtractorUI) {

		B2BExtract b2bExtract = b2bExtractService
				.getById(new B2BExtractId(b2bExtractorUI.getEaiSvcName(), b2bExtractorUI.getSvcPrcssNo()));

		b2bExtractorUIMapper.updateEntity(b2bExtractorUI, b2bExtract);
		b2bExtractService.save(b2bExtract);
	}

	public void insert(B2bExtractorUI b2bExtractorUI) {
		B2BExtract b2bExtract = b2bExtractorUIMapper.toEntity(b2bExtractorUI);
		b2bExtractService.save(b2bExtract);
	}

	public void delete(String eaiSvcName, Integer svcPrcssNo) {
		b2bExtractService.deleteById(new B2BExtractId(eaiSvcName, svcPrcssNo));
	}

	public boolean migrationToProdB2BExtractor(String userId, String listSvcName, String cmDate, String cmTime,
			String sysCode) throws BizException, DAOException {
		boolean ret = false;

		if (!SystemUtil.isDevServer() && !SystemUtil.isStagingServer()) {
			throw new EMSRuntimeException("해당 시스템에선 사용할 수 없습니다.");
		}
		PropertyDAO propertyDAO = (PropertyDAO) DAOFactory.newInstance().create(PropertyDAO.class);
		PropGroupVO prop = propertyDAO.getProperties("CM_CONFIG");
		if (prop == null) {
			throw new EMSRuntimeException("프라퍼티 정보가 없습니다. - CM_CONFIG");
		}

		boolean isDebug = logger.isDebugEnabled();
		String txtLocalPath = prop.getProperty("eaimsg.sql.path");
		String schemaId = (SystemUtil.isDevServer() ? prop.getProperty("eaimsg.sql.test.schemaId")
				: prop.getProperty("eaimsg.sql.prod.schemaId"));
		String[] eaiSvcListAll = listSvcName.split("\\&");

		StringBuilder sb = new StringBuilder();
		for (String eaiSvcName : eaiSvcListAll) {
			if (isDebug) {
				logger.debug("Start B2B 라우팅 서비스  migration To Prod (eaiSvcName=" + eaiSvcName + ")");
			}

			HashMap<String, String> paramMap = new HashMap<>();
			paramMap.put("eaiSvcName", eaiSvcName);
			List<HashMap> list1 = transformDao.selectFR06ForMigration(paramMap);

			if (isDebug) {
				if (list1 == null) {
					logger.debug("list1 is null !");
					list1 = Collections.<HashMap>emptyList();
				} else {
					logger.debug("list1 returned count is : " + list1.size());
				}
			}

			for (int j = 0; j < list1.size(); j++) {
				HashMap map = list1.get(j);
				// DELETE
				if (j == 0) {
					sb.append(String.format(B2bExtractorMigQuery.MIG_DEL_FR06, schemaId, eaiSvcName)).append("\n");
				}
				// INSERT
				sb
						.append(String
								.format(B2bExtractorMigQuery.MIG_INS_FR06, schemaId, eaiSvcName, map.get("SVCPRCSSNO"),
										StringUtil.getNullStr(map.get("SVCROUTCLSNAME")),
										StringUtil.getNullStr(map.get("ADPTRROUTCLSNAME")),
										StringUtil.getNullStr(map.get("EAISEVRDSTCD")),
										StringUtil.getNullStr(map.get("MODFIMGTSTUSDSTCD")),
										StringUtil.getNullStr(map.get("EAILASTAMNDYMS")))
								.replaceAll("' '", "''"))
						.append("\n");
			}
		}

		String txtLocalFullPath = txtLocalPath + cmDate + cmTime + "_" + userId + "_" + sysCode + "_SQL";
		BufferedWriter bw = null;
		try {
			File dir = new File(txtLocalPath);
			dir.mkdirs();

			bw = new BufferedWriter(new FileWriter(txtLocalFullPath, true));
			bw.write(sb.toString());
			bw.close();
			ret = true;
		} catch (SecurityException se) {
			logger.error("ERROR: " + se.toString());
			ret = false;
		} catch (IOException ie) {
			logger.error("ERROR: " + ie.toString());
			ret = false;
		} finally {
			if (bw != null)
				try {
					bw.close();
				} catch (Exception ee) {
					logger.error("bw close error");
				}
		}

		return ret;
	}

	public void extractB2BExt(String userId, String listSvcName, String cmDate, String cmTime, String serviceType)
			throws Exception {

		if (SystemUtil.isProdServer()) {
			throw new BizException("해당 시스템에선 사용할 수 없습니다.");
		}

		if (StringUtils.isBlank(serviceType)) {
			throw new BizException("serviceType is null");
		}

		String localPath = monitoringContext
				.getProperty(MonitoringContext.CM_AFTER_PATH, "/dat/eaiData/engineData/after/");
		String[] eaiSvcNames = listSvcName.split("\\&");

		DataSourceType dt = DataSourceContextHolder.getDataSourceType();
		String folderName = cmDate + cmTime + "_" + userId + "_" + serviceType + "_TXT";
		String path = localPath + folderName + File.separator + FileWriteUtil.B2B_EXT + File.separator;

		try {
			for (String eaiSvcName : eaiSvcNames) {
				loaderService.b2bExtDownLoading(dt, path, eaiSvcName);
			}
			eaiMsgCmFtpService.ftpUploadForStage(folderName, FileWriteUtil.B2B_EXT, eaiSvcNames);
		} catch (Exception e) {
			logger.error("ERROR: " + e.toString());
			// 스테이징에 복사가 안되었을 경우 after에 생성된 폴더 삭제
			eaiMsgCmFtpService.deleteFolder(folderName);
			throw e;
		}

	}
}
