package com.eactive.eai.rms.onl.manage.rule.transform2;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.eactive.eai.rms.common.util.PoiUtils;
import com.eactive.eai.rms.onl.manage.rule.transform2.mapper.TransformItemUIMapper;
import com.eactive.eai.rms.onl.manage.rule.transform2.ui.TransformItemUI;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
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.data.entity.onl.message.EAIMessageEntity;
import com.eactive.eai.data.entity.onl.message.ServiceMessageEntity;
import com.eactive.eai.data.entity.onl.transformer.layout.LayoutEntity;
import com.eactive.eai.data.entity.onl.transformer.layout.LayoutItemEntity;
import com.eactive.eai.data.entity.onl.transformer.transform.TransformEntity;
import com.eactive.eai.data.entity.onl.transformer.transform.TransformItemEntity;
import com.eactive.eai.data.entity.onl.transformer.transform.TransformTypeEntity;
import com.eactive.eai.data.entity.onl.transformer.transform.TransformTypeEntityId;
import com.eactive.eai.rms.common.acl.user.BizDao;
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.common.util.CommonUtil;
import com.eactive.eai.rms.data.entity.onl.eaimsg.EAIMessageService;
import com.eactive.eai.rms.data.entity.onl.layout.LayoutService;
import com.eactive.eai.rms.data.entity.onl.transform.TransformService;
import com.eactive.eai.rms.data.entity.onl.transform.TransformTypeService;
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.layout.mapper.LayoutItemUIMapper;
import com.eactive.eai.rms.onl.manage.rule.layout.ui.LayoutItemUI;
import com.eactive.eai.rms.onl.manage.rule.transform.TransformDao;
import com.eactive.eai.rms.onl.manage.rule.transform2.mapper.TransformUIMapper;
import com.eactive.eai.rms.onl.manage.rule.transform2.ui.TransformSourceResultUI;
import com.eactive.eai.rms.onl.manage.rule.transform2.ui.TransformUI;
import com.eactive.eai.rms.onl.manage.rule.upload.IoMapLoaderKey;
import com.eactive.eai.rms.onl.manage.rule.upload.IoMapLoaderService;

import edu.emory.mathcs.backport.java.util.Arrays;

@Service
@Transactional
public class Transform2Service extends BaseService {

	/** The monitoring context. */
	@Autowired
	private MonitoringContext monitoringContext;

	@Autowired
	private TransformDao transformDao;

	@Autowired
	private BizDao bizDao;

	@Autowired
	private TransactionLoaderService loaderService;

	@Autowired
	private IoMapLoaderService ioMapLoaderService;

	@Autowired
	private LayoutService layoutService;

	@Autowired
	private LayoutItemUIMapper layoutItemUIMapper;

	@Autowired
	private TransformService transformService;

	@Autowired
	private EAIMessageService eaiMessageService;

	@Autowired
	TransformItemUIMapper transformItemUIMapper;

	public Page<TransformUI> selectList(Pageable pageable, String searchCnvsnName, String searchCnvsnDesc,
			String searchBizCode, String searchIfSvcCd) {
		return transformService
				.findAll(pageable, searchCnvsnName, searchCnvsnDesc, searchBizCode, searchIfSvcCd)
				.map(transformEaiMessage -> {
					TransformUI transformUI = new TransformUI();

					TransformEntity transformEntity = transformEaiMessage.getTransformEntity();

					transformUI.setEaiBzwkDstcd(transformEaiMessage.getEaiBzwkDstcd());
					transformUI.setCnvsnName(transformEntity.getCnvsnname());
					transformUI.setEaiSvcName(transformEaiMessage.getEaiSvcName());
					transformUI.setEaiSvcDesc(transformEaiMessage.getEaiSvcDesc());
					transformUI.setEaiSevrDStcd(transformEntity.getEaisevrdstcd());
					transformUI.setUseYn(transformEntity.getUseyn());
					transformUI.setLastamndhms(transformEntity.getLastamndhms());
					transformUI.setVerInfo(transformEntity.getVerinfo());
					transformUI.setCnvsnType(StringUtils.substringAfterLast(transformUI.getCnvsnName(), "_"));
					String flag = StringUtils.isNotBlank(transformEaiMessage.getEaiBzwkDstcd()) ? "O" : "X";
					transformUI.setFlag(flag);
					transformUI.setCnvsnDesc(transformEntity.getCnvsndesc());
					return transformUI;
				});
	}

