package com.eactive.eai.rms.onl.transaction.apim.mapping;

import java.util.ArrayList;
import java.util.List;

import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageItem;
import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageItemId;
import com.eactive.eai.rms.onl.manage.serviceinfo.stdmessage.StdMessageItemUI;
import com.eactive.eai.rms.onl.manage.serviceinfo.stdmessage.StdMessageItemUIMapper;
import com.eactive.eai.rms.onl.transaction.simpleinterface.ui.SimpleInterfaceUI;
import org.apache.commons.lang.StringUtils;
import org.mapstruct.AfterMapping;
import org.mapstruct.InheritConfiguration;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Named;

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.stdmessage.StandardMessageInfo;
import com.eactive.eai.data.mapper.BaseMapperConfig;
import com.eactive.eai.rms.onl.transaction.apim.ApiInterfaceService;
import com.eactive.eai.rms.onl.transaction.apim.ui.ApiInterfaceUI;

@Mapper(config = BaseMapperConfig.class, uses = { StdMessageItemUIMapper.class })
public interface ApiInterfaceUIMapper {

    @Mapping(source = "eaiSvcName", target = "eaisvcname")
    @Mapping(source = "eaiBzwkDstcd", target = "eaibzwkdstcd")
    @Mapping(source = "sevrLogLvelNo", target = "sevrloglvelno", defaultValue = "3")
    @Mapping(source = "svcLogLvelNo", target = "svcloglvelno", defaultValue = "3")
    @Mapping(source = "eaiSvcDesc", target = "eaisvcdesc")
    @Mapping(source = "fromAdapter", target = "gstatsysadptrbzwkgroupname")
    @Mapping(source = "lastModifiedDate", target = "eailastamndyms")
    @Mapping(source = "apiEnabledYn", target = "apienabledyn")
    @Mapping(source = "authType", target = "authtype")
    @Mapping(source = "verinfo", target = "verinfo")
    @Mapping(target = "svchmseonot", constant = "0")
    @Mapping(target = "svcmotivusedstcd", constant = "SYNC")
    @Mapping(target = "svcprcesdsticname", constant = "SINGLE")
    @Mapping(target = "flowctrlroutname", constant = "BASEFC")
    @Mapping(target = "intgradsticname", constant = "ONLINE")
    @Mapping(target = "svcbfclmnlogyn", constant = "0")
    @Mapping(target = "useyn", constant = "1")
    EAIMessageEntity toEaiMessageEntity(ApiInterfaceUI vo);

    @InheritInverseConfiguration(name = "toEaiMessageEntity")
    ApiInterfaceUI toVo(EAIMessageEntity eaiMessageEntity);

    @Mapping(target = "eaiSvcName", source = "eaiMessageEntity.eaisvcname")
    @Mapping(target = "eaiBzwkDstcd", source = "eaiMessageEntity.eaibzwkdstcd")
    @Mapping(target = "eaiSvcDesc", source = "eaiMessageEntity.eaisvcdesc")
    @Mapping(target = "fromAdapter", source = "eaiMessageEntity.gstatsysadptrbzwkgroupname")
    @Mapping(target = "author", source = "eaiMessageEntity.author")
    @Mapping(source = "eaiMessageEntity.apienabledyn", target = "apiEnabledYn")
    @Mapping(source = "eaiMessageEntity.authtype", target = "authType")
    @Mapping(target = "lastModifiedDate", source = "eaiMessageEntity.eailastamndyms")
    @Mapping(target = "svcLogLvelNo", source = "eaiMessageEntity.svcloglvelno")
    @Mapping(target = "verinfo", source = "eaiMessageEntity.verinfo")
    ApiInterfaceUI toVo(EAIMessageEntity eaiMessageEntity, List<ServiceMessageEntity> serviceMessageEntities);

    @InheritConfiguration(name="toEaiMessageEntity")
    void updateEaiMessageEntity(ApiInterfaceUI vo, @MappingTarget EAIMessageEntity entity);

