
package kd.fi.cas.business.opservice.helper;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.MetadataServiceHelper;
import kd.bos.servicehelper.botp.BFTrackerServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.fi.cas.business.journal.AgentPayBookJournalBuilder;
import kd.fi.cas.business.journal.JournalServiceAdapter;
import kd.fi.cas.business.pojo.PayEntryStatusInfo;
import kd.fi.cas.business.pojo.PayStatusInfo;
import kd.fi.cas.business.pojo.PayStatusInfo.PayMode;
import kd.fi.cas.business.writeback.AgentWriteBackConsumer;
import kd.fi.cas.business.writeback.WriteBackTaskHelper;
import kd.fi.cas.business.writeback.consts.WriteBackOperateEnum;
import kd.fi.cas.enums.BeBillStatusEnum;
import kd.fi.cas.enums.BillStatusEnum;
import kd.fi.cas.helper.CasHelper;
import kd.fi.cas.util.EmptyUtil;

public class AgentPayServiceHelperEx {
    public AgentPayServiceHelperEx() {
    }

    public static void updateAcutalPayInfo(PayStatusInfo payStatus, DynamicObject agentPayBill) {
        updateAgentPayBill(payStatus, agentPayBill);
        if (BillStatusEnum.PAY.getValue().equals(agentPayBill.getString("billstatus"))) {
           // if (isNeedBookJournal(agentPayBill)) {
                bookJournal(agentPayBill);
           // }

            SaveServiceHelper.save(new DynamicObject[]{agentPayBill});
            if (payStatus.isNeedWriteback()) {
                writeBack(agentPayBill);
            }
        } else {
            SaveServiceHelper.save(new DynamicObject[]{agentPayBill});
        }

    }

    public static void updateAgentPayBill(PayStatusInfo payStatus, DynamicObject agentPayBill) {
        if (PayMode.OffLine == payStatus.getPayMode()) {
            agentPayBill.set("cashier", Long.valueOf(RequestContext.get().getUserId()));
            updateBillPayInfo(agentPayBill, payStatus.getEntryStatus());
        } else {
            BeBillStatusEnum bankAgentStatus = payStatus.getBankBillStatus();
            if (BeBillStatusEnum.TS == bankAgentStatus || BeBillStatusEnum.TF == bankAgentStatus) {
                if (PayMode.BeSync == payStatus.getPayMode()) {
                    agentPayBill.set("batchseqid", payStatus.getBatchSeq());
                }

                updateBillPayInfo(agentPayBill, payStatus.getEntryStatus());
            }

            agentPayBill.set("bankagentpaystatus", bankAgentStatus.getValue());
            if (PayMode.BeSync == payStatus.getPayMode()) {
                agentPayBill.set("bankcheckflag", CasHelper.subFlag(payStatus.getBankCheckFlag()));
                agentPayBill.set("bankcheckflag_tag", payStatus.getBankCheckFlag());
            }
        }

    }

    private static void updateBillPayInfo(DynamicObject agentPayBill, List<PayEntryStatusInfo> entryStatus) {
        agentPayBill.set("billstatus", BillStatusEnum.PAY.getValue());
        agentPayBill.set("paytime", new Date());
        BigDecimal actPayAmount = BigDecimal.ZERO;
        int actPayCount = 0;
        DynamicObjectCollection agentEntry = agentPayBill.getDynamicObjectCollection("entry");
        Iterator var5 = agentEntry.iterator();

        while(var5.hasNext()) {
            DynamicObject agentRow = (DynamicObject)var5.next();
            Iterator var7 = entryStatus.iterator();

            while(var7.hasNext()) {
                PayEntryStatusInfo rowStatus = (PayEntryStatusInfo)var7.next();
                if (rowStatus.getEntryId() == agentRow.getLong("id")) {
                    //agentRow.set("e_issuccess", rowStatus.isSuccess());
                    //agentRow.set("bankreturnmsg", rowStatus.getBankReturnMsg());
                    agentRow.set("e_isrefund", !agentRow.getBoolean("e_issuccess"));
                }
            }

            if (agentRow.getBoolean("e_issuccess")) {
                actPayAmount = actPayAmount.add(agentRow.getBigDecimal("e_amount"));
                ++actPayCount;
            }
        }

        agentPayBill.set("actpayamount", actPayAmount);
        agentPayBill.set("actcount", actPayCount);
    }