	public List<LayoutItemUI> selectLayoutItems(String loutName) {
		List<LayoutItemEntity> layoutItemEntities = layoutService.getById(loutName).getLayoutItemEntities();
		return layoutItemUIMapper.map(layoutItemEntities);
	}

	public List<LayoutItemUI> selectTransformItems(String cnvsnName, String loutName, String srcLayoutName) {

		TransformEntity transformEntity = transformService.getById(cnvsnName);
		LayoutEntity layoutEntity = layoutService.getById(loutName);

		Optional<TransformTypeEntity> transformTypeEntitOptional = transformEntity
				.getTransformTypeEntities()
				.stream()
				.filter(transformType -> transformType.getId().getSourcrsultdstcd().equalsIgnoreCase("TGT_LAYOUT"))
				.findFirst();

		List<LayoutItemUI> layoutItemUIs = layoutItemUIMapper.map(layoutEntity.getLayoutItemEntities());

		if (!transformTypeEntitOptional.isPresent()) {
			return layoutItemUIs;
		}

		List<TransformItemEntity> transformItemEntities = transformEntity.getTransformItemEntities();

		Map<String, LayoutItemUI> layoutItemPathMap = layoutItemUIs
				.parallelStream()
				.collect(Collectors.toMap(ui -> ui.getLoutitempath(), ui -> ui));

		transformItemEntities.forEach(t -> {
			String loutItemPath = CommonUtil.removeArrayTag(t.getId().getCnvsnrsultitempathname());
			if (layoutItemPathMap.containsKey(loutItemPath)) {
				LayoutItemUI loutItemUI = layoutItemPathMap.get(loutItemPath);

				loutItemUI.setCnvsnName(t.getId().getCnvsnname());
				loutItemUI.setCnvsnRsultItemPathName(t.getId().getCnvsnrsultitempathname());
				loutItemUI.setCnvsnCmdName(t.getCnvsncmdname());
				loutItemUI.setCnvsnSrcItems(genConversionSourceItems(srcLayoutName, t.getCnvsncmdname()));
				loutItemUI.setCnvsnItemBascVal(t.getCnvsnitembascval());
				loutItemUI.setCnvsnItemSerNo(t.getCnvsnitemserno());
			}
		});

		return layoutItemUIs;

	}

	private String genConversionSourceItems(String srcLayoutName, String cnvsncmdname) {

	    // \uAC00-\uD7A3 : 한글 전체 ('가' ~ '힣')
	    Pattern pattern = Pattern.compile(srcLayoutName + "[\\w\\.\\[\\]\\*\\-:\\uAC00-\\uD7A3]*");
		Matcher matcher = pattern.matcher(cnvsncmdname);

		StringBuilder result = new StringBuilder();

		while (matcher.find()) {
			result.append(matcher.group());
			result.append(",");
		}

		if (result.length() == 0) {
			return "";
		}

		return result.toString().replaceAll(".$", "");
	}

