package com.brilliance.isc.common.wfmmod.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.brilliance.mda.runtime.mda.IStream;
import com.brilliance.mda.runtime.mda.impl.Argument;
import com.brilliance.mda.runtime.mda.impl.StreamImpl;
import com.brilliance.mda.runtime.mda.util.*;
import com.brilliance.isc.bo.Sro;
import com.brilliance.isc.bo.Wfe;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.counter.service.CounterService;
import com.brilliance.isc.common.sysmod.SysmodService;
import com.brilliance.isc.common.transaction.help.TransactionHelpService;
import com.brilliance.isc.common.trnmod.vo.TrnmodVo;
import com.brilliance.isc.common.util.SettleExceptionUtils;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.wfmmod.service.WfmmodService;
import com.brilliance.isc.common.wfmmod.vo.WfmmodVo;
import com.brilliance.isc.mda.dao.PublicMapper;
import com.brilliance.isc.mda.dao.SroMapper;
import com.brilliance.isc.mda.dao.WfeMapper;
import com.brilliance.isc.mda.dao.WfsMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.brilliance.mda.runtime.mda.Constants.NULLDATETIME;
import static com.brilliance.mda.runtime.mda.Constants.NULLSTR;
@Service
public class WfmmodServiceImpl implements WfmmodService {

    private Logger log = (Logger) LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WfsMapper wfsMapper;
    @Autowired
    private WfeMapper wfeMapper;

    @Autowired
    private SysmodService sysmodService;

    @Autowired
    private PublicMapper publicMapper;

    @Autowired
    private CodetableService codetableService;

    @Autowired
    private CounterService counterService;

    @Autowired
    private SroMapper sroMapper;

    @Autowired
    private TransactionHelpService transactionHelpService;

    /**
     * 检索iniName文件所有条目（必须指定文件扩展名）
     * 以文本块形式保存流中
     * 修改指定的wfe相关属性
     *
     * @param insub
     * @param insrv
     * @param tarday
     * @param tartim
     */
    public void wfeAdd(String insub, String insrv, Date tarday, BigDecimal tartim) {
        TrnmodVo trnmodVo = transactionHelpService.getTransactionStoreSet().getTrnmodVo();
        WfmmodVo wfmmodVo = trnmodVo.getTrnism().getWfmmod();
        //! adds for wfs a new row in list of service entries for given subid
        //! or replaces such an entry if it already exists
        // arguments tarday and tartim must be passed in user time zone
        // target timestamp is stored in TZSystem
        if (!MdaUtils.isEmpty(wfmmodVo.getWfs().getInr())) {
            if (sysmodService.sptIsExeLoaded(trnmodVo.getSptaut().getSta())) {
                //    if in recalculation: Do never create new workflow entries
                return;
            } else {
                if (!"PDXTSK".equalsIgnoreCase(SettleContext.getTransName())) {
                    SettleExceptionUtils.sysDump("AddWfe: attempt to add workflow service entry after creation of wfs");
                }
            }
        }
        if (MdaUtils.compareTo(tartim, 24) >= 0) {
            tartim = new BigDecimal("23.59");
        }
        Date tardaytim = Dates.dateTimeMake(tarday, tartim);
        //3中case：1.都没找到（可能是集合是0个元素，也可能是真没找到）  2.找到Wfssub是空进行替换 3. 找到指定insub的wfssub进行替换
        int useidx = getIdx(wfmmodVo, insub);
        Wfe wfe =  new Wfe();
        wfe.setWfsinr(" ");  // will be filled in Create
        wfe.setWfssub(insub);
        wfe.setSrv(insrv);
        wfe.setSta("O");
        wfe.setRtycnt(0);
        wfe.setTardattim(tardaytim);
        wfe.setDattim(NULLDATETIME);
        wfe.setOpndur(0);
        wfe.setWaidur(0);
        wfe.setRetdur(0);
        wfe.setHdldur(0);
        if("FIN".equals(wfe.getSrv())){
            wfe.setSta("O");
        }
        if (useidx == -1) {
            int gridcnt = wfmmodVo.getWfe().size();
            for (int runidx = 0; runidx < gridcnt; runidx++) { // search free entry in WFE list
                if (MdaUtils.isEmpty(wfmmodVo.getWfe().get(runidx).getWfssub())) {
                    useidx = runidx;
                    break;
                }
            }
        }
        if (useidx == -1) {
            wfmmodVo.getWfe().add(wfe);
        } else {
            BeanUtils.copyProperties(wfe, wfmmodVo.getWfe().get(useidx));
        }
    }




