package com.eactive.eai.rms.bap.manage.message.messageMeta;

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.common.util.SqlUtil;

@Service("bapMessageMetaService")
public class BapMessageMetaService extends BapBaseService {

	@Autowired
	@Qualifier("bapMessageMetaDao")
	private BapMessageMetaDao dao;

	@Autowired
	@Qualifier("bapPropertyDao")
	private BapPropertyDao propDao;

	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 int selectTotalCount(HashMap<String, Object> paramMap) throws Exception {

		return dao.selectListCount(paramMap); 		// 전체 목록수 얻기
	}
	
	public HashMap<String, Object> selectDetail(String msgMetaDstcd) throws Exception {

		HashMap<String, Object>   detail = dao.selectDetail(msgMetaDstcd);
		List<Map<String, Object>> list   = dao.msgList(msgMetaDstcd);		

		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("detail", detail);
		map.put("list", list);
		
		return map;

	}	

	public void update(HashMap<String, Object> paramMap, HashMap<String, Object>[] list )throws Exception {
		dao.update(paramMap);
		dao.deleteList(paramMap);
		HashMap<String, Object> data ;
		for(HashMap<String, Object> map : list){
			data = new HashMap<String, Object>();
			data.putAll(paramMap);
			data.put("msgClmnSeq",map.get("MSGCLMNSEQ"));
			data.put("msgItemDsticName",map.get("MSGITEMDSTICNAME"));
			dao.insertList(data);
		}		
	}

	public void insert(HashMap<String, Object> paramMap, HashMap<String, Object>[] list) throws Exception {
		
		dao.insert(paramMap);
		HashMap<String, Object> data ;
		
		for(HashMap<String, Object> map : list){
			data = new HashMap<String, Object>();
			data.putAll(paramMap);
			data.put("msgClmnSeq",map.get("MSGCLMNSEQ"));
			data.put("msgItemDsticName",map.get("MSGITEMDSTICNAME"));
			dao.insertList(data);
		}		
	}

	public void delete(HashMap<String, Object> paramMap) throws Exception {
		dao.delete(paramMap);
		dao.deleteList(paramMap);
	}	
	