	public List<TransformSourceResultUI> selectTransformSourceResult(String cnvsnName) {
		List<TransformSourceResultUI> transSourceResultUIs = new ArrayList<>();
		Optional<TransformEntity> o = transformService.findById(cnvsnName);
		if (!o.isPresent()) {
			return transSourceResultUIs;
		}

		List<TransformTypeEntity> transformTypeEntities = o.get().getTransformTypeEntities();

		for (TransformTypeEntity transformTypeEntity : transformTypeEntities) {

			LayoutEntity layoutEntity = layoutService
					.findById(transformTypeEntity.getId().getLoutname())
					.orElse(new LayoutEntity());

			TransformSourceResultUI transformSourceResultUI = new TransformSourceResultUI();
			transformSourceResultUI.setCnvsnName(transformTypeEntity.getId().getCnvsnname());
			transformSourceResultUI.setEaiSevrDstcd(layoutEntity.getEaisevrdstcd());
			transformSourceResultUI.setLoutDesc(layoutEntity.getLoutdesc());
			transformSourceResultUI.setLoutName(transformTypeEntity.getId().getLoutname());
			transformSourceResultUI.setLoutPtrnName(layoutEntity.getLoutptrnname());
			transformSourceResultUI.setSourcRsultDstcd(transformTypeEntity.getId().getSourcrsultdstcd());

			transSourceResultUIs.add(transformSourceResultUI);
		}

		return transSourceResultUIs;
	}

	public void insert(TransformUI transformUI) {
		if (transformService.existsById(transformUI.getCnvsnName())) {
			throw new EMSRuntimeException("이미 존재하는 변환 매핑코드 입니다. - " + transformUI.getCnvsnName());
		}
		updateTransfromEaiSvcName(transformUI.getEaiSvcName(), transformUI.getCnvsnType(), "1",
				transformUI.getCnvsnName());
		TransformEntity transformEntity = transformUIMapper.toEntity(transformUI);
		transformService.save(transformEntity);
	}

	@Autowired
	private TransformUIMapper transformUIMapper;

	@Autowired
	private TransformTypeService transformTypeService;

	public void transaction(TransformUI transformUI) {
		TransformEntity transformEntity = transformService.getById(transformUI.getCnvsnName());
		transformUIMapper.updateEntity(transformUI, transformEntity);

		transformEntity.getTransformTypeEntities().clear();

		TransformTypeEntityId srcTransformTypeEntityId = new TransformTypeEntityId(transformUI.getCnvsnName(),
				transformUI.getSrcLayoutName(), "SRC_LAYOUT");

		TransformTypeEntity srcTransformTypeEntity = transformTypeService
				.findById(srcTransformTypeEntityId)
				.orElseGet(() -> {
					TransformTypeEntity transformTypeEntity = new TransformTypeEntity();
					transformTypeEntity.setId(srcTransformTypeEntityId);
					transformTypeEntity.setTransformEntity(transformEntity);
					return transformTypeEntity;
				});
		transformEntity.getTransformTypeEntities().add(srcTransformTypeEntity);

		TransformTypeEntityId tgtTransformTypeEntityId = new TransformTypeEntityId(transformUI.getCnvsnName(),
				transformUI.getTgtLayoutName(), "TGT_LAYOUT");
		TransformTypeEntity tgtTransformTypeEntity = transformTypeService
				.findById(tgtTransformTypeEntityId)
				.orElseGet(() -> {
					TransformTypeEntity transformTypeEntity = new TransformTypeEntity();
					transformTypeEntity.setId(tgtTransformTypeEntityId);
					transformTypeEntity.setTransformEntity(transformEntity);
					return transformTypeEntity;
				});
		transformEntity.getTransformTypeEntities().add(tgtTransformTypeEntity);

		transformService.save(transformEntity);
	}

	public void delete(String cnvsnName, String eaiSvcName, String cnvsnType) {
		transformService.deleteById(cnvsnName);
		if (eaiSvcName != null && !"".equals(eaiSvcName)) {
			updateTransfromEaiSvcName(eaiSvcName, cnvsnType, "0", null);
		}
	}

	public void updateTransfromEaiSvcName(String eaiSvcName, String cnvsnType, String chngEonot, String cnvsnName) {
		EAIMessageEntity eaiMessageEntity = eaiMessageService.getById(eaiSvcName);

		eaiMessageEntity
				.getServiceMessages()
				.stream()
				.filter(e -> e.getId().getSvcprcssno() == 1)
				.findFirst()
				.ifPresent(updateChngmsgidname(cnvsnType, chngEonot, cnvsnName, eaiMessageEntity));
	}