    /**
     * 检索iniName文件所有条目（必须指定文件扩展名）
     * 以文本块形式保存流中
     * 修改指定的wfe相关属性
     *
     * @param insub
     * @param insrv
     * @param tarday
     * @param tartim
     */
    public void wfeAddWithVar(String insub, String insrv, Date tarday, BigDecimal tartim, String interfacetxt) {
        TrnmodVo trnmodVo = transactionHelpService.getTransactionStoreSet().getTrnmodVo();
        WfmmodVo wfmmodVo = trnmodVo.getTrnism().getWfmmod();
        //! adds for wfs a new row in list of service entries for given subid
        //! or replaces such an entry if it already exists
        // arguments tarday and tartim must be passed in user time zone
        // target timestamp is stored in TZSystem
        if (!MdaUtils.isEmpty(wfmmodVo.getWfs().getInr())) {
            if (sysmodService.sptIsExeLoaded(trnmodVo.getSptaut().getSta())) {
                //    if in recalculation: Do never create new workflow entries
                return;
            } else {
                if (!"PDXTSK".equalsIgnoreCase(SettleContext.getTransName())) {
                    SettleExceptionUtils.sysDump("AddWfe: attempt to add workflow service entry after creation of wfs");
                }
            }
        }
        if (MdaUtils.compareTo(tartim, 24) >= 0) {
            tartim = new BigDecimal("23.59");
        }
        Date tardaytim = Dates.dateTimeMake(tarday, tartim);
        //3中case：1.都没找到（可能是集合是0个元素，也可能是真没找到）  2.找到Wfssub是空进行替换 3. 找到指定insub的wfssub进行替换
        int useidx = getIdx(wfmmodVo, insub);
        Wfe wfe =  new Wfe();
        wfe.setWfsinr(" ");  // will be filled in Create
        wfe.setWfssub(insub);
        wfe.setSrv(insrv);
        wfe.setSta("W");
        wfe.setRtycnt(0);
        wfe.setTardattim(tardaytim);
        wfe.setDattim(NULLDATETIME);
        wfe.setOpndur(0);
        wfe.setWaidur(0);
        wfe.setRetdur(0);
        wfe.setHdldur(0);
        wfe.setInterftxt(interfacetxt);
        if("FIN".equals(wfe.getSrv())){
            wfe.setSta("O");
        }
        if (useidx == -1) {
            int gridcnt = wfmmodVo.getWfe().size();
            for (int runidx = 0; runidx < gridcnt; runidx++) { // search free entry in WFE list
                if (MdaUtils.isEmpty(wfmmodVo.getWfe().get(runidx).getWfssub())) {
                    useidx = runidx;
                    break;
                }
            }
        }
        if (useidx == -1) {
            wfmmodVo.getWfe().add(wfe);
        } else {
            BeanUtils.copyProperties(wfe, wfmmodVo.getWfe().get(useidx));
        }
    }


