package com.brilliance.isc.common.component;

import com.brilliance.isc.bo.Bch;
import com.brilliance.isc.bo.Trm;
import com.brilliance.isc.common.api.bch.service.BchService;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.mda.dao.TrmMapper;
import com.brilliance.mda.runtime.mda.impl.Argument;
import com.brilliance.mda.runtime.mda.util.Decimals;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import com.brilliance.mda.runtime.mda.util.Numerics;
import com.brilliance.mda.runtime.mda.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class ActmodComponent {

    @Autowired
    private CodetableService codetableService;

    @Autowired
    private BchService bchService;

    @Autowired
    private TrmMapper trmMapper;

    /**
     *   source:actmod.0016.script
     */
    public boolean checkAccount(String account,String term_id,String branch,String cur,String manFLG, Argument<String> err) {
        //---------------------------------------------
        //   新一代账号检核函数
        //   返回：True    正确
        //         False   错误   Err  错误原因
        //   参数：Account 账号
        //         Term_id 科目代码
        //         CUR     记账币别
        //         Branch  机构
        //         ManFlg  手工输入帐码（M）
        //---------------------------------------------
        int length = Strings.len(account);
        //#DG 20101227 新需求，新账号前面增加"NRA"
        /**
         if $length == 20 and Mid( Account, 1, 3 ) == "NRA" then
         **/
        //------ZMQZMQ---------------------------------------
        //---自贸区主账号处理--
        String vcur = "";
        if( MdaUtils.compareTo(Strings.mid(account,1,2),"FT") == 0
                || MdaUtils.compareTo(Strings.mid(account,1,2),"EF") == 0
                || MdaUtils.compareTo(Strings.mid(account,1,3),"ZMQ") == 0 ) {
            if( MdaUtils.compareTo(Strings.mid(account,1,2),"FT") == 0
                    || MdaUtils.compareTo(Strings.mid(account,1,2),"EF") == 0) {
                return  true;
            } else {
                //------ZMQZMQ---------------------------------------
                return  checkZMQAccount(Strings.mid(account,4),term_id,cur,err);
            }
        } else {
            if( length == 20 && MdaUtils.compareTo(Strings.mid(account,1,3), "NRA") == 0) {
                return  checkAccount(Strings.mid(account,4,17),term_id,branch,cur,manFLG,err);
            } else {
                if( length != 17 && length != 21 ) {
                    err.value = "账号位数错误";
                    return  false;
                }
                /**
                 //505新需求
                 //同一客户下不能维护相同的账号
                 $ptyinr = GetContent( "\\\\recpan\\\\actgrp\\\\holpty\\\\inr" )
                 $error = ErrorCode
                 if not IsEmpty( $ptyinr ) then
                 $actsql = "select count(*) from act where extkey = '" + Account + "' and  holptyinr = '" + $ptyinr + "'"
                 $cnt = 0
                 DBExecuteSQL( $actsql )
                 DBFetchFields( "", $cnt )
                 DBCloseCursor
                 if $cnt > 0 then
                 Err = "该客户已经存在此账号,不能添加!           "
                 = FALSE
                 endif
                 endif
                 **/
                //---------------------------------------------
                //if IsEmpty( term_id )  then
                if( MdaUtils.isEmpty(term_id) && ( MdaUtils.compareTo(SettleContext.getTransName(),"BRTSET") != 0 && MdaUtils.compareTo(SettleContext.getTransName(),"BRTSET1") != 0 && MdaUtils.compareTo(SettleContext.getTransName(),"GITSET") != 0 && MdaUtils.compareTo(SettleContext.getTransName(),"MCTFEE") != 0 ) ) {
                    err.value = "科目代码为空";
                    return  false;
                }
                Argument<String> notypBox = new Argument<String>();
                Argument<String> repflgBox = new Argument<String>();
                Argument<String> vterm_idBox = new Argument<String>();
                Argument<String> term_namBox = new Argument<String>();
                Argument<String> seqNoBox = new Argument<String>();
                Argument<String> prtTypBox = new Argument<String>();
                Argument<String> namBox = new Argument<String>();
                getActTypField(term_id,notypBox,repflgBox,vterm_idBox,term_namBox,seqNoBox,prtTypBox,namBox);

                String repflg = repflgBox.value;
                String vterm_id = vterm_idBox.value;
                /**
                 if $notyp == "O" then // 旧帐号的检核
                 goto CheckOldAccount
                 else
                 if $notyp == "N" then // 新账号的检核
                 goto CheckNewAccount
                 else  // 根据位数判断新旧帐号
                 **/
                boolean gotoNewAccount = false;
                if( length == 21 ) {
                    gotoNewAccount = false ; // goto CheckOldAccount
                } else {
                    gotoNewAccount = true ; //  goto CheckNewAccount
                }
                /**
                 endif
                 endif
                 **/
                //  label CheckNewAccount
                if(gotoNewAccount){
                    if( length == 21 ) {
                        err.value = "科目：" + vterm_id + " 为新帐号类型，长度必须为17位";
                        return  false;
                    }
                    /**
                     $term_act = "0" + Mid( Account, 7, 4 )
                     if $repflg <> "C" or Mid( term_id, 1, 2 ) == "AS" then // 不是客户帐
                     if ManFLG == "M" and $term_act <> $term_id and ( GetFramename <> "BRTSET" and GetFramename <> "GITSET" and GetFramename <> "MCTFEE" ) then
                     Err = "账号的对应位 " + $term_act + " 与科目 " + $term_id + " 不符          "
                     = FALSE
                     endif
                     endif
                     **/
                    if( MdaUtils.compareTo(repflg,"R") == 0 && ! MdaUtils.isEmpty(branch) && MdaUtils.compareTo(getBranch(branch), Strings.mid(account,1,4)) != 0 ) {
                        err.value = "账号中的机构位(1-4)与记账机构 " + branch + " 不符";
                        return  false;
                    }
                    vcur = Strings.mid(account,5,2);
                    // goto checkEnd
                }
                // label CheckOldAccount
                if(!gotoNewAccount){
                    if( length == 17 ) {
                        err.value = "科目：" + vterm_id + " 为旧帐号类型，长度必须为21位";
                        return  false;
                    }
                    /**
                     $term_act = Mid( Account, 11, 5 )
                     //if ManFLG = "M" and $term_act <> $term_id then
                     if ManFLG == "M" and $term_act <> $term_id and ( GetFramename <> "BRTSET" and GetFramename <> "GITSET" and GetFramename <> "MCTFEE" ) then
                     Err = "账号的对应位 " + $term_act + " 与科目 " + $term_id + " 不符        "
                     = FALSE
                     endif
                     **/
                    if( MdaUtils.compareTo(repflg,"R") == 0 && ! MdaUtils.isEmpty(branch) && MdaUtils.compareTo(branch,Strings.mid(account,1,8)) != 0 ) {
                        err.value = "账号中的机构位(1-8)与记账机构 " + branch + " 不符     ";
                        return  false;
                    }
                    vcur = Strings.mid(account,9,2);
                    // goto checkEnd
                }
                //label checkEnd
                //检查账号的币别位
                if( ! MdaUtils.isEmpty(cur) ) {
                    if( MdaUtils.compareTo(vcur,Strings.mid(codetableService.getTblLabel(cur,"CURKEY"),1,2)) != 0 ) {
                        err.value = "记账币种 " + cur + " 与账号币种不符";
                        return  false;
                    }
                }
                //检查客户帐的校验位
                if( MdaUtils.compareTo(repflg,"C") == 0 && MdaUtils.compareTo(Strings.mid(term_id,1,2),"AS") != 0 ) {
                    if(!chkActMac(account)) {
                        err.value = "客户帐号合法性校验错误";
                        //    Err = "MAC[" + GetActMac( Account ) + "]," + Err
                        return  false;
                    }
                }
                return  true;
            }
        }

    }

    /**
     *   source:actmod.0024.script
     */
    public boolean checkZMQAccount(String account, String term_id, String cur, Argument<String> err) {
        //---------------------------------------------
        //   新一代账号检核函数
        //   返回：True    正确
        //         False   错误   Err  错误原因
        //   参数：Account 账号
        //         Term_id 科目代码
        //         CUR     记账币别
        //         Branch  机构
        //         ManFlg  手工输入帐码（M）
        //---------------------------------------------
        int length = Strings.len(account);
        //------ZMQZMQ---------------------------------------
        if( length != 17 && length != 21 ) {
            err.value = "账号位数错误";
            return false;
        }
        String vcur = Strings.mid(account,5,2);
        // return ; //   ####   goto checkEnd
        //    ####    label checkEnd
        if( MdaUtils.isEmpty(term_id) && ( MdaUtils.compareTo(SettleContext.getTransName(),"BRTSET") != 0 && MdaUtils.compareTo(SettleContext.getTransName(),"BRTSET1") != 0 && MdaUtils.compareTo(SettleContext.getTransName(),"GITSET") != 0 && MdaUtils.compareTo(SettleContext.getTransName(),"MCTFEE") != 0 ) ) {
            err.value = "科目代码为空";
            return  false;
        }
        /**
         if not IsEmpty( branch ) and GetBranch( branch ) <> Mid( Account, 1, 4 ) then
         Err = "账号中的机构位(1-4)与记账机构 " + branch + " 不符          "
         = FALSE
         endif
         **/
        //检查账号的币别位
        if( ! MdaUtils.isEmpty(cur) ) {
            if( MdaUtils.compareTo(vcur,Strings.mid(codetableService.getTblLabel(cur,"CURKEY"),1,2)) != 0 ) {
                err.value = "记账币种 " + cur + " 与账号币种不符       ";
                return  false;
            }
        }
        /*String vbranch = Strings.mid(account,1,4);
        Map<String, Object> dyncMap = new HashMap<>();
        String sql = "select count(*) from sysbch where YNGYJG='" + vbranch + "'";
        dyncMap.put("sql", sql);
        int count = publicMapper.dyncCount(dyncMap);
        if (count == 0) {
            err.value = "机构不存在";
            return  false;
        }*/
        return  true;
    }

    /**
     *   source:actmod.0011.script
     */
    public void getActTypField(String tbltyp,Argument<String> nottyp,Argument<String> repTyp,Argument<String> term_id,Argument<String> term_nam,Argument<String> seqNo,Argument<String> prttyp,Argument<String> nam) {
        //-------------------------------------------
        //    获取账户信息的函数
        //    TBLTYP  CodeTable ACTMIX 的TBL
        //    NOTTYP  返回新旧帐号类型   N 新帐号 O旧帐号 M 新旧帐号并存
        //    RepTyp  账号中机构位的生成规则  R  用当前机构替换  G  使用EXTACT中的机构    C 客户类账号
        //    term_id  科目代码   账号中的科目号位  5位  新帐号需要去掉前1位   08开头的仅仅取头3位
        //    term_nam 科目号     账号对应的科目号，打印传票时使用
        //    SEQNo   顺序号
        //    PRTTYP  传票打印类型
        //    NAM     该科目的名称
        //-------------------------------------------
        nottyp.value = "";
        repTyp.value = "";
        term_id.value = "";
        seqNo.value = "";
        prttyp.value = "";
        nam.value = "";
        String txt = codetableService.getTblLabel(tbltyp,"ACTMIX");
        if(!MdaUtils.isEmpty(txt)) {
            nottyp.value = Strings.mid(txt,1,1);
            repTyp.value = Strings.mid(txt,2,1);
            term_id.value = Strings.mid(txt,4,5);
            term_nam.value = Strings.mid(txt,10,6);
            seqNo.value = Strings.mid(txt,17,1);
            prttyp.value = Strings.mid(txt,19,2);
            nam.value = Strings.mid(txt,22,-1);
        }
    }

    /**
     *   source:actmod.0010.script
     */
    public String getBranch(String branch) {
        //-----获取核心的记账机构代码－－－－－－－－－－－－－
        Bch bch = bchService.getDirectAccBch(branch);
        if (bch != null) {
            return bch.getBranch();
        }
        return "";
    }

    /**
     *   source:actmod.0017.script
     */
    public boolean chkActMac(String account) {
        //----------------------------
        //现有账号校验均不合法，屏蔽
        //= TRUE
        //----------------------------
        String e0 = "000000000000000000000";
        String fullAct = Strings.mid(e0,1,21 - Strings.len(account)) + account;
        int ss = 0;
        String switchVar = "";
        int k = 0;
        String j = "";
        int factor = 0;
        for(int  i = 1; i <= 19;i++) {
            switchVar = Strings.mid(fullAct,i,1);
            switch( switchVar ) {
                case "0":
                    k = 0;
                    break;
                case "1":
                    k = 1;
                    break;
                case "2":
                    k = 2;
                    break;
                case "3":
                    k = 3;
                    break;
                case "4":
                    k = 4;
                    break;
                case "5":
                    k = 5;
                    break;
                case "6":
                    k = 6;
                    break;
                case "7":
                    k = 7;
                    break;
                case "8":
                    k = 8;
                    break;
                case "9":
                    k = 9;
                    break;
            }
            j = MdaUtils.toString(i);
            switch( j ) {
                case "1":
                    factor = 1;
                    break;
                case "2":
                    factor = 3;
                    break;
                case "3":
                    factor = 5;
                    break;
                case "4":
                    factor = 7;
                    break;
                case "5":
                    factor = 11;
                    break;
                case "6":
                    factor = 13;
                    break;
                case "7":
                    factor = 17;
                    break;
                case "8":
                    factor = 19;
                    break;
                case "9":
                    factor = 23;
                    break;
                case "10":
                    factor = 29;
                    break;
                case "11":
                    factor = 31;
                    break;
                case "12":
                    factor = 37;
                    break;
                case "13":
                    factor = 53;
                    break;
                case "14":
                    factor = 61;
                    break;
                case "15":
                    factor = 67;
                    break;
                case "16":
                    factor = 89;
                    break;
                case "17":
                    factor = 91;
                    break;
                case "18":
                    factor = 73;
                    break;
                case "19":
                    factor = 79;
                    break;
            }
            ss = factor * k + ss;
        }
        int a = Numerics.floor(Decimals.div(ss,97));
        int returnVar = ss - a * 97;
        String result = "";
        if( returnVar - 10 >= 0 ) {
            result = MdaUtils.toString(returnVar);
        } else {
            result = "0" + MdaUtils.toString(returnVar);
        }
        if( MdaUtils.compareTo(result,Strings.mid(fullAct,20,2)) == 0 ) {
            return  true;
        } else {
            return  false;
        }
    }

    /**
     *   source:actmod.0018.script
     */
    public List<Trm> getActTermCode(String termType) {
        //----新一代需求---------------
        //   根据选择的账户类型返回设置可以选择的科目代码
        //   TYPE    帐户类型  可以是SetDSP或Account Type
        //   返回   可以设置的CodeValue
        //-----------------------------
        String res = getdsp(termType);
        List<Trm> trmList = trmMapper.getTrmListByTrmType(res);
        return trmList;
    }

    /**
     *   source:actmod.0021.script
     */
    public String getdsp(String type) {
        //----新一代需求---------------
        //   根据选择的账户类型返回账户类型代码
        //
        //  -----------------------------
        String dsp = Strings.mid(type,1,2);
        if("PA".equals(dsp)) {
            dsp = "SP";
        }
        return dsp;
    }
}
