package com.brilliance.isc.swift.objmtconvert.model.busvalidator.mt1xx;

import com.brilliance.isc.swift.objmtconvert.model.AbsMTValidator;
import com.brilliance.isc.swift.objmtconvert.result.MtResult;
import com.brilliance.isc.swift.objmtconvert.util.Language;
import com.prowidesoftware.swift.model.field.*;
import com.prowidesoftware.swift.model.mt.mt1xx.MT101;
import java.util.*;
import static com.brilliance.isc.swift.objmtconvert.util.Constans.ZERO;

/**

 * @author liusheng
 */
public class MT101Validator extends AbsMTValidator {

    public MT101Validator(String mtstr, MtResult mtResult) {super(mtstr, mtResult);}

    @Override
    public void bussinessValidator() {
       // MtResult mtResult = getMtResult();
        MT101 mt101 = (MT101) getAbstractMT();

        List<Field> fields = mt101.getFields();
        HashMap fieldMap = new HashMap();
        List<List<String>> list23E = new ArrayList<>();

        // 按照序列拆分
        String sequence = "A";
        int circle = 0;
        for (Field field: fields){
            List<String> list = new ArrayList<>();
            if(field.getName().equals("21")) {
                list = new ArrayList<>();
                sequence = "B";
                circle++;
            }

            if(field.getName().equals("32B")) {
                list23E.add(list);
            }

            if (sequence.equals("A"))
                fieldMap.put(field.getName()+"SequenceA",field.getValue());
            else if(!field.getName().equals("23E")) {
                fieldMap.put(field.getName() + "SequenceB" + circle, field.getValue());
            }else{
                list.add(field.getValue());
            }

        }


        boolean contain = false;
        //C1
        //If an exchange rate is given in field 36, the corresponding forex deal must be referenced in field 21F (Error code(s): D54).
        int i = circle;
        while(ZERO < i) {
            if(fieldMap.containsKey("36SequenceB"+i) && !fieldMap.containsKey("21FSequenceB"+i))

                //mtResult.addDescription("【MT101】如果字段36中给出了汇率，则必须在字段21F中引用相应的外汇交易,请检查!");
                mtResult.addDescription(Language.getLanguage("MT101_C1","【MT101】"));
            i--;
        }

        //C2
        //In each occurrence of sequence B, if field 33B is present and 'amount' in field 32B is not equal to zero, then field 36 must be present, otherwise field 36 is not allowed (Error code(s): D60).
        i = circle;
        while(ZERO < i) {
            // 在序列B 每次循环存在33B 32B
            if(fieldMap.containsKey("33BSequenceB"+i) && fieldMap.containsKey("32BSequenceB"+i)){
                // 32B金额不为零 且 36不存在
                if (!fieldMap.get("32BSequenceB"+i).equals("0") && !fieldMap.containsKey("36SequenceB"+i))
                    //mtResult.addDescription("【MT101】在序列B的每次出现中，如果字段33B存在且字段32B中的“金额”不等于零，则字段36必须存在,请检查!");
                mtResult.addDescription(Language.getLanguage("MT101_C2","【MT101】"));
            }
            // 在序列B 每次循环不存在33B 存在32B 因为32B必填
            else {
                if(fieldMap.containsKey("36SequenceB"+i))
                    //mtResult.addDescription("【MT101】在序列B的每次出现中，如果字段33B不存在 或者 字段32B中的“金额”不等于零，不允许字段36,请检查!");
                    mtResult.addDescription(Language.getLanguage("MT101_C2","【MT101】"));
            }

            i--;
        }

        //C3
        //If there is only one debit account, the ordering customer must be identified in field 50a (option F, G or H) in sequence A. Conversely, if multiple debit accounts are used, they must be identified for every transaction in field 50a (option F, G or H) of sequence B.
        //Consequently, field 50a (option F, G or H), must be present in either sequence A (index 5) or in each occurrence of sequence B (index 15), but must never be present in both sequences, nor be absent from both sequences (Error code(s): D61).
        // 如果在SequenceA , 就不能在SequenceB.    而且在序列A,只能有一个，   序列B,有多个
        contain = fieldMap.containsKey("50a2SequenceA");
        i = circle;
        int B = 0;
        while(ZERO < i) {

            if(contain){
                // 在A又在B
                if(fieldMap.containsKey("50a2SequenceB"+i))
                    //mtResult.addDescription("【MT101】如果只有一个借方账户，则必须在序列A的字段50a（选项F、G或H）中标识订购客户。相反，如果使用多个借方账户的话，则必须为序列B的字段50b（选项F，G或H。,请检查!");
                    mtResult.addDescription(Language.getLanguage("MT101_C3","【MT101】"));
            }else{
                // 不在A 在B
                if(fieldMap.containsKey("50a2SequenceB"+i))
                   B++;
            }
            i--;
        }
        // 在B又只有一个
        if (1 == B){
            //mtResult.addDescription("【MT101】如果只有一个借方账户，则必须在序列A的字段50a（选项F、G或H）中标识订购客户。相反，如果使用多个借方账户的话，则必须为序列B的字段50b（选项F，G或H。,请检查!");
            mtResult.addDescription(Language.getLanguage("MT101_C3","【MT101】"));
        }

        //C4
        //Field 50a (option C or L), may be present in either sequence A (index 4), or in one or more occurrences of sequence B (index 14), but must not be present in both sequences A and B (Error code(s): D62).
        // 如果在SequenceA , 就不能在SequenceB.    而且在序列A,只能有一个，   序列B,有多个
        contain = fieldMap.containsKey("50aSequenceA");
        i = circle;
        B = 0;
        while(ZERO < i) {

            if(contain){
                // 在A又在B
                if(fieldMap.containsKey("50aSequenceB"+i))
                    //mtResult.addDescription("【MT101】如果只有一个借方账户，则必须在序列A的字段50a（选项F、G或H）中标识订购客户。相反，如果使用多个借方账户的话，则必须为序列B的字段50b（选项F，G或H。,请检查!");
                    mtResult.addDescription(Language.getLanguage("MT101_C4","【MT101】"));
            }else{
                // 不在A 在B
                if(fieldMap.containsKey("50aSequenceB"+i))
                    B++;
            }
            i--;
        }
        // 在B又只有一个
        if (1 == B){
            //mtResult.addDescription("【MT101】如果只有一个借方账户，则必须在序列A的字段50a（选项F、G或H）中标识订购客户。相反，如果使用多个借方账户的话，则必须为序列B的字段50b（选项F，G或H。,请检查!");
            mtResult.addDescription(Language.getLanguage("MT101_C4","【MT101】"));
        }

        //C5
        //If field 33B is present in sequence B, its currency code must be different from the currency code in field 32B in the same occurrence of sequence B (Error code(s): D68).
        // 币种不同
//        List<MT101.SequenceB> sequenceBList = mt101.getSequenceBList();
//        Tag[] tagsByName = sequenceBList.get(0).getTagsByName("23E");
        i = circle;
        while(ZERO < i) {
            // 332B必填 不用判断空
            if(fieldMap.containsKey("33BSequenceB"+i)){
                // 判断币种
                if (fieldMap.get("33BSequenceB"+i).toString().substring(0,3).equals(fieldMap.get("32BSequenceB"+i).toString().substring(0,3)))
                    //mtResult.addDescription("【MT101】如果序列B中存在字段33B，则其货币代码必须与序列B中相同出现的字段32B中的货币代码不同,请检查!");
                    mtResult.addDescription(Language.getLanguage("MT101_C5","【MT101】"));
            }
            i--;
        }

        //C6
        //Field 52a may be present in either sequence A or in one or more occurrences of sequence B, but must not be present in both sequences (Error code(s): D64).
        contain = fieldMap.containsKey("52aSequenceA");
        i = circle;
        while(ZERO < i) {
            if(fieldMap.containsKey("52aSequenceB"+i) && contain)
                    //mtResult.addDescription("【MT101】字段52a可以出现在序列A或序列B的一次或多次出现中，但不能同时出现在两个序列中,请检查!");
                mtResult.addDescription(Language.getLanguage("MT101_C6","【MT101】"));
            i--;
        }

        //C7
        //If field 56a is present, field 57a must also be present (Error code(s): D65).
        i = circle;
        while(ZERO < i) {
            if(fieldMap.containsKey("56aSequenceB"+i) && !fieldMap.containsKey("57aSequenceB"+i))
                //mtResult.addDescription("【MT101】如果字段56a存在，则字段57a也必须存在,请检查!");
                mtResult.addDescription(Language.getLanguage("MT101_C7","【MT101】"));
            i--;
        }

        //C8
        //If field 21R is present in sequence A, then in each occurrence of sequence B, the currency code in fields 32B must be the same (Error code(s): D98).
        i = circle;
        while(ZERO < i) {
            if(fieldMap.containsKey("21RSequenceA") && fieldMap.containsKey("32BSequenceB"+i) && fieldMap.containsKey("32BSequenceB"+(i-1))){
                String a  = fieldMap.get("32BSequenceB"+i).toString().substring(0,3);
                String b = fieldMap.get("32BSequenceB"+(i-1)).toString().substring(0,3);
                if (!fieldMap.get("32BSequenceB"+i).toString().substring(0,3).equals(fieldMap.get("32BSequenceB"+(i-1)).toString().substring(0,3)))
                    //mtResult.addDescription("【MT101】如果序列A中存在字段21R，则在序列B的每次出现中，字段32B中的货币代码必须相同,请检查!");
                    mtResult.addDescription(Language.getLanguage("MT101_C8","【MT101】"));
            }
            i--;
        }

        //C9
        //In each occurrence of sequence B, the presence of fields 33B and 21F is dependent on the presence and value of fields 32B and 23E as follows (Error code(s): E54).
        i = circle;
//        List<MT101.SequenceB> sequenceBList = mt101.getSequenceBList();
//        Tag[] tagsByName = sequenceBList.get(0).getTagsByName("32B");
//
//        tagsByName[0].getValue().equals(0);

        while(ZERO < i) {
            if(fieldMap.get("32BSequenceB"+i).equals("0")){

                List<String> list = list23E.get(i-1);
                boolean equi = false;
                for(String value : list){
                    equi = value.equals("EQUI");
                }

                if (equi) {
                    if(!fieldMap.containsKey("33BSequenceB"))
                        //mtResult.addDescription("【MT101】在序列B的每次出现中，字段33B和21F的存在取决于字段32B和23E的存在和值,请检查!");
                        mtResult.addDescription(Language.getLanguage("MT101_C9","【MT101】"));
                }else{
                    if(fieldMap.containsKey("33BSequenceB"))
                        //mtResult.addDescription("【MT101】在序列B的每次出现中，字段33B和21F的存在取决于字段32B和23E的存在和值,请检查!");
                        mtResult.addDescription(Language.getLanguage("MT101_C9","【MT101】"));
                    if(fieldMap.containsKey("21FSequenceB"))
                        //mtResult.addDescription("【MT101】在序列B的每次出现中，字段33B和21F的存在取决于字段32B和23E的存在和值,请检查!");
                        mtResult.addDescription(Language.getLanguage("MT101_C9","【MT101】"));
                }
            }
            i--;
        }

       // return mtResult;
    }
}