    /**
     * 检索iniName文件所有条目（必须指定文件扩展名）
     * 以文本块形式保存流中
     * 修改指定的wfe相关属性
     *
     * @param insub
     * @param insrv
     * @param tarday
     * @param tartim
     */
    public void wfeAddYTZ(String insub, String insrv, Date tarday, BigDecimal tartim) {
        TrnmodVo trnmodVo = transactionHelpService.getTransactionStoreSet().getTrnmodVo();
        WfmmodVo wfmmodVo = trnmodVo.getTrnism().getWfmmod();
        //! adds for wfs a new row in list of service entries for given subid
        //! or replaces such an entry if it already exists
        // arguments tarday and tartim must be passed in user time zone
        // target timestamp is stored in TZSystem
        if (!MdaUtils.isEmpty(wfmmodVo.getWfs().getInr())) {
            if (sysmodService.sptIsExeLoaded(trnmodVo.getSptaut().getSta())) {
                //    if in recalculation: Do never create new workflow entries
                return;
            } else {
                if (!"PDXTSK".equalsIgnoreCase(SettleContext.getTransName())) {
                    SettleExceptionUtils.sysDump("AddWfe: attempt to add workflow service entry after creation of wfs");
                }
            }
        }
        if (MdaUtils.compareTo(tartim, 24) >= 0) {
            tartim = new BigDecimal("23.59");
        }
        Date tardaytim = Dates.dateTimeMake(tarday, tartim);
        //3中case：1.都没找到（可能是集合是0个元素，也可能是真没找到）  2.找到Wfssub是空进行替换 3. 找到指定insub的wfssub进行替换
        int useidx = getIdx(wfmmodVo, insub);
        Wfe wfe =  new Wfe();
        wfe.setWfsinr(" ");  // will be filled in Create
        wfe.setWfssub(insub);
        wfe.setSrv(insrv);
        wfe.setSta("W");
        wfe.setRtycnt(0);
        wfe.setTardattim(tardaytim);
        wfe.setDattim(NULLDATETIME);
        wfe.setOpndur(0);
        wfe.setWaidur(0);
        wfe.setRetdur(0);
        wfe.setHdldur(0);
        if (useidx == -1) {
            int gridcnt = wfmmodVo.getWfe().size();
            for (int runidx = 0; runidx < gridcnt; runidx++) { // search free entry in WFE list
                if (MdaUtils.isEmpty(wfmmodVo.getWfe().get(runidx).getWfssub())) {
                    useidx = runidx;
                    break;
                }
            }
        }
        if (useidx == -1) {
            wfmmodVo.getWfe().add(wfe);
        } else {
            BeanUtils.copyProperties(wfe, wfmmodVo.getWfe().get(useidx));
        }
    }

    /**
     *   source:wfmmod.0062.script
     */
    public void wfeAddWithVarYPT(String insub,String insrv,Date tarday,BigDecimal tartim,String interfacetxt) {
        TrnmodVo trnmodVo = transactionHelpService.getTransactionStoreSet().getTrnmodVo();
        WfmmodVo wfmmodVo = trnmodVo.getTrnism().getWfmmod();
        //! adds for wfs a new row in list of service entries for given subid
        //! or replaces such an entry if it already exists
        // arguments tarday and tartim must be passed in user time zone
        // target timestamp is stored in TZSystem
        if (!MdaUtils.isEmpty(wfmmodVo.getWfs().getInr())) {
            if (sysmodService.sptIsExeLoaded(trnmodVo.getSptaut().getSta())) {
                //    if in recalculation: Do never create new workflow entries
                return;
            } else {
                if (!"PDXTSK".equalsIgnoreCase(SettleContext.getTransName())) {
                    SettleExceptionUtils.sysDump("AddWfe: attempt to add workflow service entry after creation of wfs");
                }
            }
        }
        if (MdaUtils.compareTo(tartim, 24) >= 0) {
            tartim = new BigDecimal("23.59");
        }
        Date tardaytim = Dates.dateTimeMake(tarday,tartim);
        // check for fitting Service-Entries.
        // Ignore errors when unable to insert the entries (238), as other processes
        // might already have inserted these entries.
        String uilBlk = NULLSTR;
        IStream uilStr = new StreamImpl();
        String uil = NULLSTR;
        int stmCnt = 0;
        if( MdaUtils.isEmpty(Codetables.getCodetableLabelOfTd(insrv,"SRVTXT","EN")) ) {
            // SysDump( "AddWfe: Undefined Service " + insrv + " included in workflow. Please create entry." )
            uilBlk = Strings.toUpper(Inis.getIniBlock("TDPARA.INI","Language","Language"));
            Streams.streamSet(uilStr,uilBlk);
            uil = "EN";
            if( Streams.streamSearch(uilStr,uil) == 0 ) {
                Streams.streamInsert(uilStr,0,uil);
            }
            uil = Strings.toUpper(Inis.getIniBlock("TDPARA.INI","SYSTEM","UIL"));
            if( Streams.streamSearch(uilStr,uil) == 0 ) {
                Streams.streamInsert(uilStr,0,uil);
            }
            uil = Strings.toUpper(Systems.getLang());
            if( Streams.streamSearch(uilStr,uil) == 0 ) {
                Streams.streamInsert(uilStr,0,uil);
            }
            stmCnt = Streams.streamCount(uilStr);
            for(int  uilIdx = 1;uilIdx <= stmCnt;uilIdx++) {
                uil = Strings.getLine(uilStr,uilIdx);
                //Codetables.setTblText(insrv,"SRVTXT",uil,"<" + insrv + "> autogen by WFMMOD.WfeAdd");
            }
        }
        int useidx = getIdx(wfmmodVo, insub);
        Wfe wfe =  new Wfe();
        wfe.setWfsinr(" ");  // will be filled in Create
        wfe.setWfssub(insub);
        wfe.setSrv(insrv);
        wfe.setSta("O");
        wfe.setRtycnt(0);
        wfe.setTardattim(tardaytim);
        wfe.setDattim(NULLDATETIME);
        wfe.setOpndur(0);
        wfe.setWaidur(0);
        wfe.setRetdur(0);
        wfe.setHdldur(0);
        wfe.setInterftxt( interfacetxt);
        if (useidx == -1) {
            int gridcnt = wfmmodVo.getWfe().size();
            for (int runidx = 0; runidx < gridcnt; runidx++) { // search free entry in WFE list
                if (MdaUtils.isEmpty(wfmmodVo.getWfe().get(runidx).getWfssub())) {
                    useidx = runidx;
                    break;
                }
            }
        }
        if (useidx == -1) {
            wfmmodVo.getWfe().add(wfe);
        } else {
            BeanUtils.copyProperties(wfe, wfmmodVo.getWfe().get(useidx));
        }
    }