	private Consumer<? super ServiceMessageEntity> updateChngmsgidname(String cnvsnType, String chngEonot,
			String cnvsnName, EAIMessageEntity eaiMessageEntity) {
		return serviceMessageEntity -> {
			String motivdstcd = eaiMessageEntity.getSvcmotivusedstcd();
			String psvindstcd = serviceMessageEntity.getPsvintfacdsticname();
			if (logger.isInfoEnabled()) {
				logger.info("motivdstcd :" + motivdstcd + ", psvindstcd : " + psvindstcd);
			}

			String newCnvsnType = cnvsnType;
			if ("ASYN".equals(motivdstcd) && "ASYN".equals(psvindstcd) && !"ERR".equals(cnvsnType)) {
				newCnvsnType = "REQ";
			}

			if ("REQ".equals(newCnvsnType)) {
				serviceMessageEntity.setChngeonot(chngEonot);
				serviceMessageEntity.setChngmsgidname(cnvsnName);
			} else if ("RES".equals(newCnvsnType)) {
				serviceMessageEntity.setBascrspnschngeonot(chngEonot);
				serviceMessageEntity.setBascrspnschngmsgidname(cnvsnName);
			} else if ("ERR".equals(newCnvsnType)) {
				serviceMessageEntity.setErrrspnschngeonot(chngEonot);
				serviceMessageEntity.setErrrspnschngmsgidname(cnvsnName);
			}
		};
	}

	public List<HashMap> selectTransform(String cnvsnName) {
		HashMap params = new HashMap();
		params.put("cnvsnName", cnvsnName);
		return transformDao.selectTransform(params);
	}

