package com.yem.wm.es.contactbook.op;

import com.yem.wm.es.contactbook.validator.ContactBookSaveValidator;
import com.yem.wm.es.shippingdetails.util.PaymentControlUtil;
import com.yem.wm.utils.YEM;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.AddValidatorsEventArgs;
import kd.bos.entity.plugin.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.BeforeOperationArgs;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.AttachmentServiceHelper;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

import static com.yem.wm.es.contractamtlist.util.FunUtil.*;
import static com.yem.wm.es.shippingdetails.util.PaymentControlUtil.calcIOUAmount;
import static com.yem.wm.fm.gathering.dynamic.GatheringClaimFormPlugin.getPercentagePeriod;

/**
 * @Classname ContactBookSaveOp
 * @Description TODO
 * @Date 2023/12/21 15:05
 * @Created by ZZSLL
 */

public class ContactBookSaveOp extends AbstractOperationServicePlugIn
{

    private static final Logger logger = LoggerFactory.getLogger(ContactBookSaveOp.class);

    @Override
    public void onPreparePropertys(PreparePropertysEventArgs e)
    {
        super.onPreparePropertys(e);
        List<String> keys = e.getFieldKeys();
        keys.addAll(this.billEntityType.getAllFields().keySet());
    }

    @Override
    public void onAddValidators(AddValidatorsEventArgs e)
    {
        super.onAddValidators(e);
        e.addValidator(new ContactBookSaveValidator());

    }



    @Override
    public void beforeExecuteOperationTransaction(BeforeOperationArgs e)
    {
        super.beforeExecuteOperationTransaction(e);

        DynamicObject[] dataEntities = e.getDataEntities();
        String operationKey = e.getOperationKey();
        if ("save".equals(operationKey)) {
            for (DynamicObject dataEntity : dataEntities) {
//                String billno = dataEntity.getString("billno");

//                QFilter qFilter = new QFilter("billno", QCP.equals, billno);
//                DynamicObject[] load = BusinessDataServiceHelper.load("yem_es_storagetrans", "id, billno", qFilter.toArray());

//                for (DynamicObject dynamicObject : load) {

//                    AttachmentServiceHelper.remove("yem_es_storagetrans", dynamicObject.getLong("id"));
//
//                    uploadAttachmentPanel(dataEntity, dynamicObject);
//                }

                updatePaymentControlStatus(dataEntity);
            }

            // 反写关联发货联系数量
//            for (DynamicObject dataEntity : dataEntities) {
//
//                String billno = dataEntity.getString("yem_storagetransno");
//                DynamicObject yem_producttype = dataEntity.getDynamicObject("yem_producttype");
//                if (yem_producttype == null) throw new KDBizException("产品类型不能为空");
//                long producttype = yem_producttype.getLong("id");
//                DynamicObjectCollection collection = dataEntity.getDynamicObjectCollection("yem_es_materialinfo");
//                List<Long> book = new ArrayList<>();
//                for (DynamicObject dynamicObject : collection) {
//                    book.add(dynamicObject.getLong("yem_sourceentryid"));
//                }
//                DynamicObject single = BusinessDataServiceHelper.loadSingle("yem_es_storagetrans", new QFilter[]{new QFilter("billno", QCP.equals, billno)});
//                if (single == null) continue;
//                DynamicObjectCollection materialinfo = single.getDynamicObjectCollection("yem_es_materialinfo");
//                List<Long> origin = new ArrayList<>();
//                for (DynamicObject dynamicObject : materialinfo) {
//                    DynamicObject products = dynamicObject.getDynamicObject("yem_products");
//                    if (products == null) continue;
//                    if (producttype == products.getLong("id")) {
//                        origin.add((Long) dynamicObject.getPkValue());
//                    }
//                }
//                for (DynamicObject object : collection) {
//                    for (DynamicObject materialinfoEntry : materialinfo) {
//                        Long pkValue = (Long) materialinfoEntry.getPkValue();
//                        if (object.getLong("yem_sourceentryid") == pkValue) {
//                            materialinfoEntry.set("yem_contactbookqty", object.getBigDecimal("yem_qty"));
//                        }
//                    }
//                }
//                List<Long> result = new ArrayList<>(CollectionUtils.removeAll(origin, book));
//                for (DynamicObject dynamicObject : materialinfo) {
//                    for (Long longId : result) {
//                        if (longId.equals(dynamicObject.getPkValue())) {
//                            dynamicObject.set("yem_contactbookqty", 0);
//                        }
//                    }
//                }
//                single.set("yem_secdeliverytime", dataEntity.get("yem_secdeliverytime"));
//                SaveServiceHelper.update(single);
//            }
        }
    }