    /**
     * 返回下标insub的wfe
     *
     * @param wfmmodVo
     * @param insub
     * @return
     */
    public int getIdx(WfmmodVo wfmmodVo, String insub) {
        int idx = -1;
        if (!CollectionUtil.isEmpty(wfmmodVo.getWfe())) {
            for (Wfe item : wfmmodVo.getWfe()) {
                if (MdaUtils.compareTo(item.getWfssub(), insub) == 0) {
                    idx = wfmmodVo.getWfe().indexOf(item);
                    break;
                }
            }
        }
        return idx;
    }

    /**
     * 数据库插入一条wfs
     * 循环wfe，查询bchkeyinr
     *
     * @param wfmmodVo
     * @param argtyp
     * @param arginr
     * @param argnam
     */
    public void create(WfmmodVo wfmmodVo, String argtyp, String arginr, String argnam) {
        wfmmodVo.getWfs().setObjtyp(argtyp);
        wfmmodVo.getWfs().setObjinr(arginr);
        //WFS\\OBJNAM = argnam
        //wfs中objnam字段短
        wfmmodVo.getWfs().setObjnam(argnam);
        wfmmodVo.getWfs().setInr(counterService.dbCounterFormat("WFS"));
        wfmmodVo.getWfs().setEtyextkey(SettleContext.getUserEty().getExtkey());
//        Platform.sdbInsert(wfs);
        wfsMapper.insert(wfmmodVo.getWfs());
        int gridcnt = wfmmodVo.getWfe().size();
        String bchkey = NULLSTR;
        String bchkeyinr = NULLSTR;
        String okflag = NULLSTR;
        //针对LMT做下wfe排序
        sortWfe(wfmmodVo.getWfe());
        gridcnt=wfmmodVo.getWfe().size();
        for(int  idx = 0;idx < gridcnt;idx++)
        {
            Wfe wfe = wfmmodVo.getWfe().get(idx);
            wfe.setWfsinr( wfmmodVo.getWfs().getInr());
            bchkey = sysmodService.getProcessBranch();
            Argument<String> bchkeyinrBox = new Argument<String>();
            sysmodService.getxxdfields ( "BCH", "INR", bchkey, "Y", bchkeyinrBox );

            bchkeyinr = bchkeyinrBox.value;

            wfe.setBchkeyinr( bchkeyinr);
            okflag = staCalcEntry(wfmmodVo, wfe.getSrv() );
            if( MdaUtils.isEmpty(okflag) ) {
                if(!"LMA".equals(wfe.getSrv())) {
                    wfe.setSta("W");
                }
            }
            if( MdaUtils.compareTo(wfe.getSrv(),"SWT") == 0 ) {
                // WFE( $idx )\\STA = "W"
            }
            if( MdaUtils.compareTo(wfe.getSrv(),"CMT") == 0 ) {
                wfe.setSta( "W");
            }
            if( MdaUtils.compareTo(wfe.getSrv(),"BNG") == 0 ) {
                wfe.setSta( "W");
            }
            if( MdaUtils.compareTo(wfe.getSrv(),"AGE") == 0 ) {
                wfe.setSta( "W");
            }
            if( MdaUtils.compareTo(wfe.getSrv(),"FMT") == 0 ) {
                wfe.setSta( "W");
            }
            if( MdaUtils.compareTo(wfe.getSrv(),"ECI") == 0 ) {
                wfe.setSta( "W");
            }
            if( MdaUtils.compareTo(wfe.getSrv(),"EJS") == 0 ) {
                wfe.setSta( "O");
            }
            if( ! MdaUtils.isEmpty(wfe.getWfssub()) ) {
                wfe.setDattim( Dates.now());
                wfeMapper.insert(wfmmodVo.getWfe().get(idx));
            }
        }

    }

