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

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.simpleinterface.ui.SimpleInterfaceUI;
import org.apache.commons.lang.StringUtils;
import org.mapstruct.*;

import java.util.List;

@Mapper(config = BaseMapperConfig.class)
public interface SimpleInterfaceUIMapper {

    @Mapping(source = "eaiSvcName", target = "eaisvcname")
    @Mapping(source = "eaiBzwkDstcd", target = "eaibzwkdstcd")
    @Mapping(source = "sevrLogLvelNo", target = "sevrloglvelno", defaultValue = "3")
    @Mapping(source = "sevrLogLvelNo", target = "svcloglvelno", defaultValue = "3")
    @Mapping(source = "eaiSvcDesc", target = "eaisvcdesc")
    @Mapping(source = "fromAdapter", target = "gstatsysadptrbzwkgroupname")
    @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(SimpleInterfaceUI vo);

    @InheritInverseConfiguration(name = "toEaiMessageEntity")
    SimpleInterfaceUI 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(target = "toAdapter", source = "serviceMessageEntity.psvsysadptrbzwkgroupname")
    SimpleInterfaceUI toVo(EAIMessageEntity eaiMessageEntity, ServiceMessageEntity serviceMessageEntity);


    @AfterMapping
    default void afterVoMapping(@MappingTarget SimpleInterfaceUI apiInterfaceUI,
                              EAIMessageEntity eaiMessageEntity,
                              ServiceMessageEntity serviceMessageEntity) {
        String simYn = "T".equals(eaiMessageEntity.getTrantype()) ? "Y" : "N";
        apiInterfaceUI.setSimYn(simYn);

        String inboundSyncAsyncType = eaiMessageEntity.getSvcmotivusedstcd();
        String outboundSyncAsyncType = serviceMessageEntity.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";
        }
        apiInterfaceUI.setSyncAsyncType(syncAsyncType);
    }

    @AfterMapping
    default void setEaiMessageEntity(SimpleInterfaceUI vo, @MappingTarget EAIMessageEntity entity) {
        String tranType = "Y".equals(vo.getSimYn()) ? "T" : "R";
        entity.setTrantype(tranType);
        switch(vo.getSyncAsyncType()){
            case "async":
            case "asyncSync":
                entity.setSvcmotivusedstcd("ASYN");
                break;
        }
    }

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

    @AfterMapping
    default void setServiceMessageEntity(SimpleInterfaceUI vo, @MappingTarget ServiceMessageEntity entity) {
        if("asyncSync".equals(vo.getSyncAsyncType())  && 2 == entity.getId().getSvcprcssno()
        || "syncAsync".equals(vo.getSyncAsyncType())  && entity.getId().getEaisvcname().charAt(entity.getId().getEaisvcname().length() - 2) == 'R'){
            return;
        }

        switch(vo.getSyncAsyncType()){
            case "async":
            case "syncAsync":
                entity.setPsvintfacdsticname("ASYN");
                break;
        }

        String requestTransfrom = StringUtils.defaultString((String) vo.getRequestTransform());
        String requestTransformYn = StringUtils.isBlank(requestTransfrom) ? "0" : "1";

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

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

        entity.setChngeonot(requestTransformYn);
        entity.setBascrspnschngeonot(responseTransfromYn);
    }

    @Mapping(target = "psvsysbzwkdstcd", source = "eaiBzwkDstcd")
    @Mapping(target = "psvsysadptrbzwkgroupname", source = "toAdapter")
    @Mapping(target = "chngmsgidname", source = "requestTransform")
    @Mapping(target = "bascrspnschngmsgidname", source = "responseTransform")
    @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 = "errrspnschngeonot", constant = "0")
    @Mapping(target = "errrspnschngmsgidname", 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(SimpleInterfaceUI vo, @MappingTarget ServiceMessageEntity entity);

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

    @InheritConfiguration(name="updateServiceMessageEntity")
    @Mapping(target = "psvsysadptrbzwkgroupname", source = "fromResponseAdapter")
    void updateAsyncSyncResServiceMessageEntity(SimpleInterfaceUI vo, @MappingTarget ServiceMessageEntity entity);


    @Mapping(target = "eaisvcname", source = "eaiSvcName")
    @Mapping(target = "eaisendrecv", source = "sendRecvType")
    @Mapping(target = "eaidirection", source = "inOutType")
    StandardMessageInfo toStandardMessageInfo(SimpleInterfaceUI vo);

    @InheritConfiguration(name="toStandardMessageInfo")
    @Mapping(source = "eaiSvcName", target = "eaisvcname", qualifiedByName = "changeEaiSvcNameToRecv")
    @Mapping(target = "eaisendrecv", constant = "R")
    StandardMessageInfo toSyncAsyncResStandardMessageInfo(SimpleInterfaceUI vo);

    @InheritConfiguration(name="updateServiceMessageEntity")
    @Mapping(target = "id.eaisvcname", source = "eaiSvcName")
    @Mapping(target = "id.svcprcssno", constant = "2")
    @Mapping(target = "psvintfacdsticname", constant = "ASYN")
    @Mapping(target = "psvsysadptrbzwkgroupname", source = "fromResponseAdapter")
    @Mapping(target = "chngmsgidname", constant = " ")
    @Mapping(target = "bascrspnschngmsgidname", constant = " ")
    ServiceMessageEntity toAsyncSyncResServiceMessageEntity(SimpleInterfaceUI vo);

    @InheritConfiguration(name="updateServiceMessageEntity")
    @Mapping(target = "id.eaisvcname", source = "eaiSvcName", qualifiedByName = "changeEaiSvcNameToRecv")
    @Mapping(target = "id.svcprcssno", constant = "1")
    @Mapping(target = "psvintfacdsticname", constant = "ASYN")
    @Mapping(target = "chngmsgidname", constant = " ")
    @Mapping(target = "bascrspnschngmsgidname", constant = " ")
    ServiceMessageEntity toSyncAsyncResServiceMessageEntity(SimpleInterfaceUI vo);

    @InheritConfiguration(name = "toEaiMessageEntity")
    @Mapping(source = "eaiSvcName", target = "eaisvcname", qualifiedByName = "changeEaiSvcNameToRecv")
    @Mapping(target = "gstatsysadptrbzwkgroupname", source = "toResponseAdapter")
    EAIMessageEntity toSyncAsyncResEaiMessageEntity(SimpleInterfaceUI vo);

    @Named("changeEaiSvcNameToRecv")
    default String changeEaiSvcNameToRecv(String eaiSvcName) {
        if (eaiSvcName != null && eaiSvcName.length() > 1) {
            StringBuilder sb = new StringBuilder(eaiSvcName);
            sb.setCharAt(sb.length() - 2, 'R'); // 끝에서 두 번째 문자를 'R'로 변경
            return sb.toString();
        }
        return eaiSvcName; // 원본 반환
    }

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

        if(eaiSvcName.charAt(eaiSvcName.length() - 2) == 'R'){
            inboundAdapterGroupName = (String) vo.getToResponseAdapter();
            inboundRestPath = (String) vo.getOutboundResponseRestPath();
            inboundHttpMethod = (String) vo.getOutboundResponseHttpMethod();
        }else {
            inboundAdapterGroupName = (String) vo.getFromAdapter();
            inboundRestPath = (String) vo.getInboundRestPath();
            inboundHttpMethod = (String) 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() && headerValues != null && headerValues.size() > 0){
            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);

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

}