    @AfterMapping
    default void setServiceMessageEntity(ApiInterfaceUI vo, @MappingTarget ServiceMessageEntity entity) {
        String requestTransfrom = StringUtils.defaultString(vo.getRequestTransform());
        String requestTransformYn = StringUtils.isBlank(requestTransfrom) ? "0" : "1";

        String responseTransfrom = StringUtils.defaultString(vo.getResponseTransform());
        String responseTransfromYn = StringUtils.isBlank(responseTransfrom) ? "0" : "1";

        String errResponseTransform = StringUtils.defaultString(vo.getErrResponseTransform());
        String errResponseTransformYn = StringUtils.isBlank(errResponseTransform) ? "0" : "1";

        if("N".equals(vo.getTransformYn())) {
            requestTransformYn = "0";
            responseTransfromYn = "0";
        }

        if(!"Y".equals(vo.getErrTransformYn())) {
            errResponseTransformYn = "0";
        }

        entity.setChngeonot(requestTransformYn);
        entity.setBascrspnschngeonot(responseTransfromYn);
        entity.setErrrspnschngeonot(errResponseTransformYn);
        entity.setErrrspnschngmsgidname(errResponseTransform);
    }

    @AfterMapping
    default void setServiceMessageEntities(EAIMessageEntity eaiMessageEntity, List<ServiceMessageEntity> serviceMessageEntities, @MappingTarget ApiInterfaceUI vo) {
        if (serviceMessageEntities == null || serviceMessageEntities.isEmpty()) {
            return;
        }

        // 요청 처리 (항상 첫 번째 ServiceMessageEntity 사용)
        ServiceMessageEntity requestEntity = serviceMessageEntities.get(0);

        // Sync/Async 타입 결정
        String inboundSyncAsyncType = eaiMessageEntity.getSvcmotivusedstcd();
        String outboundSyncAsyncType = requestEntity.getPsvintfacdsticname();
        String syncAsyncType = "sync";

        if(inboundSyncAsyncType.equals("ASYN") && outboundSyncAsyncType.equals("ASYN")){
            syncAsyncType = "async";
        }else if(inboundSyncAsyncType.equals("SYNC") && outboundSyncAsyncType.equals("ASYN")){
            syncAsyncType = "syncAsync";
        }else if(inboundSyncAsyncType.equals("ASYN") && outboundSyncAsyncType.equals("SYNC")){
            syncAsyncType = "asyncSync";
        }
        vo.setSyncAsyncType(syncAsyncType);
        
        // 가상응답 여부
        String simYn = "T".equals(eaiMessageEntity.getTrantype()) ? "Y" : "N";
        vo.setSimYn(simYn);

        vo.setToAdapter(requestEntity.getPsvsysadptrbzwkgroupname());
        vo.setToutVal(requestEntity.getToutval());
        vo.setRequestTransform(requestEntity.getChngmsgidname());
    }

    @Mapping(target = "psvsysbzwkdstcd", source = "eaiBzwkDstcd")
    @Mapping(target = "psvsysadptrbzwkgroupname", source = "toAdapter")
    @Mapping(target = "chngmsgidname", source = "requestTransform")
    @Mapping(target = "bascrspnschngmsgidname", source = "responseTransform")
    @Mapping(target = "errrspnschngmsgidname", source = "errResponseTransform")
    @Mapping(target = "toutval", source = "toutVal", defaultValue = "0L")
    @Mapping(target = "psvsysidname", constant = "EAIDOM")
    @Mapping(target = "psvintfacdsticname", constant = "SYNC")
    @Mapping(target = "psvsyssvcdsticname", constant = " ")
    @Mapping(target = "flovryn", constant = "0")
    @Mapping(target = "bascrspnsmsgcmprctnt", constant = " ")
    @Mapping(target = "errrspnsmsgcmprctnt", constant = " ")
    @Mapping(target = "nextsvcprcssno", constant = "1")
    @Mapping(target = "cmpensvcprcssdsticname", constant = " ")
    @Mapping(target = "suppldelyn", constant = "0")
    @Mapping(target = "hdrctrldstcd", constant = "01")
    @Mapping(target = "hdrrefclsname", constant = " ")
    void updateServiceMessageEntity(ApiInterfaceUI vo, @MappingTarget ServiceMessageEntity entity);

