package com.eactive.eai.rms.bap.tansaction.messageProcReq;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.eactive.eai.rms.bap.common.base.BapBaseService;
import com.eactive.eai.rms.bap.manage.comm.property.BapPropertyDao;
import com.eactive.eai.rms.bap.manage.comm.property.BapTelePropertyDao;
import com.eactive.eai.rms.common.acl.user.UserDao;
import com.eactive.eai.rms.common.util.SqlUtil;


@Service("bapMessageReqService")
public class BapMessageReqService extends BapBaseService {

	@Autowired
	@Qualifier("bapMessageReqDao")
	private BapMessageReqDao dao;

	@Autowired
	@Qualifier("bapTelePropertyDao")
	private BapTelePropertyDao telePropDao;
	
	@Autowired
	@Qualifier("bapPropertyDao")
	private BapPropertyDao propDao;
	
	@Autowired
	private UserDao userDao;
	
	public HashMap<String, Object> selectList(int startNum,int endNum, HashMap<String, Object> paramMap) throws Exception {
 
		// 전체 목록수 얻기
		int totalCount = dao.selectListCount(paramMap);

		paramMap.put("startNum" , startNum);// 시작 record
		paramMap.put("endNum"   , endNum);// 끝 record

		List<Map<String, Object>> list = dao.selectList(paramMap);
		HashMap<String, Object> map = new HashMap<String, Object>();

		map.put("totalCount", totalCount);
		map.put("list", list);

		return map;
	}	

	public HashMap<String, Object> selectDetail(HashMap<String, Object> param) throws Exception {

		HashMap<String, Object>   detail        = dao.selectDetail(param);
		String bjobBzwkDstcd = (String)detail.get("BJOBBZWKDSTCD");
		String bjobTranDstcdName = (String)detail.get("BJOBTRANDSTCDNAME");
		param.put("bjobBzwkDstcd", bjobBzwkDstcd );
		param.put("propGroupName", "TelegramInfo{" + bjobBzwkDstcd + "_" + bjobTranDstcdName + "}");
		List<Map<String, Object>> list          = dao.getProps(param);
		HashMap<String, Object> map = new HashMap<String, Object>();
		
		try {
			Map<String, Object> user = userDao.selectDetail(new HashMap<String, Object>() {{
				put("userId", String.valueOf(detail.get("THISMSGREGSNTID")));
			}});
			
			detail.put("BZWKRSEMPNAME", user.get("USERNAME"));
			detail.put("BZWKRSEMPTELNO", user.get("OFCTELNO")); // 사무실 번호
//			detail.put("BZWKRSEMPTELNO", user.get("CPHNNO")); // 휴대폰번호
		} catch (Exception e) {
			logger.error("유저 정보를 불러오기를 실패했습니다.", e);
		}

		map.put("detail", detail);
		map.put("rows", list);

		return map;
	}

	public void update(HashMap<String, Object> paramMap, HashMap<String, Object>[] list, HashMap<String, Object> connList) throws Exception {
		dao.update(paramMap);
		telePropDao.delete(paramMap);
		telePropDao.deleteProperty(paramMap);
		telePropDao.insert(paramMap);
		HashMap<String, Object> prop ;
		for(HashMap<String, Object> map : list){
			String prptyName = (String)map.get("PRPTYNAME");
			String prpty2Val = (String)map.get("PRPTY2VAL");
			if ( !prptyName.equals("") && !prpty2Val.equals("")){
				prop = new HashMap<String, Object>();
				prop.putAll(paramMap);
				prop.put("prptyGroupName",paramMap.get("prptyGroupName"));
				prop.put("prptyName", prptyName);
				prop.put("prpty2Val", prpty2Val);
				telePropDao.insertProperty(prop);
			}
		}
	}

	public String insert(HashMap<String, Object> paramMap, HashMap<String, Object>[] list, HashMap<String, Object> connList) throws Exception {
		
		String bjobMsgDstcd = "";  //inboundErrorInfoDao.generatePK(paramMap);
		paramMap.put( "bjobMsgDstcd", bjobMsgDstcd);
		dao.insert(paramMap);
		telePropDao.delete(paramMap);
		telePropDao.deleteProperty(paramMap);
		telePropDao.insert(paramMap);
		HashMap<String, Object> prop ;
		for(HashMap<String, Object> map : list){
			String prptyName = (String)map.get("PRPTYNAME");
			String prpty2Val = (String)map.get("PRPTY2VAL");
			if ( !prptyName.equals("") && !prpty2Val.equals("")){
				prop = new HashMap<String, Object>();
				prop.putAll(paramMap);
				prop.put("prptyGroupName",paramMap.get("prptyGroupName"));
				prop.put("prptyName", prptyName);
				prop.put("prpty2Val", prpty2Val);
				telePropDao.insertProperty(prop);
			}
		}
		
		return bjobMsgDstcd;
	}

