
package kd.fi.cas.opplugin;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.AddValidatorsEventArgs;
import kd.bos.entity.plugin.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.AfterOperationArgs;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.exception.KDBizException;
import kd.bos.extplugin.PluginProxy;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.MetadataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.fi.cas.business.helper.VoucherCheckHepler;
import kd.fi.cas.business.journal.book.jourrnalbook.book.BookJournalService;
import kd.fi.cas.business.opservice.helper.AgentPayServiceHelperEx;
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.BillStatusEnum;
import kd.fi.cas.helper.AgentPayBillHelper;
import kd.fi.cas.helper.CasHelper;
import kd.fi.cas.helper.OperateServiceHelper;
import kd.fi.cas.helper.QuotationHelper;
import kd.fi.cas.helper.RefundHelper;
import kd.fi.cas.helper.SystemParameterHelper;
import kd.fi.cas.pojo.book.BookCheckResult;
import kd.fi.cas.util.EmptyUtil;
import kd.fi.cas.util.StringUtils;
import kd.fi.cas.validator.AgentPayBillIsFreezeValidator;
import kd.fi.cas.validator.AgentPayBillWriteValidator;
import kd.fi.cas.validator.AgentPayValidator;
import kd.sdk.fi.cas.extpoint.recbill.IAgentPayField;

public class AgentPayPayOPEx extends AbstractOperationServicePlugIn {
    public AgentPayPayOPEx() {
    }

    public void onPreparePropertys(PreparePropertysEventArgs e) {
        super.onPreparePropertys(e);
        List<String> fieldKeys = e.getFieldKeys();
        fieldKeys.addAll(AgentPayServiceHelperEx.getSelectors());
    }

    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        super.beginOperationTransaction(e);
        DynamicObject[] agentPayBillDts = e.getDataEntities();
        List<Long> agentIdList = (List)Arrays.stream(agentPayBillDts).map((o) -> {
            return o.getLong("id");
        }).collect(Collectors.toList());
        Set<String> sourceBillNoList = (Set)Arrays.stream(agentPayBillDts).filter((o) -> {
            return !StringUtils.isBlank(o.getString("sourcebillnumber"));
        }).map((o) -> {
            return o.getString("sourcebillnumber");
        }).collect(Collectors.toSet());
        List<DynamicObject> agentPayBillList = new ArrayList(10);
        DynamicObject[] agentPaySourceBillList = AgentPayServiceHelperEx.getSourceAgentBillList(agentIdList);
        List<Long> agentErrSourceBillIdList = (List)Arrays.stream(agentPaySourceBillList).filter((o) -> {
            return !"repay".equals(o.getString("sourcebilltype"));
        }).map((o) -> {
            return o.getLong("id");
        }).collect(Collectors.toList());
        DynamicObject[] var8 = agentPaySourceBillList;
        int var9 = agentPaySourceBillList.length;

        for(int var10 = 0; var10 < var9; ++var10) {
            DynamicObject agentPaySourceBill = var8[var10];
            if (sourceBillNoList.contains(agentPaySourceBill.getString("billno"))) {
                agentPayBillList.add(agentPaySourceBill);
            }
        }

        Set<Long> orgIds = (Set)((Stream)Arrays.stream(agentPayBillDts).parallel()).filter((d1) -> {
            DynamicObject d = (DynamicObject)d1;
            return CasHelper.isNotEmpty(d.getDynamicObject("org")) && CasHelper.isNotEmpty(d.getDynamicObject("org").getLong("id"));
        }).map((d1) -> {
            DynamicObject d = (DynamicObject)d1;
            return d.getDynamicObject("org").getLong("id");
        }).collect(Collectors.toSet());
        Map<String, Object> pushMap = SystemParameterHelper.getSystemParamsByOrgIds(new ArrayList(orgIds), "cs088");
        List<DynamicObject> pushBills = new ArrayList();
        DynamicObject[] agentPaySourceBills = BusinessDataServiceHelper.load(agentIdList.toArray(), EntityMetadataCache.getDataEntityType("cas_agentpaybill"));
        agentPayBillList.addAll(Arrays.asList(agentPaySourceBills));
        DynamicObject[] var12 = e.getDataEntities();
        int var13 = var12.length;

        for(int var14 = 0; var14 < var13; ++var14) {
            DynamicObject info = var12[var14];
            if (AgentPayBillHelper.isDelegPush(info)) {
                String orgId = info.getDynamicObject("org").getString("id");
                boolean isPush = EmptyUtil.isEmpty(orgId) ? false : (Boolean)pushMap.get(orgId);
                if (isPush) {
                    pushBills.add(info);
                }
            }
        }

        Map<String, String> params = this.getOption().getVariables();
        Iterator var43 = agentPayBillList.iterator();