    public void sortWfe(List<Wfe> wfeList){
        if(wfeList==null)
            return;
        List<Wfe> newWfeList= new ArrayList<>();
        List<String> srvList= wfeList.stream().map(Wfe::getSrv).collect(Collectors.toList());

       //LMA-ACT-LMT-
        List<String> specialList=new ArrayList<>();//复核服务
        List<String> finalList=new ArrayList<>();//后台服务
        specialList=codetableService.getTblKeyListBySrtAsc("FRTSRV");
        finalList=codetableService.getTblKeyListBySrtAsc("BGSRV");
/*        specialList.add("LMA");
        specialList.add("ACT");
        specialList.add("LMO");
        specialList.add("LMT");
        specialList.add("AXQ");
        specialList.add("WZH");
        specialList.add("OFD");
        specialList.add("OFE");
        specialList.add("OFF");
        //-------------------------------------------------
        finalList.add("YPT");//云平台国内证通知

        finalList.add("YTZ");
        finalList.add("PDP");
        finalList.add("ERX");
        finalList.add("SWT");
        finalList.add("PDA");
        finalList.add("EJS");
        finalList.add("AXD");
        finalList.add("MFT");
        finalList.add("MFV");
        finalList.add("BDL");
        finalList.add("BDC");
        finalList.add("BDX");
        finalList.add("BDY");
        finalList.add("FIN");
        finalList.add("BDL");
        finalList.add("FIN");*/
        for(int i=0;i<specialList.size();i++){
            if(srvList.contains(specialList.get(i))) {
                newWfeList.add(getWfeBySrv(specialList.get(i), wfeList));
            }
        }
        //添加非WFE记录
        for(int i=0;i<wfeList.size();i++) {
            Wfe wfe = wfeList.get(i);
            if (!specialList.contains(wfe.getSrv()) && !finalList.contains(wfe.getSrv())) {
                newWfeList.add(wfe);
            }
        }
       //PDP-SWT-FIN
        for(int i=0;i<finalList.size();i++){
            if(srvList.contains(finalList.get(i))) {
                newWfeList.add(getWfeBySrv(finalList.get(i),wfeList));
            }
        }
        Collections.copy(wfeList,newWfeList);
    }

    public Wfe getWfeBySrv(String srv,List<Wfe> wfeList){
        Wfe wfe=new Wfe();
        for(int i=0;i<wfeList.size();i++){
            if(srv.equals(wfeList.get(i).getSrv())){
                BeanUtils.copyProperties(wfeList.get(i),wfe);
                break;
            }
        }
        return wfe;
    }