	public void delete(HashMap<String, Object> paramMap) throws Exception {
		dao.delete(paramMap);
		dao.deleteBS01(paramMap);
		telePropDao.delete(paramMap);
		telePropDao.deleteProperty(paramMap);
	}	

	@SuppressWarnings("unchecked")
	public HashMap<String,String> mkInsertSqlForMsgProc(HashMap<String, Object> msgProc) throws Exception {
		
		StringBuffer msgProcInsertSql = new StringBuffer();
		for (String bjobMsgDstcd : msgProc.get("bjobMsgDstcdList").toString().split(",")) {
			HashMap<String, Object> paramDetail = new HashMap<String,Object>();
			paramDetail.put("bjobMsgDstcd", bjobMsgDstcd);
			HashMap<String, Object> msgProcDetail = selectDetail(paramDetail);
			HashMap<String, Object>   detail      = (HashMap<String, Object>)msgProcDetail.get("detail");
			List<Map<String, Object>> propList    = (List<Map<String, Object>>)msgProcDetail.get("rows");
	
			String bjobBzwkDstcd = (String)detail.get("BJOBBZWKDSTCD");
			String bjobTranDstcd = (String)detail.get("BJOBTRANDSTCDNAME");
			detail.put("PRPTYGROUPNAME", "TelegramInfo{" + bjobBzwkDstcd + "_" + bjobTranDstcd + "}");
			
			String[] columnUserId = {"THISMSGREGSNTID","THISMSGAMNDRID"};  // userID 입력컬럼 구분
			String[] columnDateTime = {"THISMSGREGIHMS","THISMSGAMNDHMS"};  // DateTime 입력컬럼 구분
			String userid = msgProc.get("userid") != null ? msgProc.get("userid").toString() : "";
			
			// 시스템대외기관 into BJ06
			List<String> columnArr = new ArrayList<String>();
			String[] columnList = {"BJOBMSGDSTCD","BJOBMSGDSTICNAME","BJOBBZWKDSTCD","BJOBTRANDSTCDNAME","BJOBTELGMHDRSIZE",
									"BJOBTELGMRECSIZE","BJOBTELGMTRAILSIZE","EAIFILESENDUSEYN","EAIFILERECVUSEYN","MSGPRCSSPRITY",
									"UAPPLCD","GROUPCOCD","THISMSGUSEYN","THISMSGREGSNTID","THISMSGREGIHMS","THISMSGAMNDRID",
									"THISMSGAMNDHMS","SNDRCVFILENAME","THISMSGCHRGIDS","RECVNOTIUSEYN","RMTNODENAME",
									"SNDSCRIPTNAME","LOGCRETNYN","BZWKRSEMPNAME","BZWKRSEMPTELNO","OSIDINSTICODE",
									"OSIDINSTIBZWKRSEMPNAME","OSIDINSTITELNO","FILETRANSCOND","FILETRANSSCHE","FILETRANSALAM"};
			columnArr = Arrays.asList(columnList);
			msgProcInsertSql.append("INSERT INTO EAIPKG.TSEAIBJ01 (");
			
			// 필드명 입력
			for (String column : columnArr) {
				msgProcInsertSql.append((column.equals(columnArr.get(columnArr.size()-1))) ? column : column+",");
			}
			msgProcInsertSql.append(") VALUES (");
			// 필드값 입력
			String[] columnInt = {"BJOBTELGMHDRSIZE","BJOBTELGMRECSIZE","BJOBTELGMTRAILSIZE","MSGPRCSSPRITY"};  // Integer 컬럼 구분
			for (String column : columnArr) {
				if (column.equals(columnArr.get(columnArr.size()-1))) {
					if (Arrays.asList(columnInt).contains(column)) {
						msgProcInsertSql.append((detail.containsKey(column) ? detail.get(column) : 0)+");\n");
					} else {
						if (Arrays.asList(columnUserId).contains(column)) {
							msgProcInsertSql.append("'"+userid+"');\n");
						} else if (Arrays.asList(columnDateTime).contains(column)) {
							msgProcInsertSql.append("TO_CHAR(LOCALTIMESTAMP, 'YYYYMMDDHH24MISSFF3'));\n");
						} else {
							msgProcInsertSql.append("'"+(detail.get(column) != null ? detail.get(column) : "")+"');\n");
						}
					}
				} else {
					if (Arrays.asList(columnInt).contains(column)) {
						msgProcInsertSql.append((detail.containsKey(column) ? detail.get(column) : 0)+",");
					} else {
						if (Arrays.asList(columnUserId).contains(column)) {
							msgProcInsertSql.append("'"+userid+"',");
						} else if (Arrays.asList(columnDateTime).contains(column)) {
							msgProcInsertSql.append("TO_CHAR(LOCALTIMESTAMP, 'YYYYMMDDHH24MISSFF3'),");
						} else {
							if (column.equals("EAIFILESENDUSEYN")) column = "FILESENDUSEYN";
							if (column.equals("EAIFILERECVUSEYN")) column = "FILERECVUSEYN";
							msgProcInsertSql.append("'"+(detail.get(column) != null ? detail.get(column) : "")+"',");
						}
					}
				}
			}
	
			// TELEGRAM PROP GROUP into BA05 (공통코드에서 별도로 입력됨)
			List<String> columnPropGrpArr = new ArrayList<String>();
			String[] columnPropGrpList = {"PRPTYGROUPNAME","PRPTYGROUPDESC"};
			columnPropGrpArr = Arrays.asList(columnPropGrpList);
			msgProcInsertSql.append("INSERT INTO EAIPKG.TSEAIBA05 (");
			
			// 필드명 입력
			for (String column : columnPropGrpArr) {
				msgProcInsertSql.append((column.equals(columnPropGrpArr.get(columnPropGrpArr.size()-1))) ? column : column+",");
			}
			msgProcInsertSql.append(") VALUES (");
			// 필드값 입력
			for (String column : columnPropGrpArr) {
				if (column.equals(columnPropGrpArr.get(columnPropGrpArr.size()-1))) {
					msgProcInsertSql.append("'"+(detail.get(column) != null ? detail.get(column) : "")+"');\n");
				} else {
					msgProcInsertSql.append("'"+(detail.get(column) != null ? detail.get(column) : "")+"',");
				}
			}
			
			// TELEGRAM PROP LIST into BA06 (프로퍼티명과 프로퍼티설명은 업무구분에서 별도로 입력되고, 프로퍼티값만 여기서 업데이트됨)
			for (Map<String, Object> prop : propList) {
				List<String> columnPropArr = new ArrayList<String>();
				String[] columnPropList = {"PRPTYGROUPNAME","PRPTYNAME","PRPTY2VAL"};
				columnPropArr = Arrays.asList(columnPropList);
				msgProcInsertSql.append("INSERT INTO EAIPKG.TSEAIBA06 (");
				
				// 필드명 입력
				for (String column : columnPropArr) {
					msgProcInsertSql.append((column.equals(columnPropArr.get(columnPropArr.size()-1))) ? column : column+",");
				}
				msgProcInsertSql.append(") VALUES (");
				// 필드값 입력
				for (String column : columnPropArr) {
					if (column.equals("PRPTYGROUPNAME")) {
						msgProcInsertSql.append("'"+detail.get("PRPTYGROUPNAME")+"',");
					} else if (column.equals(columnPropArr.get(columnPropArr.size()-1))) {
						msgProcInsertSql.append("'"+(prop.get(column) != null ? prop.get(column) : "")+"');\n");
					} else {
						msgProcInsertSql.append("'"+(prop.get(column) != null ? prop.get(column) : "")+"',");
					}
				}
			}
		}
		
		HashMap<String,String> retMap = new HashMap<String,String>(); 
		if (msgProc.get("fileName") != null) {
			OutputStream output = null;
			try {
				String sqlDownloadPath = getProperties("SQL_DOWNLOAD", "DOWNLOAD_PATH");
				String sqlDownloadFile = sqlDownloadPath+msgProc.get("fileName");
				output = new FileOutputStream(sqlDownloadFile);
				if (sqlDownloadPath != null) {
					byte[] bt = msgProcInsertSql.toString().getBytes();
					output.write(bt);
					output.close();
				}
				retMap.put("path", sqlDownloadPath);
			} catch (Exception e) {
				logger.error( e.getMessage(), e);
			} finally {
				if(output != null) try { output.close(); } catch(Exception ee) {logger.error( ee.getMessage(), ee);}
			}
		} else {
			retMap = SqlUtil.executeSql(msgProcInsertSql.toString(), "BAP_"+msgProc.get("svrType").toString().toUpperCase());
		}
		
		return retMap;
	}
	
	public HashMap<String, Object> getProps(String bjobBzwkDstcd, String propGroupName) throws Exception {

		HashMap<String, Object> param = new HashMap<String, Object>();
		param.put("bjobBzwkDstcd", bjobBzwkDstcd);
		param.put("propGroupName", propGroupName);		

		List<Map<String, Object>> list          = dao.getProps(param);
		HashMap<String, Object> map = new HashMap<String, Object>();

		map.put("rows", list);

		return map;
	}

	private String getProperties(String propGroup, String propName) throws Exception {
		HashMap<String,Object> params = new HashMap<String,Object>();
		params.put("prptyGroupName", propGroup);
		params.put("prptyName", propName);
		
		HashMap<String, Object> props = propDao.getProperties(params);
		
		return props.get("PRPTY2VAL").toString();
	}
}