    public static boolean isNeedBookJournal(DynamicObject agentPayBill) {
        DynamicObject settleType = (DynamicObject)agentPayBill.get("settletype");
        if (EmptyUtil.isNoEmpty(settleType)) {
            String settlementtype = settleType.getString("settlementtype");
            Set<String> draftTypeList = (Set)Stream.of("2", "5", "6").collect(Collectors.toSet());
            if (draftTypeList.contains(settlementtype)) {
                return false;
            }
        }

        DynamicObjectCollection entry = agentPayBill.getDynamicObjectCollection("entry");
        Iterator var6 = entry.iterator();

        DynamicObject row;
        do {
            if (!var6.hasNext()) {
                return false;
            }

            row = (DynamicObject)var6.next();
        } while(!row.getBoolean("e_issuccess") && !row.getBoolean("e_isrefund"));

        return true;
    }

    public static void bookJournal(DynamicObject agentPayBill) {
        JournalServiceAdapter journalServiceAdapter = new JournalServiceAdapter();
        journalServiceAdapter.validateBook(new AgentPayBookJournalBuilder(), agentPayBill);
        journalServiceAdapter.book(agentPayBill);
    }

    private static void writeBack(DynamicObject agentPayBill) {
        String source = agentPayBill.getString("source");
        if ("BOTP".equals(source)) {
            WriteBackTaskHelper.addRealtimeTask(agentPayBill, agentPayBill.getString("sourcebilltype"), WriteBackOperateEnum.PAY, AgentWriteBackConsumer.class);
        }
    }

    public static List<String> getSelector() {
        List<String> lst = new ArrayList(59);
        lst.add("billstatus");
        lst.add("org");
        lst.add("bizdate");
        lst.add("payeracctbank");
        lst.add("currency");
        lst.add("basecurrency");
        lst.add("payamount");
        lst.add("localamt");
        lst.add("exchangerate");
        lst.add("expectdealtime");
        lst.add("settletype");
        lst.add("count");
        lst.add("billtype");
        lst.add("org");
        lst.add("sourcebillnumber");
        lst.add("accountcash");
        lst.add("openorg");
        lst.add("modifier");
        lst.add("ispersonpay");
        lst.add("payeetype");
        lst.add("e_encryptamount");
        lst.add("e_amount");
        lst.add("paymentterm");
        lst.add("paymentfps");
        lst.add("paymentareacode");
        lst.add("informrecemail");
        lst.add("inforpayment");
        lst.add("payeename");
        lst.add("payeeacctbank");
        lst.add("payeebankname");
        lst.add("e_amount");
        lst.add("e_encryptamount");
        lst.add("payeebanknumber");
        lst.add("e_localamt");
        lst.add("e_encryptlocalamt");
        lst.add("sourcebillid");
        lst.add("isencryption");
        lst.add("e_encryptamount");
        lst.add("e_amount");
        lst.add("paymentchannel");
        lst.add("isdiffcur");
        lst.add("dpcurrency");
        lst.add("dpexchangerate");
        lst.add("dpamt");
        lst.add("dplocalamt");
        lst.add("lossamt");
        lst.add("agreedrate");
        lst.add("iscrosspay");
        lst.add("contractno");
        lst.add("crosstrantype");
        lst.add("paycountry");
        lst.add("reccountry");
        lst.add("payerbank");
        lst.add("recswiftcode");
        lst.add("paymenttype");
        lst.add("description");
        lst.add("delegorg");
        lst.add("feepayer");
        lst.add("feeactbank");
        lst.add("feecurrency");
        lst.add("fee");
        lst.add("actpayamount");
        lst.add("exratedate");
        lst.add("exratetable");
        lst.add("payquotation");
        lst.add("dppayquotation");
        lst.add("agreedquotation");
        lst.add("basecurrency");
        lst.add("e_dpamt");
        lst.add("e_dplocalamt");
        lst.add("matchflag");
        lst.add("matchamount");
        lst.add("unmatchamount");
        lst.add("entrymatchamount");
        lst.add("entryunmatchamount");
        lst.add("entrymatchflag");
        lst.add("businesstype");
        return lst;
    }