	@SuppressWarnings("unchecked")
	public HashMap<String,String> mkInserSqlForMsgMeta(HashMap<String, Object> msgMetaMap) throws Exception {
		
		StringBuffer msgMetaInsertSql = new StringBuffer();
		String[] columnUserId = {"THISMSGREGSNTID","THISMSGAMNDRID","THISMSGCLMNREGSNTID","THISMSGCLMNAMNDRID"};  // userID 입력컬럼 구분
		String[] columnDateTime = {"THISMSGREGIHMS","THISMSGAMNDHMS","THISMSGCLMNREGIHMS","THISMSGCLMNAMNDHMS"};  // DateTime 입력컬럼 구분
		List<Map<String, Object>> msgMetaList = (List<Map<String, Object>>)msgMetaMap.get("list");
		String userid = msgMetaMap.containsKey("userid") ? msgMetaMap.get("userid").toString() : "";
		
		for (Map<String,Object> meta : msgMetaList) {
			// MESSAGE META LIST into BM03
			List<String> columnArr = new ArrayList<String>();
			String[] columnList = {"MSGMETADSTCD","MSGDESC","THISMSGUSEYN","THISMSGREGSNTID","THISMSGREGIHMS","THISMSGAMNDRID","THISMSGAMNDHMS"};
			columnArr = Arrays.asList(columnList);
			msgMetaInsertSql.append("INSERT INTO EAIPKG.TSEAIBM03 (");
			
			// 필드명 입력
			for (String column : columnArr) {
				msgMetaInsertSql.append((column.equals(columnArr.get(columnArr.size()-1))) ? column : column+",");
			}
			msgMetaInsertSql.append(") VALUES (");
			// 필드값 입력
			for (String column : columnArr) {
				if (column.equals(columnArr.get(columnArr.size()-1))) {
					if (Arrays.asList(columnUserId).contains(column)) {
						msgMetaInsertSql.append("'"+userid+"');\n");
					} else if (Arrays.asList(columnDateTime).contains(column)) {
						msgMetaInsertSql.append("TO_CHAR(LOCALTIMESTAMP, 'YYYYMMDDHH24MISSFF3'));\n");
					} else {
						msgMetaInsertSql.append("'"+(meta.containsKey(column) ? meta.get(column) : "")+"');\n");
					}
				} else {
					if (Arrays.asList(columnUserId).contains(column)) {
						msgMetaInsertSql.append("'"+userid+"',");
					} else if (Arrays.asList(columnDateTime).contains(column)) {
						msgMetaInsertSql.append("TO_CHAR(LOCALTIMESTAMP, 'YYYYMMDDHH24MISSFF3'),");
					} else {
						msgMetaInsertSql.append("'"+(meta.containsKey(column) ? meta.get(column) : "")+"',");
					}
				}
			}

			HashMap<String, Object> metaMap = selectDetail(meta.get("MSGMETADSTCD").toString());
			List<Map<String, Object>> metaItemList = (List<Map<String, Object>>)metaMap.get("list");

			// MESSAGE META LIST into BM02
			for (Map<String, Object> metaItem : metaItemList) {
				List<String> columnItemArr = new ArrayList<String>();
				String[] columnItemList = {"MSGMETADSTCD","MSGCLMNSEQ","MSGITEMDSTICNAME","THISMSGCLMNUSEYN","THISMSGREGSNTID","THISMSGREGIHMS","THISMSGAMNDRID","THISMSGAMNDHMS"};
				columnItemArr = Arrays.asList(columnItemList);
				msgMetaInsertSql.append("INSERT INTO EAIPKG.TSEAIBM02 (MSGGROUPDSTCD,");
				
				// 필드명 입력
				for (String columnItem : columnItemArr) {
					if (columnItem.equals("MSGMETADSTCD")) continue;
					msgMetaInsertSql.append((columnItem.equals(columnItemArr.get(columnItemArr.size()-1))) ? columnItem : columnItem+",");
				}
				msgMetaInsertSql.append(") VALUES (");
				// 필드값 입력
				for (String column : columnItemArr) {
					if (column.equals(columnItemArr.get(columnItemArr.size()-1))) {
						if (Arrays.asList(columnUserId).contains(column)) {
							msgMetaInsertSql.append("'"+userid+"');\n");
						} else if (Arrays.asList(columnDateTime).contains(column)) {
							msgMetaInsertSql.append("TO_CHAR(LOCALTIMESTAMP, 'YYYYMMDDHH24MISSFF3'));\n");
						} else {
							msgMetaInsertSql.append("'"+(metaItem.containsKey(column) ? metaItem.get(column) : "")+"');\n");
						}
					} else {
						if (Arrays.asList(columnUserId).contains(column)) {
							msgMetaInsertSql.append("'"+userid+"',");
						} else if (Arrays.asList(columnDateTime).contains(column)) {
							msgMetaInsertSql.append("TO_CHAR(LOCALTIMESTAMP, 'YYYYMMDDHH24MISSFF3'),");
						} else {
							msgMetaInsertSql.append("'"+(metaItem.containsKey(column) ? metaItem.get(column) : "")+"',");
						}
					}
				}
			}
			
			// MESSAGE META LIST into BM01
			for (Map<String, Object> metaItem : metaItemList) {	
				List<String> columnClmArr = new ArrayList<String>();
				String[] columnClmList = {"MSGITEMDSTICNAME","THISMSGCLMNUSEYN","MSGCLMNNAME","MSGCLMNATTRIPTRNCD","MSGCLMNVAL","THISMSGCLMNREGSNTID","THISMSGCLMNREGIHMS","THISMSGCLMNAMNDRID","THISMSGCLMNAMNDHMS"};
				columnClmArr = Arrays.asList(columnClmList);
				
				msgMetaInsertSql.append("MERGE INTO EAIPKG.TSEAIBM01 r USING (VALUES(");
				// 필드값 입력
				for (String column : columnClmArr) {
					if (column.equals(columnClmArr.get(columnClmArr.size()-1))) {
						if (Arrays.asList(columnUserId).contains(column)) {
							msgMetaInsertSql.append("'"+userid+"')) ");
						} else if (Arrays.asList(columnDateTime).contains(column)) {
							msgMetaInsertSql.append("TO_CHAR(LOCALTIMESTAMP, 'YYYYMMDDHH24MISSFF3'))) ");
						} else {
							msgMetaInsertSql.append("'"+(metaItem.containsKey(column) ? metaItem.get(column) : "")+"')) ");
						}
					} else {
						if (Arrays.asList(columnUserId).contains(column)) {
							msgMetaInsertSql.append("'"+userid+"',");
						} else if (Arrays.asList(columnDateTime).contains(column)) {
							msgMetaInsertSql.append("TO_CHAR(LOCALTIMESTAMP, 'YYYYMMDDHH24MISSFF3'),");
						} else {
							msgMetaInsertSql.append("'"+(metaItem.containsKey(column) ? metaItem.get(column) : "")+"',");
						}
					}
				}
				// 필드명 입력
				msgMetaInsertSql.append("AS s(");
				for (String columnClm : columnClmArr) {
					msgMetaInsertSql.append((columnClm.equals(columnClmArr.get(columnClmArr.size()-1))) ? columnClm+")\n" : columnClm+",");
				}
				msgMetaInsertSql.append("ON r.MSGITEMDSTICNAME = s.MSGITEMDSTICNAME WHEN NOT MATCHED THEN\n");
				msgMetaInsertSql.append("INSERT (");
				for (String columnClm : columnClmArr) {
					msgMetaInsertSql.append((columnClm.equals(columnClmArr.get(columnClmArr.size()-1))) ? "r."+columnClm : "r."+columnClm+",");
				}
				msgMetaInsertSql.append(") VALUES (");
				for (String columnClm : columnClmArr) {
					msgMetaInsertSql.append((columnClm.equals(columnClmArr.get(columnClmArr.size()-1))) ? "s."+columnClm+");\n" : "s."+columnClm+",");
				}
			}
		}

		HashMap<String,String> retMap = new HashMap<String,String>(); 
		if (msgMetaMap.get("fileName") != null) {
			OutputStream output = null;
			try {
				String sqlDownloadPath = getProperties("SQL_DOWNLOAD", "DOWNLOAD_PATH");
				String sqlDownloadFile = sqlDownloadPath+msgMetaMap.get("fileName");
				output = new FileOutputStream(sqlDownloadFile);
				if (sqlDownloadPath != null) {
					byte[] bt = msgMetaInsertSql.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(msgMetaInsertSql.toString(), "BAP_"+msgMetaMap.get("svrType").toString().toUpperCase());
		}
		
		return retMap;
	}
	
	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();
	}
}