    public static void uploadAttachmentPanel(DynamicObject from, DynamicObject to) {
        List<Map<String, Object>> attachments = AttachmentServiceHelper
                .getAttachmentsByExport(from.getDataEntityType().getName(), from.getLong("id"));
        List<Map<String, Object>> toattachments = AttachmentServiceHelper
                .getAttachmentsByExport(to.getDynamicObjectType().getName(), to.getLong("id"));
        List<String> toname = toattachments.stream().map(x -> (String) x.get("name")).collect(Collectors.toList());
        for (Map<String, Object> map : attachments) {
            String fileName = (String) map.get("name");
            if (fileName != null && !toname.contains(fileName)) {// 判断源单的附件是否在目标单上存在
                DynamicObject newAtt = BusinessDataServiceHelper.newDynamicObject("bos_attachment");
                Long id = ORM.create().genLongId("bos_attachment");
                newAtt.set("id", id);
                newAtt.set("fnumber", "upload_" + id);
                newAtt.set("FBillType", to.getDataEntityType().getName());
                newAtt.set("FInterID", to.getString("id"));
                newAtt.set("FModifyTime", map.get("lastModified"));
                newAtt.set("fcreatetime", map.get("createdate"));
                newAtt.set("FaliasFileName", fileName);
                newAtt.set("FAttachmentName", fileName);
                newAtt.set("FFileId", map.get("url"));
                newAtt.set("FExtName", map.get("type"));
                newAtt.set("FATTACHMENTSIZE", map.get("size"));
                newAtt.set("FCREATEMEN", map.get("creator"));
                newAtt.set("fattachmentpanel", map.get("fattachmentpanel"));
                newAtt.set("fdescription", map.get("description"));
                SaveServiceHelper.save(new DynamicObject[] { newAtt });
            }
        }
    }