        while(var43.hasNext()) {
            DynamicObject info = (DynamicObject)var43.next();
            DynamicObject basecurrency;
            if (info.getBoolean("isdiffcur")) {
                Object agreeRate = params.get("agreedrate");
                if (agreeRate != null) {
                    BigDecimal dpAmt = new BigDecimal((String)params.get("dpamt"));
                    BigDecimal fee = new BigDecimal((String)params.get("fee"));
                    info.set("dpamt", dpAmt);
                    info.set("agreedrate", agreeRate);
                    info.set("fee", fee);
                    BigDecimal dpExchangeRate = info.getBigDecimal("dpexchangerate");
                    basecurrency = info.getDynamicObject("basecurrency");
                    String dppayquotation = info.getString("dppayquotation");
                    String agreedquotation = info.getString("agreedquotation");
                    BigDecimal dpLocalAmt = QuotationHelper.callToCurrency(dpAmt, dpExchangeRate, dppayquotation, basecurrency.getInt("amtprecision"));
                    BigDecimal localAmt = info.getBigDecimal("localamt");
                    info.set("dplocalamt", dpLocalAmt);
                    info.set("lossamt", localAmt.subtract(dpLocalAmt));
                    BigDecimal payAmount = info.getBigDecimal("payamount");
                    BigDecimal agreedrate = info.getBigDecimal("agreedrate");
                    DynamicObject dpcurrency = info.getDynamicObject("dpcurrency");
                    BigDecimal sumDpamt = BigDecimal.ZERO;
                    BigDecimal sumDpLocalamt = BigDecimal.ZERO;
                    BigDecimal sumEFee = BigDecimal.ZERO;
                    DynamicObjectCollection entry = info.getDynamicObjectCollection("entry");

                    for(int i = 0; i < entry.size(); ++i) {
                        DynamicObject row = (DynamicObject)entry.get(i);
                        BigDecimal edpamt = BigDecimal.ZERO;
                        BigDecimal edplocalamt = BigDecimal.ZERO;
                        BigDecimal efee = BigDecimal.ZERO;
                        if (i == entry.size() - 1) {
                            edpamt = dpAmt.subtract(sumDpamt);
                            edplocalamt = dpLocalAmt.subtract(sumDpLocalamt);
                            efee = fee.subtract(sumEFee);
                        } else {
                            String encryptAmt = row.getString("e_encryptamount");
                            BigDecimal eamount = AgentPayBillHelper.decodeAmount(encryptAmt);
                            if (dpcurrency != null) {
                                edpamt = QuotationHelper.callToCurrency(eamount, agreedrate, agreedquotation, dpcurrency.getInt("amtprecision"));
                            } else {
                                edpamt = QuotationHelper.callToCurrency(eamount, agreedrate, agreedquotation, 10);
                            }

                            sumDpamt = sumDpamt.add(edpamt);
                            edplocalamt = QuotationHelper.callToCurrency(edpamt, dpExchangeRate, dppayquotation, basecurrency.getInt("amtprecision"));
                            sumDpLocalamt = sumDpLocalamt.add(edplocalamt);
                            if (dpcurrency != null) {
                                efee = fee.multiply(eamount.divide(payAmount, 10, 4)).setScale(dpcurrency.getInt("amtprecision"), 4);
                            }

                            sumEFee = sumEFee.add(efee);
                        }

                        row.set("e_dpamt", edpamt);
                        row.set("e_dplocalamt", edplocalamt);
                        row.set("e_fee", efee);
                        row.set("e_paytime", new Date());
                    }
                }
            }

            PayStatusInfo payStatus = new PayStatusInfo();
            payStatus.setId((Long)info.getPkValue());
            payStatus.setPayMode(PayMode.OffLine);
            List<PayEntryStatusInfo> entryStatus = new ArrayList();
            DynamicObjectCollection entry = info.getDynamicObjectCollection("entry");
            Iterator var57 = entry.iterator();

            while(var57.hasNext()) {
                basecurrency = (DynamicObject)var57.next();
                entryStatus.add(new PayEntryStatusInfo((Long)basecurrency.getPkValue(), true, (String)null));
            }

            payStatus.setEntryStatus(entryStatus);
            AgentPayBillHelper.decodeAmount(info);
            AgentPayServiceHelperEx.updateAgentPayBill(payStatus, info);
            this.setAgentPayField(info);
            boolean isencryption = info.getBoolean("isencryption");
            Iterator var59 = entry.iterator();

            while(var59.hasNext()) {
                DynamicObject r = (DynamicObject)var59.next();
                if (isencryption) {
                    r.set("e_amount", (Object)null);
                    r.set("e_localamt", (Object)null);
                }
            }
        }