	public void exportData(HashMap paramMap) throws Exception {
		String eaiBzwkDstCd = (String) paramMap.get("eaiBzwkDstCd");
		String userId = (String) paramMap.get("userId");
		String cmId = (String) paramMap.get("cmId");
		String[] arrCnvsnNames = (String[]) paramMap.get("arrCnvsnNames");

		// º¯È¯¸í Áßº¹ Á¦°Å
		arrCnvsnNames = new HashSet<String>(Arrays.asList(arrCnvsnNames)).toArray(new String[0]);

		Properties prop = monitoringContext.getProperties();
		if (prop == null) {
			throw new Exception("프라퍼티 정보가 없습니다. - CM_CONFIG");
		}
		// [2020-01-08 13:45:54,490] INFO (AuroraUtil.java:134) - addCMResource:
		// 9159|EAI200001|/fslog/eai/cmtemp/eai/EAI200001/DSG/transform/TRANSFORM_EAI_TST0200100EAI_REQ.txt
		String auroraIni = (String) prop
				.getProperty(MonitoringContext.CM_AURORA_INI_PATH, "/fshome/greai/eaiadm/aurora/auroraApi_config.ini");
		String localPath = (String) prop.getProperty(MonitoringContext.CM_AURORA_TMP_PATH, "/fslog/eai/cmtemp/");
		String rootPath = localPath + eaiBzwkDstCd.toLowerCase() + File.separator + cmId + File.separator;
		List<String> cmList = new ArrayList<String>();
		// º¯È¯ÆÄÀÏ»ý¼º
		for (String cnvsnName : arrCnvsnNames) {
			List<HashMap> listTransform = selectTransform(cnvsnName);
			if (listTransform != null && listTransform.size() > 0) {
				String eaiSevrDstcd = (String) listTransform.get(0).get("EAISEVRDSTCD");
				String eaiSevrName = IoMapLoaderKey.getEaiSevrName(eaiSevrDstcd);

				if ("ALL".equals(eaiSevrName)) {
					for (String sevr : IoMapLoaderKey.getAllEaiSevrName()) {
						eaiSevrName = sevr;
						String subPath = eaiSevrName + File.separator + FileWriteUtil.TRANSFORM + File.separator;
						String path = rootPath + subPath;

						DataSourceType dt = DataSourceContextHolder.getDataSourceType();
						try {
							LinkedHashMap<String, List> tables = loaderService
									.transformDownLoadingForData(dt, path, cnvsnName);
							List<LinkedHashMap> interfaceInfo = ioMapLoaderService
									.interfaceInfoDownLoading(path, cnvsnName, eaiSevrName);
							if (interfaceInfo.size() > 0) {
								tables.put("INTERFACEINFO", interfaceInfo);
							}
							FileWriteUtil.FileWrite(path, cnvsnName + FileWriteUtil.EXT_TXT, tables);
							File f = new File(path + cnvsnName + FileWriteUtil.EXT_TXT);
							if (f.exists()) {
								cmList.add(path + cnvsnName + FileWriteUtil.EXT_TXT);
							}
						} catch (Exception e) {
							throw new BizException("파일 생성에 실패하였습니다. CM 파일 목록이 없습니다.");
						}
					}
				} else {
					String subPath = eaiSevrName + File.separator + FileWriteUtil.TRANSFORM + File.separator;
					String path = rootPath + subPath;

					DataSourceType dt = DataSourceContextHolder.getDataSourceType();
					try {
						LinkedHashMap<String, List> tables = loaderService
								.transformDownLoadingForData(dt, path, cnvsnName);
						List<LinkedHashMap> interfaceInfo = ioMapLoaderService
								.interfaceInfoDownLoading(path, cnvsnName, eaiSevrName);
						if (interfaceInfo.size() > 0) {
							tables.put("INTERFACEINFO", interfaceInfo);
						}
						FileWriteUtil.FileWrite(path, cnvsnName + FileWriteUtil.EXT_TXT, tables);
						File f = new File(path + cnvsnName + FileWriteUtil.EXT_TXT);
						if (f.exists()) {
							cmList.add(path + cnvsnName + FileWriteUtil.EXT_TXT);
						}
					} catch (Exception e) {
						throw new BizException("파일 생성에 실패하였습니다. CM 파일 목록이 없습니다.");
					}
				}
			} else {
				logger.error("returned listTR01 is null : cnvsnName=" + cnvsnName);
			}
		}

		if (cmList == null || cmList.size() == 0) {
			throw new BizException("파일 생성에 실패하였습니다. CM 파일 목록이 없습니다.");
		}

		String groupCoCd = bizDao.selectGroupCoCdByEAIBzwkDstCd(new HashMap() {
			{
				put("eaiBzwkDstCd", eaiBzwkDstCd);
			}
		});

	}

	public List<Map<String, Object>> selectListToExcel(String searchCnvsnName, String searchCnvsnDesc,
			String searchBizCode, String searchIfSvcCd) {
		return transformService
				.findAll(Pageable.unpaged(), searchCnvsnName, searchCnvsnDesc, searchBizCode, searchIfSvcCd)
				.getContent()
				.stream()
				.map(transformEaiMessage -> {
					TransformEntity transformEntity = transformEaiMessage.getTransformEntity();
					Map<String, Object> map = new HashMap<>();
					map.put("EAIBZWKDSTCD", transformEaiMessage.getEaiBzwkDstcd());
					map.put("CNVSNNAME", transformEntity.getCnvsnname());
					map.put("CNVSNDESC", transformEntity.getCnvsndesc());
					map.put("EAISVCNAME", transformEaiMessage.getEaiSvcName());
					map.put("EAISVCDESC", transformEaiMessage.getEaiSvcDesc());
					map.put("USEYN", transformEntity.getUseyn());
					map.put("LASTAMNDHMS", transformEntity.getLastamndhms());
					map.put("VERINFO", transformEntity.getVerinfo());

					return map;
				})
				.collect(Collectors.toList());
	}