    /**
     * 返回DSC在wfe的Sta中的位置
     * 额外检查
     * @param argSRV
     * @param
     * @return
     */
    public String staCalcEntry(WfmmodVo wfmmodVo,String argSRV) {
        String preLst = getPreLst( wfmmodVo,argSRV );
        int gridcnt = wfmmodVo.getWfe().size();
        String preSrv = "";
        boolean wFEFound = false;
        for(int  sroidx = 1;sroidx <= Strings.len(preLst);sroidx+=6){
            preSrv = Strings.mid(preLst,sroidx,6);
            wFEFound = false;
            for(int  searchidx = 0;searchidx < gridcnt;searchidx++) {
                if( Objects.equals(wfmmodVo.getWfe().get(searchidx).getSrv(),preSrv.trim())) {
                    if( Strings.pos("DSC",wfmmodVo.getWfe().get(searchidx).getSta()) == 0 ){
                        return "NO";
                    }
                    wFEFound = true;
                    searchidx = gridcnt;
                }
            }
            if(!wFEFound) {
                preLst = preLst + getPreLst(wfmmodVo, preSrv );
            }
        }
        return "";
    }


    /**
     * 查询SRO表（lst没有赋值?????）
     * @param wfmmodVo
     * @param srvnam
     * @return
     */
    public String getPreLst(WfmmodVo wfmmodVo, String srvnam) {
        String lst = "";
        String presrv = "";
        String sucsrv = "";
        if( MdaUtils.isEmpty(wfmmodVo.getSro()) ) {
            List<Sro> sroList =sroMapper.selectAllOrderBySucsrv("");
            for(int i=0;i<sroList.size();i++){
                sucsrv =sroList.get(i).getSucsrv();
                presrv =sroList.get(i).getPresrv();
                if( MdaUtils.compareTo(sucsrv,Strings.mid(lst,1,6)) != 0 ){
                    if(!StringUtils.isEmpty(lst) ) {
                        wfmmodVo.getSro().add(lst);
                    }
                    lst = Strings.mid(sucsrv,1,6);
                }
                lst = lst + Strings.mid(presrv,1,6);
            }
            if(!MdaUtils.isEmpty(lst)) {
                wfmmodVo.getSro().add(lst);
            }
        }
        for (String prelst : wfmmodVo.getSro()) {
            if (prelst.startsWith(srvnam)) {
                return Strings.mid(prelst,7);
            }
        }
        return "";


//        String lst = "";
//        String presrv = "";
//        String sucsrv = "";
//        if( MdaUtils.isEmpty(wfmmodVo.getSro())) {
//           List<Sro> sroList = sroMapper.selectAllOrderBySucsrv("");
//           for(int i=0;i<sroList.size();i++){
//                sucsrv =sroList.get(i).getSucsrv();
//                presrv =sroList.get(i).getPresrv();
//                String compairStr=lst.split(",")==null ?"":lst.split(",")[0];
//                if( !Objects.equals(sucsrv,compairStr)) {
//                    if(!MdaUtils.isEmpty(lst) ) {
//                        wfmmodVo.getSro().add(lst);
//                    }
//                    lst = sucsrv;
//                }
//                lst = lst +presrv;
//            }
//            if(!MdaUtils.isEmpty(lst) ) {
//                wfmmodVo.getSro().add(lst);
//            }
//        }
//        for (String prelst : wfmmodVo.getSro()) {
//            if (prelst.startsWith(srvnam)) {
//                return prelst.substring(prelst.indexOf(",")+1);
//            }
//        }
//        return "";
    }

    public boolean existCreFin(List<Wfe> wfeg) {
        return wfeg.stream().anyMatch(e->(MdaUtils.compareTo(e.getWfssub(),"CREFIN") == 0 || MdaUtils.compareTo(e.getWfssub(),"ZTS") == 0));
    }

    /**
     *   source:wfmmod.0017.script
     */
    public void wfeRemove(String insub, WfmmodVo wfmmod) {
        //! removes WFE entry from workflow
        //! (only valid before call to Create, i.e. not for workflows already stored)
        int useidx = getIdx(wfmmod,insub);
        if(useidx >= 0) {
            wfmmod.getWfe().get(useidx).setWfssub("");
        }
    }
}