        this.batchUpdatePayDate(agentPayBillList, orgIds);
        RefundHelper.setSomeRefundAmtFields((DynamicObject[])agentPayBillList.toArray(new DynamicObject[0]), "cas_agentpaybill");
        SaveServiceHelper.save((DynamicObject[])agentPayBillList.toArray(new DynamicObject[0]));
        List<DynamicObject> agentPayBillBookList = (List)agentPayBillList.stream().filter((o) -> {
            return !agentErrSourceBillIdList.contains(o.getLong("id"));
        }).collect(Collectors.toList());
        List<BookCheckResult> results = BookJournalService.getInstance().doBook(agentPayBillBookList);
        if (results != null && results.size() > 0) {
            StringBuilder strInfos = new StringBuilder();
            results.forEach((o) -> {
                strInfos.append(o.getBizBillNo()).append(o.getInfo()).append("\r\n");
            });
            throw new KDBizException(strInfos.toString());
        } else {
            Iterator var49 = agentPayBillList.iterator();

            while(var49.hasNext()) {
                DynamicObject agentPayBill = (DynamicObject)var49.next();
                String source = agentPayBill.getString("source");
                if ("BOTP".equals(source)) {
                    WriteBackTaskHelper.addRealtimeTask(agentPayBill, agentPayBill.getString("sourcebilltype"), WriteBackOperateEnum.PAY, AgentWriteBackConsumer.class);
                }
            }

            if (pushBills.size() > 0) {
                OperateServiceHelper.execOperate("genotherarbill", "cas_agentpaybill", (DynamicObject[])pushBills.toArray(new DynamicObject[0]), OperateOption.create());
            }

        }
    }

    public void onAddValidators(AddValidatorsEventArgs e) {
        super.onAddValidators(e);
        e.addValidator(new AgentPayValidator());
        e.addValidator(new AgentPayBillWriteValidator(WriteBackOperateEnum.PAYVALIDATE));
        e.getValidators().add(new AgentPayBillIsFreezeValidator());
    }

    public void afterExecuteOperationTransaction(AfterOperationArgs e) {
        super.afterExecuteOperationTransaction(e);
        List<DynamicObject> checkBills = new ArrayList();
        List<Object> agentIdList = (List)Arrays.stream(e.getDataEntities()).map((o) -> {
            return o.getPkValue();
        }).collect(Collectors.toList());
        DynamicObject[] agentDts = BusinessDataServiceHelper.load(agentIdList.toArray(new Object[0]), MetadataServiceHelper.getDataEntityType("cas_agentpaybill"));
        Map<Object, DynamicObject> agentDtsMap = (Map)Arrays.stream(agentDts).collect(Collectors.toMap((o) -> {
            return o.getPkValue();
        }, Function.identity()));
        DynamicObject[] var6 = e.getDataEntities();
        int var7 = var6.length;

        for(int var8 = 0; var8 < var7; ++var8) {
            DynamicObject info = var6[var8];
            DynamicObject bill = (DynamicObject)agentDtsMap.get(info.getPkValue());
            if (null != bill && BillStatusEnum.AUDIT.getValue().equals(bill.getString("billstatus"))) {
                checkBills.add(info);
            }
        }

        if (EmptyUtil.isNoEmpty(checkBills)) {
            VoucherCheckHepler.batchDoVoucherCheck(checkBills);
        }

        OperateServiceHelper.execOperate("synctrigger", "cas_agentpaybill", e.getDataEntities(), OperateOption.create());
    }

    private void batchUpdatePayDate(List<DynamicObject> agentPayBills, Set<Long> orgIds) {
        Map<String, Object> payDateMap = SystemParameterHelper.getSystemParamsByOrgIds(new ArrayList(orgIds), "selectpaydate");
        Iterator var5 = agentPayBills.iterator();

        while(var5.hasNext()) {
            DynamicObject agentPayBill = (DynamicObject)var5.next();
            DynamicObjectCollection agentEntry = agentPayBill.getDynamicObjectCollection("entry");
            String orgId = agentPayBill.getDynamicObject("org").getString("id");
            Object value = payDateMap.get(orgId);
            Date payDate;
            switch (value == null ? "sysdate" : value.toString()) {
                case "expectdate":
                    payDate = agentPayBill.getDate("expectdealtime");
                    break;
                case "bizdate":
                    payDate = agentPayBill.getDate("bizdate");
                    break;
                case "auditdate":
                    payDate = agentPayBill.getDate("auditdate");
                    break;
                case "sysdate":
                    payDate = new Date();
                    break;
                default:
                    payDate = null;
            }

            Iterator var11 = agentEntry.iterator();

            while(var11.hasNext()) {
                DynamicObject agentRow = (DynamicObject)var11.next();
                if (agentRow.getBoolean("e_issuccess")) {
                    agentRow.set("e_paytime", payDate);
                }
            }
            agentPayBill.set("paytime", payDate);

        }

    }

    private void setAgentPayField(DynamicObject info) {
        PluginProxy<IAgentPayField> pluginProxy = PluginProxy.create(IAgentPayField.class, "fi.cas.agentpay.IAgentPayField");
        pluginProxy.callReplace((proxy) -> {
            proxy.setAgentPayField(info);
            return null;
        });
    }
}