	public List selectCnvsnDetailPop(String cnvsnName, String tgt_layout, String src_layout) throws Exception {
		HashMap paramMap = new HashMap();
		paramMap.put("cnvsnName", cnvsnName);
		paramMap.put("loutName", tgt_layout);
		List<HashMap> loutList = transformDao.selectLayoutItems(paramMap);
		List<HashMap> transformList = transformDao.selectTransformItems(paramMap);

		for (HashMap trVo : transformList) {
			for (HashMap layoutVo : loutList) {
				String resultFullPath = (String) trVo.get("CNVSNRSULTITEMPATHNAME"); // º¯È¯°á°ú Ç×¸ñ°æ·Î
				String loutItemPath = (String) layoutVo.get("LOUTITEMPATH"); // ½ÇÁ¦°æ·Î
				if (resultFullPath.endsWith(loutItemPath)) {
					trVo.put("TGTEXIST", "O");
					break;
				} else if (CommonUtil.removeArrayTag(resultFullPath).endsWith(loutItemPath)) {
					trVo.put("TGTEXIST", "O");
					break;
				}
			}
		}
		// º¯È¯ ¸í·É
		HashMap paramMap2 = new HashMap();
		paramMap2.put("cnvsnName", cnvsnName);
		paramMap2.put("loutName", src_layout);
		List<HashMap> loutList2 = transformDao.selectLayoutItems(paramMap2);
		String patternStr = src_layout+".[ㄱ-ㅎ가-Ra-zA-Z0-9_\\-\\.\\[\\]]+";
		Pattern pattern = Pattern.compile(patternStr);

		for (HashMap trVo : transformList) {
			String cnvsnCmdName = (String) trVo.get("CNVSNCMDNAME"); // º¯È¯¸í·É
			cnvsnCmdName = CommonUtil.removeArrayTag(cnvsnCmdName); // ¹è¿­Á¦°Å
			Matcher match = pattern.matcher(cnvsnCmdName);
			List<String> matchList = new ArrayList<>();
			while (match.find()) {
				matchList.add((String) match.group());
			}
			if (matchList.size() > 0) { // º¯È¯¸í·É¿¡ ¼Ò½º·¹ÀÌ¾Æ¿ô path°¡ ÀÖ´Â °æ¿ì
				for (int i = 0; i < matchList.size(); i++) {
					for (HashMap layoutVo : loutList2) {
						String loutItemPath = (String) layoutVo.get("LOUTITEMPATH"); // ¼Ò½º·¹ÀÌ¾Æ¿ô ½ÇÁ¦°æ·Î
						if (matchList.get(i).endsWith(loutItemPath)) {
							trVo.put("SRCEXIST", "O");
							break;
						}
					}
				}
			} else {
				// º¯È¯¸í·ÉÀÌ Ç×¸ñ°æ·Î°¡¾Æ´Ñ °ª(ex:ascii2ebcdicx(DEFAULT_VALUE,12)) ÀÎ°æ¿ì
				// "O"¼ÂÆÃ
				trVo.put("SRCEXIST", "O");
			}
		}

		return transformList;
	}

	public TransformUI getTransformUiToExport(String transformName){
		TransformEntity transformEntity = transformService.getById(transformName);
		TransformUI transformUI = transformUIMapper.toVo(transformEntity);
		List<TransformTypeEntity> transformTypeEntities = transformEntity.getTransformTypeEntities();
		for(TransformTypeEntity transformTypeEntity : transformTypeEntities){
			if("SRC_LAYOUT".equals(transformTypeEntity.getId().getSourcrsultdstcd())){
				transformUI.setSrcLayoutName(transformTypeEntity.getId().getLoutname());
			}else if("TGT_LAYOUT".equals(transformTypeEntity.getId().getSourcrsultdstcd())){
				transformUI.setTgtLayoutName(transformTypeEntity.getId().getLoutname());
			}
		}

		List<TransformItemEntity> transformItemEntities = transformEntity.getTransformItemEntities();
		List<TransformItemUI> itemUIList = transformItemEntities.stream()
				.map(itemEntity -> transformItemUIMapper.toVo(itemEntity))
				.collect(Collectors.toList());
		transformUI.setGridData(itemUIList);

		return transformUI;
	}