    /**
     *
     * @param dataEntity
     */
    private void updatePaymentControlStatus(DynamicObject dataEntity) {
        DynamicObjectCollection c = dataEntity.getDynamicObjectCollection("yem_es_materialinfo");
        Map<String, String> map = new HashMap<>();

        for (DynamicObject d : c) {
            String shipmentnumbers_m = d.getString("yem_shipmentnumbers_m");
            String contractnumbers_m = d.getString("yem_contractnumbers_m");
            if (YEM.isNotEmpty(shipmentnumbers_m) && YEM.isNotEmpty(contractnumbers_m)) {
                map.put(contractnumbers_m, shipmentnumbers_m);
            }
        }

//        List<Boolean> proc = new ArrayList<>();
//        List<Boolean> ship = new ArrayList<>();
        List<Boolean> pre = new ArrayList<>();
        List<Boolean> last = new ArrayList<>();
        int iou = 0;
        StringBuilder debugMsg = new StringBuilder();
        for (Map.Entry<String, String> entry : map.entrySet()) {

//            boolean isProcClaimFinish = false;//下单预收金额是否认领完成
//            boolean isShipClaimFinish = false;//本次发运 发运预收认领是否完成
//            boolean isPreClaimFinish = false;
//            boolean isFinalClaimFinish = false;//尾款是否认领完成

            String salesorder_no = entry.getKey();
            String ship_no = entry.getValue();

            logger.info("发货联系书保存： 合同号：{} , 发运明细号：{}", salesorder_no, ship_no);
            debugMsg.append(String.format("发货联系书保存： 合同号：%s , 发运明细号：%s", salesorder_no, ship_no)).append("\n");
            DynamicObject saleOrder = BusinessDataServiceHelper.loadSingle("yem_es_salesorder", new QFilter[]{new QFilter("billno", "=", salesorder_no)});
            DynamicObject shipDetail = BusinessDataServiceHelper.loadSingle("yem_shippingdetails", new QFilter[]{new QFilter("billno", "=", ship_no)});

            DynamicObject[] shipBills = getShipBills(saleOrder, shipDetail, "A");//出运
            DynamicObject[] payBills = getPayBills(saleOrder, shipDetail, "B");//收款单

            BigDecimal procPreRapRate = PaymentControlUtil.getProcPreRapRate(saleOrder);//生产预收汇比例
            BigDecimal shipPreRapRate = PaymentControlUtil.getShipPreRapRate(saleOrder);//发货预收汇比例
            BigDecimal lastRate = getPercentagePeriod(shipPreRapRate, procPreRapRate);//尾款比例
            logger.info("尾款比例：{}", lastRate);
            logger.info("下单预收比例：{}，发货预收比例：{}，尾款比例：{}", procPreRapRate, shipPreRapRate, lastRate);
            debugMsg.append(String.format("下单预收比例：%s，发货预收比例：：%s，尾款比例：%s", procPreRapRate, shipPreRapRate, lastRate)).append("\n");
            BigDecimal procClaimAnt = PaymentControlUtil.getPreCollection(saleOrder, payBills, "D");//下单已认领金额
            BigDecimal offeramount = saleOrder.getBigDecimal("yem_offeramount");//合同价格条款金额
            BigDecimal advancePayment = PaymentControlUtil.getAdvancePayment(offeramount, procPreRapRate).setScale(2, RoundingMode.HALF_UP);

            logger.info("下单已认领金额：{}， 下单预收金额：{}", procClaimAnt, advancePayment);
            debugMsg.append(String.format("下单已认领金额：%s， 下单预收金额：%s", procClaimAnt, advancePayment)).append("\n");
            // 下单已认领金额 >= 下单预收金额
//            if (advancePayment.compareTo(BigDecimal.ZERO) > 0 && procClaimAnt.compareTo(advancePayment) >= 0) {
//                isProcClaimFinish = true;
//            } else if (advancePayment.compareTo(BigDecimal.ZERO) == 0) {
//                isProcClaimFinish = true;
//            }
            BigDecimal thisAmt = getThisAmt(shipDetail);//本次出运/发货金额
            // 本次发运已认领金额 >= 发运预收金额
            BigDecimal thisShipIOUAmt = PaymentControlUtil.getAdvancePayment(thisAmt, shipPreRapRate).setScale(2, RoundingMode.HALF_UP);//本次发运欠款金额，本次发运应认领金额
            BigDecimal shipClaimAmt = PaymentControlUtil.getAmountClaimed(new DynamicObject[]{shipDetail}, "E");//本次发运已认领金额
            logger.info("发运已认领金额：{}，发运预收金额：{}", shipClaimAmt, thisShipIOUAmt);
            debugMsg.append(String.format("发运已认领金额：%s， 发运预收金额：%s", shipClaimAmt, thisShipIOUAmt)).append("\n");
//            if (thisShipIOUAmt.compareTo(BigDecimal.ZERO) > 0 && shipClaimAmt.compareTo(thisShipIOUAmt) >= 0) {
//                isShipClaimFinish = true;
//            } else if (thisShipIOUAmt.compareTo(BigDecimal.ZERO) == 0) {
//                isShipClaimFinish = true;
//            }

            BigDecimal mergeAmtClaimed = shipClaimAmt.add(procClaimAnt);
            BigDecimal mergeAmtIOU = advancePayment.add(thisShipIOUAmt);

            if (mergeAmtIOU.compareTo(BigDecimal.ZERO) > 0) {
                if (mergeAmtClaimed.compareTo(mergeAmtIOU) >= 0) {
                    pre.add(true);
                } else {
                    pre.add(false);
                }
            }

            BigDecimal amount = shipDetail.getBigDecimal("yem_offeramount");//发运 价格条款金额
            BigDecimal periodrefundamt = lastRate.multiply(amount).setScale(2, RoundingMode.HALF_UP);//尾款 应收金额
            BigDecimal shipClaimAmt_periodrefund = PaymentControlUtil.getAmountClaimed(new DynamicObject[]{shipDetail}, "F");//本次发运已认领金额_尾款
            logger.info("尾款已认领金额：{}， 尾款应收金额：{}", shipClaimAmt_periodrefund, periodrefundamt);
            debugMsg.append(String.format("尾款已认领金额：%s， 尾款应收金额：%s", shipClaimAmt_periodrefund, periodrefundamt)).append("\n");
            // 尾款认领金额 >= 尾款 应收金额
            if (periodrefundamt.compareTo(BigDecimal.ZERO) > 0) {
                if (shipClaimAmt_periodrefund.compareTo(periodrefundamt) >= 0) {
                    last.add(true);
                } else {
                    last.add(false);
                }
            }

//            proc.add(isProcClaimFinish);
//            ship.add(isShipClaimFinish);
//            pre.add(isPreClaimFinish);
//            last.add(isFinalClaimFinish);

            DynamicObject[] tradeapps = BusinessDataServiceHelper.load("yem_im_tradeapp", "id, billno", new QFilter[]{new QFilter("yem_im_tradeapp_em.yem_shippingnumber", QCP.equals, shipDetail.getString("billno")), new QFilter("billstatus", QCP.equals, "C")});
            iou = iou + tradeapps.length;
            logger.info("欠条个数：{}", tradeapps.length);
            logger.info("欠条个数（累计）：{}", iou);
            debugMsg.append(String.format("欠条个数：%s", tradeapps.length)).append("\n");
            debugMsg.append(String.format("欠条个数（累计）：%s", iou)).append("\n");
            debugMsg.append("==========================").append("\n");
        }
        if (!pre.contains(false) && !last.contains(false)) {
            //全款完成
            dataEntity.set("yem_paystatus", "A");
        } else if (!pre.contains(false)) {
            //预收完成
            dataEntity.set("yem_paystatus", "B");
        } else if (iou > 0) {
            //欠条到位
            dataEntity.set("yem_paystatus", "C");
        } else {
            dataEntity.set("yem_paystatus", null);
        }
        dataEntity.set("yem_debugmsg", debugMsg.toString());
    }
}