    @InheritConfiguration(name="updateServiceMessageEntity")
    @Mapping(target = "id.eaisvcname", source = "eaiSvcName")
    @Mapping(target = "id.svcprcssno", constant = "1")
    ServiceMessageEntity toServiceMessageEntity(ApiInterfaceUI vo);

    @Mapping(target = "eaisvcname", source = "eaiSvcName")
    @Mapping(target = "eaisendrecv", source = "sendRecvType")
    @Mapping(target = "eaidirection", source = "inOutType")
    @Mapping(target = "standardMessageItems", source = "standardMessageItems")
    @Mapping(target = "apifullpath", source = "apiFullPath")
    StandardMessageInfo toStandardMessageInfo(ApiInterfaceUI vo);

    @AfterMapping
    default void setStandardMessageInfo(ApiInterfaceUI vo, @MappingTarget StandardMessageInfo entity) throws RuntimeException {
        String eaiSvcName = entity.getEaisvcname();
        String inboundAdapterGroupName = vo.getFromAdapter();
        String inboundRestPath = vo.getInboundRestPath();
        String inboundHttpMethod = vo.getInboundHttpMethod();

        String inboundMethod = StringUtils.defaultString(inboundHttpMethod, "POST").toUpperCase();

        List<String> headerValues = vo.getHeaderValues();

        String stdMessageKey = inboundAdapterGroupName + ApiInterfaceService.STEMSG_METHOD_DELIMITER + inboundMethod;

        if(vo.getIsHeaderRouting() != null && vo.getIsHeaderRouting() && headerValues != null && headerValues.size() > 0){
        	if(!StringUtils.isBlank(inboundRestPath)) {
        		stdMessageKey += ApiInterfaceService.STEMSG_SERVICE_URL_DELIMITER + inboundRestPath;
        	}
            stdMessageKey += ApiInterfaceService.STEMSG_SERVICE_HEADER_DELIMITER + String.join(ApiInterfaceService.STEMSG_HEADER_SEPARATOR, headerValues);
        }else{
            if(StringUtils.isBlank(inboundRestPath)) {
                throw new RuntimeException("inbound 서비스 URL이 정의되어 있지 않습니다.");
            }
            stdMessageKey += ApiInterfaceService.STEMSG_SERVICE_URL_DELIMITER + inboundRestPath;
        }

        entity.setBzwksvckeyname(stdMessageKey);

        List<StandardMessageItem> standardMessageItems = entity.getStandardMessageItems();
        if(standardMessageItems != null){
            for (StandardMessageItem standardMessageItem : standardMessageItems){
                standardMessageItem.getId().setBzwksvckeyname(stdMessageKey);
            }
        }

        String eaiTranName = eaiSvcName.substring(0, eaiSvcName.length() - 2);
        entity.setEaitranname(eaiTranName);
    }

    @AfterMapping
    default void setEaiMessageEntity(ApiInterfaceUI vo, @MappingTarget EAIMessageEntity entity) {
        if(vo == null || vo.getSyncAsyncType() == null){
            return;
        }
        
        // 가상응답 여부
        String tranType = "Y".equals(vo.getSimYn()) ? "T" : "R";
        entity.setTrantype(tranType);
        
        switch(vo.getSyncAsyncType()){
            case "async":
            case "asyncSync":
                entity.setSvcmotivusedstcd("ASYN");
                break;
        }
    }
}