	public void addTransformExcelSheet(String transformName, Workbook workbook, String sheetName) throws IOException {
		int height = 25;
		TransformUI transformUI = getTransformUiToExport(transformName);

		Sheet sheet = workbook.createSheet(sheetName);

		// 헤더 스타일 생성 및 설정
		CellStyle headerStyle = PoiUtils.createHeaderCellStyle(workbook);
		// 텍스트 스타일 생성 및 설정
		CellStyle textStyle = PoiUtils.createTextCellStyle(workbook);
		CellStyle titleStyle = PoiUtils.createTitleCellStyle(workbook);

		int rowNum = 0;
		rowNum = addTitle(sheet, rowNum, titleStyle, "기본 설정");
		Row row = sheet.createRow(rowNum++);
		row.setHeightInPoints(height); // 행 높이 설정
		int cellIndex = 0;
		createCell(row, cellIndex++, headerStyle, "타입");
		createCell(row, cellIndex++, textStyle, "TRANSFORM");
		row = sheet.createRow(rowNum++);
		row.setHeightInPoints(height); // 행 높이 설정
		cellIndex = 0;
		createCell(row, cellIndex++, headerStyle, "변환 명");
		createCell(row, cellIndex++, textStyle, transformName);
		row = sheet.createRow(rowNum++);
		row.setHeightInPoints(height); // 행 높이 설정
		cellIndex = 0;
		createCell(row, cellIndex++, headerStyle, "변환 설명");
		createCell(row, cellIndex++, textStyle, transformUI.getCnvsnDesc());
		row = sheet.createRow(rowNum++);
		row.setHeightInPoints(height); // 행 높이 설정
		cellIndex = 0;
		createCell(row, cellIndex++, headerStyle, "소스 레이아웃");
		createCell(row, cellIndex++, textStyle, transformUI.getSrcLayoutName());
		row = sheet.createRow(rowNum++);
		row.setHeightInPoints(height); // 행 높이 설정
		cellIndex = 0;
		createCell(row, cellIndex++, headerStyle, "타겟 레이아웃");
		createCell(row, cellIndex++, textStyle, transformUI.getTgtLayoutName());

		rowNum = addTitle(sheet, ++rowNum, titleStyle, "변환 항목");
		createItemsTable(transformUI.getGridData(), sheet, workbook, rowNum);

		int ci = 0;
		sheet.setColumnWidth(ci++, 200 * 30);
		sheet.setColumnWidth(ci++, 400 * 30);
		sheet.setColumnWidth(ci++, 400 * 30);
		sheet.setColumnWidth(ci++, 300 * 30);
	}

	private int addTitle(Sheet sheet, int rowNum, CellStyle titleStyle, String title) {
		Row row = sheet.createRow(rowNum++);
		row.setHeightInPoints(30); // 행 높이를 20 포인트로 설정
		createCell(row, 0, titleStyle, title);
		return rowNum;
	}

	private void createCell(Row row, int cellIndex, CellStyle cellStyle, String value){
		Cell cell = row.createCell(cellIndex);
		cell.setCellValue(value);
		cell.setCellStyle(cellStyle);
	}

