package com.eactive.eai.rms.onl.manage.rule.layout.mapper;

import java.util.HashMap;
import java.util.List;

import org.apache.commons.lang.WordUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.mapstruct.AfterMapping;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;

import com.eactive.eai.data.entity.onl.transformer.layout.LayoutItemEntity;
import com.eactive.eai.data.mapper.BaseMapperConfig;
import com.eactive.eai.data.mapper.GenericMapper;
import com.eactive.eai.rms.onl.common.exception.EMSRuntimeException;
import com.eactive.eai.rms.onl.manage.rule.layout.ui.LayoutPopupUI;
import com.eactive.eai.transformer.layout.Item;
import com.eactive.eai.transformer.layout.ItemNodeType;

@Mapper(config = BaseMapperConfig.class)
public interface LayoutPopupUIMapper extends GenericMapper<LayoutPopupUI, LayoutItemEntity> {


	@Mapping(source = "id.loutname", target = "loutName")
	@Mapping(source = "id.loutitemserno", target = "loutItemSerno")
	@Mapping(source = "id.loutitemname", target = "loutItemName")
	@Mapping(source = "loutitemdesc", target = "loutItemDesc")
	@Mapping(source = "loutdptcnt", target = "loutItemDepth")
	@Mapping(constant = "Field", target = "loutItemType")
	@Mapping(source = "loutitemrefinfo2", target = "loutItemOccRef")
	@Mapping(source = "loutitemrefptrnidname", target = "loutItemDataType")
	@Mapping(source = "decptlencnt", target = "loutItemDecimal")
	@Mapping(source = "loutitembascval", target = "loutItemDefault")
	@Mapping(source = "loutitemmskyn", target = "loutItemMaskYn")
	@Mapping(source = "loutitemmaskoffset", target = "loutItemMaskOffset")
	@Mapping(source = "loutitemmasklength", target = "loutItemMaskLength")
	@Mapping(source = "loutitemlencnt", target = "loutItemLength")
	@Mapping(target = "id", ignore = true)
	@Override
	LayoutPopupUI toVo(LayoutItemEntity entity);

	@InheritInverseConfiguration
	@Override
	LayoutItemEntity toEntity(LayoutPopupUI vo);

	List<LayoutPopupUI> map(List<LayoutItemEntity> entities);

	
	@AfterMapping
	default void configTreeAttribute(LayoutItemEntity item, @MappingTarget LayoutPopupUI popupUI) {
		popupUI.setLevel(0);
		popupUI.setId(item.getLoutitemidname());
		popupUI.setParent(item.getParntloutitemidname());
		popupUI.setExpanded(true);

		if (Item.NODE_FIELD == item.getLoutitemnodeptrnidname()) {
			popupUI.setLeaf(true);
		}

		String itemType;
		String itemLoopCount = "";

		// 아이템 노드 타입이 GROUP인 경우
		if (ItemNodeType.GROUP.getNumber() == item.getLoutitemnodeptrnidname()) {
			// 아이템 발생 포인터 명이 '*'이거나 숫자로 생성 가능한 경우
			boolean isGridCondition = "*".equals(item.getLoutitemoccurptrndstcd()) || NumberUtils.isCreatable(item.getLoutitemoccurptrndstcd());
			// itemType을 GRID 또는 GROUP으로 설정
			itemType = isGridCondition ? "GRID" : "GROUP";

			// isGridCondition이 참이고, 참조 정보2가 비어 있는 경우, itemLoopCount 설정
			if (isGridCondition && StringUtils.isBlank(item.getLoutitemrefinfo2())) {
				if ("*".equals(item.getLoutitemoccurptrndstcd())) {
					// 반복횟수로 '*'(무제한)이 저장된 경우, 화면 그리드에도 '*'을 그대로 표시
					itemLoopCount = "*";
				} else if (NumberUtils.isCreatable(item.getLoutitemoccurptrndstcd())
						&& Integer.parseInt(item.getLoutitemoccurptrndstcd()) > -1) {
					itemLoopCount = item.getLoutitemoccurptrndstcd();
				}
			}
		} else if (ItemNodeType.FIELD.getNumber() == item.getLoutitemnodeptrnidname()) {
			// 아이템 발생 포인터 명이 '*'이거나 숫자로 생성 가능한 경우
			boolean isArrayCondition = "*".equals(item.getLoutitemoccurptrndstcd()) || NumberUtils.isCreatable(item.getLoutitemoccurptrndstcd());
			// itemType을 ARRAY 또는 FIELD 로 설정
			itemType = isArrayCondition ? "ARRAY" : "FIELD";

			// isArrayCondition이 참이고, 참조 정보2가 비어 있는 경우, itemLoopCount 설정
			if (isArrayCondition && StringUtils.isBlank(item.getLoutitemrefinfo2())) {
				if ("*".equals(item.getLoutitemoccurptrndstcd())) {
					// 반복횟수로 '*'(무제한)이 저장된 경우, 화면 그리드에도 '*'을 그대로 표시
					itemLoopCount = "*";
				} else if (NumberUtils.isCreatable(item.getLoutitemoccurptrndstcd())
						&& Integer.parseInt(item.getLoutitemoccurptrndstcd()) > -1) {
					itemLoopCount = item.getLoutitemoccurptrndstcd();
				}
			}
		} else {
			// 아이템 노드 타입이 GROUP이 아닌 경우, 해당 노드 타입으로 itemType 설정
			itemType = ItemNodeType.fromNumber(item.getLoutitemnodeptrnidname()).toString();
		}

		itemType = WordUtils.capitalizeFully(itemType); //아이템유형

		popupUI.setLoutItemType(itemType);

		if (!"*".equals(itemLoopCount) && NumberUtils.toInt(itemLoopCount) == 0) {
			itemLoopCount = "";
		}
		popupUI.setLoutItemOccCnt(itemLoopCount);

		popupUI.setLoutItemDepth(item.getLoutdptcnt() - 1);
	}

	@AfterMapping
	default void buildTree(@MappingTarget List<LayoutPopupUI> layoutPopupUIs) {

		HashMap<String, Integer> levelMap = new HashMap<>();
		HashMap<String, String> pathMap = new HashMap<>();

		for (LayoutPopupUI layoutItemUi : layoutPopupUIs) {
			try {
				String id = getObjectAsString(layoutItemUi.getId());
				String parent = getObjectAsString(layoutItemUi.getParent());

				int level = levelMap.containsKey(parent) ? levelMap.get(parent) + 1 : 0;
				layoutItemUi.setLevel(level);
				levelMap.put(id, level);

				String parentLoutItemPath = pathMap.get(parent);
				String path = getObjectAsString(layoutItemUi.getLoutItemName());
				path = (parentLoutItemPath != null) ? parentLoutItemPath + "." + path : path;
				pathMap.put(id, path);
				layoutItemUi.setLoutitempath(path);
			} catch (Exception e) {
				throw new EMSRuntimeException("Level Check Error", e);
			}
		}
	}

	default String getObjectAsString(Object obj) {
		if (obj instanceof String) {
			return (String) obj;
		} else if (obj instanceof Number) {
			return obj.toString();
		} else {
			return (obj != null) ? obj.toString() : "";
		}
	}

}