    public static List<String> getSelectors() {
        List<String> selectors = new ArrayList(70);
        selectors.add("billno");
        selectors.add("billstatus");
        selectors.add("source");
        selectors.add("payeracctbank");
        selectors.add("accountcash");
        selectors.add("org");
        selectors.add("bizdate");
        selectors.add("description");
        selectors.add("currency");
        selectors.add("exchangerate");
        selectors.add("settletype");
        selectors.add("settletnumber");
        selectors.add("localamt");
        selectors.add("payamount");
        selectors.add("sourcebilltype");
        selectors.add("count");
        selectors.add("paytime");
        selectors.add("actpayamount");
        selectors.add("actcount");
        selectors.add("cashier");
        selectors.add("iscommitbe");
        selectors.add("bankcheckflag");
        selectors.add("bankcheckflag_tag");
        selectors.add("delegorg");
        selectors.add("payeename");
        selectors.add("e_amount");
        selectors.add("e_localamt");
        selectors.add("e_encryptamount");
        selectors.add("e_encryptlocalamt");
        selectors.add("e_fundflowitem");
        selectors.add("e_issuccess");
        selectors.add("bankreturnmsg");
        selectors.add("settletnumber");
        selectors.add("batchseqid");
        selectors.add("bankagentpaystatus");
        selectors.add("e_isrefund");
        selectors.add("billtype");
        selectors.add("isencryption");
        selectors.add("sourcebillid");
        selectors.add("sourceentryid");
        selectors.add("paymentchannel");
        selectors.add("isdiffcur");
        selectors.add("dpcurrency");
        selectors.add("dpamt");
        selectors.add("iscrosspay");
        selectors.add("dplocalamt");
        selectors.add("agreedrate");
        selectors.add("dpexchangerate");
        selectors.add("fee");
        selectors.add("feecurrency");
        selectors.add("feeactbank");
        selectors.add("e_bankcheckflag");
        selectors.add("lossamt");
        selectors.add("isagencypersonpay");
        selectors.add("basecurrency");
        selectors.add("e_dpamt");
        selectors.add("e_dplocalamt");
        selectors.add("e_fee");
        selectors.add("payeebankname");
        selectors.add("payeeacctbank");
        selectors.add("e_fee");
        selectors.add("feepayer");
        selectors.add("acttradedate");
        selectors.add("createtime");
        selectors.add("e_paytime");
        selectors.add("payquotation");
        selectors.add("dppayquotation");
        selectors.add("agreedquotation");
        return selectors;
    }

    public static DynamicObject[] getSourceAgentBillList(List<Long> agentIdList) {
        List<Long> agentPaySourceBillIdList = new ArrayList(10);
        Map<String, HashSet<Long>> srcBills = BFTrackerServiceHelper.findSourceBills("cas_agentpaybill", (Long[])agentIdList.toArray(new Long[0]));
        Set<Map.Entry<String, HashSet<Long>>> entrySet = srcBills.entrySet();
        Iterator var4 = entrySet.iterator();

        while(var4.hasNext()) {
            Map.Entry<String, HashSet<Long>> entry = (Map.Entry)var4.next();
            String key = (String)entry.getKey();
            HashSet<Long> value = (HashSet)entry.getValue();
            if ("cas_agentpaybill".equals(key)) {
                agentPaySourceBillIdList.addAll(value);
            }
        }

        DynamicObject[] agentPaySourceBills = BusinessDataServiceHelper.load(agentPaySourceBillIdList.toArray(new Object[0]), MetadataServiceHelper.getDataEntityType("cas_agentpaybill"));
        return agentPaySourceBills;
    }
}