	private void createItemsTable(List<TransformItemUI> items, Sheet sheet, Workbook workbook, int startRow) {
		int height = 25;
		CellStyle headerStyle = PoiUtils.createHeaderCellStyle(workbook);
		CellStyle dataStyle = PoiUtils.createTextCellStyle(workbook);
		CellStyle dataStyleCenter = PoiUtils.createTextCellStyle(workbook);
		dataStyleCenter.setAlignment(HorizontalAlignment.CENTER);

		if (workbook instanceof XSSFWorkbook) {
			XSSFCellStyle xssfHeaderStyle = (XSSFCellStyle) headerStyle;
			// 연두색 파스텔 톤으로 배경색 설정
			xssfHeaderStyle.setFillForegroundColor(new XSSFColor(new java.awt.Color(204, 255, 204)));
			xssfHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		} else if (workbook instanceof HSSFWorkbook) {
			// HSSFWorkbook의 경우 IndexedColors를 사용 (가장 가까운 색상 선택)
			headerStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
			headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		}

		String[] headers = {
				"일련번호",
				"변환명령",
				"대상아이템경로",
				"기본 값",
		};

		Row headerRow = sheet.createRow(startRow);
		headerRow.setHeightInPoints(height); // 행 높이를 20 포인트로 설정
		for (int i = 0; i < headers.length; i++) {
			Cell cell = headerRow.createCell(i);
			cell.setCellValue(headers[i]);
			cell.setCellStyle(headerStyle);
		}

		int rowNum = startRow + 1;
		for (int i = 0; i < items.size(); i++) {
			TransformItemUI item = items.get(i);
			Row row = sheet.createRow(rowNum++);
			row.setHeightInPoints(height); // 행 높이 설정
			int ci = 0;
			Cell serNo = row.createCell(ci++);
			serNo.setCellStyle(dataStyleCenter);
			serNo.setCellValue(item.getCnvsnitemserno());//일련번호

			row.createCell(ci++).setCellValue(item.getCnvsncmdname());//변환명령
			row.createCell(ci++).setCellValue(item.getCnvsnRsultItemPathName());//대상아이템경로
			row.createCell(ci).setCellValue(item.getCnvsnitembascval());//기본 값

			for (int index = 1; index < headers.length; index++) {
				Cell cell = row.getCell(index, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
				cell.setCellStyle(dataStyle);
			}
		}
	}

	public TransformUI importTransformExcelSheet(Sheet sheet){
		String transformName = PoiUtils.getCellValue(sheet, 2, 1);
		String transformDesc = PoiUtils.getCellValue(sheet, 3, 1);
		String sourceLayoutName = PoiUtils.getCellValue(sheet, 4, 1);
		String targetLayoutName = PoiUtils.getCellValue(sheet, 5, 1);

		TransformUI transformUI = new TransformUI();
		transformUI.setCnvsnName(transformName);
		transformUI.setCnvsnDesc(transformDesc);
		transformUI.setSrcLayoutName(sourceLayoutName);
		transformUI.setTgtLayoutName(targetLayoutName);
		transformUI.setUseYn("1");

		List<TransformItemUI> transformItemUiList = new ArrayList<>();
		transformUI.setGridData(transformItemUiList);

		// 시트의 마지막 행까지 반복
		for (int rowIndex = 9; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
			Row row = sheet.getRow(rowIndex);
			if(row == null) continue;

			TransformItemUI transformItemUI = new TransformItemUI();
			transformItemUI.setCnvsnName(transformName);
			transformItemUI.setCnvsnitemserno(PoiUtils.convertCellToInt(row.getCell(0)));
			transformItemUI.setCnvsncmdname(row.getCell(1).getStringCellValue());
			transformItemUI.setCnvsnRsultItemPathName(row.getCell(2).getStringCellValue());
			transformItemUI.setCnvsnitembascval(row.getCell(3).getStringCellValue());
			transformItemUiList.add(transformItemUI);
		}

		importTransformUi(transformUI);

		return transformUI;
	}

	public void importTransformUi(TransformUI transformUI) {
		String transformName = transformUI.getCnvsnName();

		if(!transformService.existsById(transformName)){
			TransformEntity transformEntity = transformUIMapper.toEntity(transformUI);
			transformEntity.setTransformTypeEntities(new ArrayList<>());
			transformService.save(transformEntity);
		}

		transaction(transformUI);
	}
}
