package com.yem.tws.task;

import com.yem.wm.task.YunZhiJaGetOpenidTask;
import com.yem.wm.utils.DynamicObjectUtil;
import com.yem.wm.utils.YEM;
import kd.bos.coderule.api.CodeRuleInfo;
import kd.bos.context.RequestContext;
import kd.bos.data.BusinessDataReader;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.IDataEntityType;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.botp.runtime.ConvertOperationResult;
import kd.bos.entity.botp.runtime.PushArgs;
import kd.bos.entity.datamodel.IRefrencedataProvider;
import kd.bos.entity.datamodel.ListSelectedRow;
import kd.bos.entity.operate.result.IOperateInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.exception.KDBizException;
import kd.bos.exception.KDException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.schedule.executor.AbstractTask;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.botp.BFTrackerServiceHelper;
import kd.bos.servicehelper.botp.ConvertServiceHelper;
import kd.bos.servicehelper.coderule.CodeRuleServiceHelper;
import kd.bos.servicehelper.operation.DeleteServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author ljw
 * @date 2024/3/18 10:00
 * @className YunZhiJaGetOpenidTask
 * @description 获取单一窗口报关单数据反写至出口报关单
 */
public class CusdecToDeclaredocxTask extends AbstractTask {
    @Override
    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
        Log log = LogFactory.getLog(YunZhiJaGetOpenidTask.class);
        QFilter filter = new QFilter("yem_billno", QCP.not_equals, "");
        String selectfield = DynamicObjectUtil.getSelectfields("yem_ca_cusdec", false);
        String selectfields = DynamicObjectUtil.getEntrySelectfields(selectfield, "yem_ca_cusdec", "yem_ca_cddetailedentry", false);
        DynamicObject[] bos_user = BusinessDataServiceHelper.load("yem_ca_cusdec", selectfields
                , new QFilter[]{filter});
//        extracted(bos_user);
        extracted(bos_user);
    }

    /**
     * @param bosUser
     */
    private void extracted(DynamicObject[] bosUser) {
        for (DynamicObject user : bosUser) {
            //新增日志
            DynamicObject data = BusinessDataServiceHelper.newDynamicObject("yem_es_declarationlog");
            //单一窗口报关单map
            Map<String, DynamicObject> maps = new HashMap<String, DynamicObject>();
            //提单号
            String yemBillno = user.getString("yem_billno");
            String yemEntryid = user.getString("yem_entryid");
            //但一窗口报关单id
            long id = user.getLong("id");
            //单一窗口报关单分录
            DynamicObjectCollection yemCaCddetailedentry = user.getDynamicObjectCollection("yem_ca_cddetailedentry");
            for (DynamicObject dynamicObject : yemCaCddetailedentry) {
                //商品编码（商品编码）
                String yemCodets = dynamicObject.getString("yem_codets");
                //商品名称（报关名称）
                String yemGname = dynamicObject.getString("yem_gname");
                //成交数量（数量）
                BigDecimal yemGqty = dynamicObject.getBigDecimal("yem_gqty");
                //单价（单价）
                BigDecimal yemDeclprice = dynamicObject.getBigDecimal("yem_declprice");
                //总价（金额）
                BigDecimal yemDecltotal = dynamicObject.getBigDecimal("yem_decltotal");
                //币别
                DynamicObject yemTradecurr = dynamicObject.getDynamicObject("yem_tradecurr");
                String number = "";
                if (yemTradecurr != null) {
                    number = yemTradecurr.getString("number");
                }
                //拼接KEY  去掉"-" + billno +   加上 商品编码
                String string = yemCodets + "-" + yemGname + "-" + yemGqty + "-" + yemDeclprice + "-" + yemDecltotal + "-" + number;
                maps.put(string, dynamicObject);
            }
            //出口报关单
            QFilter yemRealbringbillno = new QFilter("yem_realbringbillno", QCP.equals, yemBillno);
            yemRealbringbillno.or(new QFilter("yem_bringbillno", QCP.equals, yemBillno));
            String selectfield = DynamicObjectUtil.getSelectfields("yem_es_declaredocx", false);
            String selectfields = DynamicObjectUtil.getEntrySelectfields(selectfield, "yem_es_declaredocx", "yem_es_declare_ec", false);
            DynamicObject declaredocx = BusinessDataServiceHelper.loadSingle("yem_es_declaredocx", selectfields
                    , new QFilter[]{yemRealbringbillno});
            if (null != declaredocx) {
                //申报状态
                String yemDeclarationstatus = declaredocx.getString("yem_declarationstatus");
                //单一窗口报关单id
                Long yemCustomsdocumentid = declaredocx.getLong("yem_customsdocumentid");
                if (!"结关".equals(yemDeclarationstatus)) {
                    if (yemCustomsdocumentid != 0) {
                        //单一窗口报关单
                        String yemCaCusdec = DynamicObjectUtil.getSelectfields("yem_ca_cusdec", false);
                        DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle("yem_ca_cusdec", yemCaCusdec
                                , new QFilter[]{new QFilter("id", QCP.equals, yemCustomsdocumentid)});
                        if (dynamicObject != null) {
                            String yemCusdecstatusname = dynamicObject.getString("yem_cusdecstatusname");//申报状态
                            declaredocx.set("yem_declarationstatus", yemCusdecstatusname);
                            if ("结关".equals(yemCusdecstatusname)) {
                                extracted(Long.valueOf(declaredocx.getPkValue().toString()));
                            }
                        } else {
                            declaredocx.set("yem_customsdocumentid", 0);
                        }
                        SaveServiceHelper.update(declaredocx);
                        SaveServiceHelper.save(new DynamicObject[]{declaredocx});
                    } else {
                //出口报关单分录
                DynamicObjectCollection dynamicObjectCollection = declaredocx.getDynamicObjectCollection("yem_es_declare_ec");
                //结算币别
                DynamicObject yemCurrency = declaredocx.getDynamicObject("yem_currency");
                String aLong = "";
                if (yemCurrency != null) {
                    aLong = yemCurrency.getString("number");
                }
                //单据编号
                String declaredocxbillno = declaredocx.getString("billno");
                int i = dynamicObjectCollection.size();
                String seq = "";
                for (DynamicObject object : dynamicObjectCollection) {
                    //海关商品编码
                    DynamicObject yemCusboxgoods = object.getDynamicObject("yem_cushscode");
                    String billno = "";
                    if (yemCusboxgoods != null) {
                        billno = yemCusboxgoods.getString("number");
                    }
                    //报关名称
                    String yemDecmatericalname = object.getString("yem_decmatericalname");
                    //数量
                    BigDecimal yemCusqty = object.getBigDecimal("yem_cusqty");
                    //单价
                    BigDecimal yemCusconsalesprice = object.getBigDecimal("yem_cusconsalesprice");
                    //金额
                    BigDecimal yemCusamount = object.getBigDecimal("yem_cusamount");
                    //拼接KEY  + "-" + billno
                    String yemErroriskey = billno + "-" + yemDecmatericalname + "-" + yemCusqty + "-" + yemCusconsalesprice + "-" + yemCusamount + "-" + aLong;
                    DynamicObject dynamicObject = maps.get(yemErroriskey);
                    if (dynamicObject != null) {
                        i = i - 1;
                    } else {
                        seq = seq + object.getString("seq") + ",";
                    }
                }
                if (i != 0) {
                    extracted(data, "出口报关报关单号【" + declaredocxbillno + "】,第" + seq + "行未匹配到单一窗口报关单;\n", id, declaredocxbillno, yemBillno);
                } else {
                    String yemCusdecstatusname = user.getString("yem_cusdecstatusname");//申报状态
                    Date yemFiedatets = user.getDate("yem_fiedatets");//出口日期
                    extracted(data, "出口报关报关单号【" + declaredocxbillno + "】成功匹配单一窗口报关单;\n", id, declaredocxbillno, yemBillno);
                    declaredocx.set("yem_declarationstatus", yemCusdecstatusname);
                    declaredocx.set("yem_customsnumber", yemEntryid);
                    declaredocx.set("yem_exportdate", yemFiedatets);
                    declaredocx.set("yem_customsdocumentid", id);
                    if ("结关".equals(yemCusdecstatusname) && !YEM.isEmpty(yemFiedatets)) {
                        extracted(Long.valueOf(declaredocx.getPkValue().toString()));
                    }
                    SaveServiceHelper.update(declaredocx);
                    SaveServiceHelper.save(new DynamicObject[]{declaredocx});
                        }
                    }
                }
            }
        }
    }

    /**
     * 生成日志
     *
     * @param data
     * @param declaredocxbillno
     * @param id
     * @param declaredocxbillno1
     * @param yemBillno
     */
    private static void extracted(DynamicObject data, String declaredocxbillno, long id, String declaredocxbillno1, String yemBillno) {
        data.set("yem_errorissues", declaredocxbillno);
        data.set("yem_customsid", id);
        data.set("yem_customsnumber", declaredocxbillno1);
        data.set("yem_billno", yemBillno);
        data.set("billstatus", "A");
        CodeRuleInfo codeRule = CodeRuleServiceHelper.getCodeRule(data.getDataEntityType().getName(), data, null);
        String number = CodeRuleServiceHelper.getNumber(codeRule, data);
        data.set("billno", number);
        SaveServiceHelper.save(new DynamicObject[]{data});
        SaveServiceHelper.update(data);
    }


    /**
     * 单一窗口报关单反写出口报关单
     *
     * @param bos_user
     */
//    private static void extractede(DynamicObject[] bos_user) {
//        for (DynamicObject user : bos_user) {
//            DynamicObject data = BusinessDataServiceHelper.newDynamicObject("yem_es_declarationlog");
//            //单一窗口报关单map
//            Map<Long, DynamicObject> maps = new HashMap<Long, DynamicObject>();
//            long id = user.getLong("id");//关务单id
//            String yemBillno = user.getString("yem_billno");//提单号
//            DynamicObjectCollection yemCaCddetailedentry = user.getDynamicObjectCollection("yem_ca_cddetailedentry");
//            for (DynamicObject dynamicObject : yemCaCddetailedentry) {
//                Long yemCodets = dynamicObject.getLong("id");//商品编号
//                maps.put(yemCodets, dynamicObject);
//            }
//            QFilter yemRealbringbillno = new QFilter("yem_realbringbillno", QCP.equals, yemBillno);
//            yemRealbringbillno.or(new QFilter("yem_bringbillno", QCP.equals, yemBillno));
//            String selectfield = DynamicObjectUtil.getSelectfields("yem_es_declaredocx", false);
//            String selectfields = DynamicObjectUtil.getEntrySelectfields(selectfield, "yem_es_declaredocx", "yem_es_declare_ec", false);
//            DynamicObject declaredocx = BusinessDataServiceHelper.loadSingle("yem_es_declaredocx", selectfields
//                    , new QFilter[]{yemRealbringbillno});
//            if (null != declaredocx) {
//                DynamicObjectCollection dynamicObjectCollection = declaredocx.getDynamicObjectCollection("yem_es_declare_ec");
//                DynamicObject yemCurrency = declaredocx.getDynamicObject("yem_currency");//结算币别
//                long aLong = 0L;
//                if (yemCurrency != null) {
//                    aLong = yemCurrency.getLong("id");
//                }
//                String declaredocxbillno = declaredocx.getString("billno");
//                String yemErroriskey = "";
//                for (DynamicObject object : dynamicObjectCollection) {
//                    DynamicObject yemCusboxgoods = object.getDynamicObject("yem_cushscode");//商品编码
//                    String yemDecmatericalname = object.getString("yem_decmatericalname");//报关名称
//                    BigDecimal yemCusqty = object.getBigDecimal("yem_cusqty");//数量
//                    BigDecimal yemCusconsalesprice = object.getBigDecimal("yem_cusconsalesprice");//单价
//                    BigDecimal yemCusamount = object.getBigDecimal("yem_cusamount");//金额
//                    DynamicObject yemCusunit = object.getDynamicObject("yem_cushscode");//计量单位
//                    DynamicObject yemHscode = object.getDynamicObject("yem_cushscode");//海关编码
//                    long yem_sourcebillentryid = object.getLong("yem_sourcebillentryid");
//                    String yemHscodenumber = "";
//                    if (null != yemHscode) {
//                        yemHscodenumber = yemHscode.getString("number");
//                    }
//                    String boxgoodsname = "";
//                    if (yemCusboxgoods != null) {
//                        boxgoodsname = yemCusboxgoods.getString("number");
//                    }
//                    DynamicObject dynamicObject = maps.get(yem_sourcebillentryid);
//                    if (dynamicObject != null) {
//                        BigDecimal yemGqty = dynamicObject.getBigDecimal("yem_gqty");//成交数量
//                        DynamicObject yem_gunit = dynamicObject.getDynamicObject("yem_unit1");//成交计量单位
//                        DynamicObject yem_tradecurr = dynamicObject.getDynamicObject("yem_tradecurr");//币别
//                        DynamicObject yemCodets = dynamicObject.getDynamicObject("yem_codets");//商品编码
//                        String yemCodetsString = "";
//                        if (yemCodets != null) {
//                            yemCodetsString = yemCodets.getString("number");
//                        }
//                        long aLong1 = 0L;
//                        if (yem_tradecurr != null) {
//                            aLong1 = yem_tradecurr.getLong("id");
//                        }
//                        String unitname = "";
//                        if (yem_gunit != null) {
//                            unitname = yem_gunit.getString("name");
//                        }
//                        String yemGname = dynamicObject.getString("yem_gname");//商品名称
//                        String yem_codets = dynamicObject.getString("yem_codets");//商品编码
//                        BigDecimal yemDeclprice = dynamicObject.getBigDecimal("yem_declprice");//单价
//                        BigDecimal yemDecltotal = dynamicObject.getBigDecimal("yem_decltotal");//总价
//                        String name = "";
//                        if (yemCusunit != null) {
//                            name = yemCusunit.getString("yem_legalfirst.name");
//                        }
//                        if (yemGqty.compareTo(yemCusqty) == 0
//                                && yemHscodenumber.equals(yemCodetsString)
//                                && aLong1 == aLong
//                                && yemCusconsalesprice.compareTo(yemDeclprice) == 0
//                                && yemCusamount.compareTo(yemDecltotal) == 0
//                                && name.equals(unitname)
//                                && boxgoodsname.equals(yem_codets)
//                                && yemDecmatericalname.equals(yemGname)) {
//                            String yemCusdecstatusname = user.getString("yem_cusdecstatusname");//申报状态
//                            Date yemFiedatets = user.getDate("yem_fiedatets");//出口日期
//                            extracted(declaredocx, yemCusdecstatusname, declaredocxbillno, yemFiedatets, id);
//                        } else {
//                            String yemErrorissues = "";
//                            if (!yemHscodenumber.equals(yemCodetsString)) {
//                                yemErrorissues = yemErrorissues + "商品编码;";
//                            }
//                            if (aLong1 != aLong) {
//                                yemErrorissues = yemErrorissues + "币别;";
//                            }
//                            if (!unitname.equals(name)) {
//                                yemErrorissues = yemErrorissues + "计量单位;";
//                            }
//                            if (yemGqty.compareTo(yemCusqty) != 0) {
//                                yemErrorissues = yemErrorissues + "商品数量;";
//                            }
//                            if (yemCusamount.compareTo(yemDecltotal) != 0) {
//                                yemErrorissues = yemErrorissues + "销售金额;";
//                            }
//                            if (yemCusconsalesprice.compareTo(yemDeclprice) != 0) {
//                                yemErrorissues = yemErrorissues + "单价;";
//                            }
//                            if (!boxgoodsname.equals(yem_codets)) {
//                                yemErrorissues = yemErrorissues + "商品编码;";
//                            }
//                            if (!yemDecmatericalname.equals(yemGname)) {
//                                yemErrorissues = yemErrorissues + "报关名称;";
//                            }
//                            String yemCustomclassString = object.getString("yem_decmatericalname");
//                            if (yemHscode != null) {
//                                String names = yemHscode.getString("number");
////                                String yemCustomclassString = yemCustomclass.getString("name");
//                                yemErroriskey = yemErroriskey + "出口报关报关单号【" + declaredocxbillno + "】:" + "第" + object.getLong("seq") + "行,海关编码【" + names + "】,报关名称【"
//                                        + yemCustomclassString + "】未匹配到【相同的" + yemErrorissues + "】的单一窗口报关单;" + "\n";
//
//                                extracted(declaredocx, "", "", null, 0);
//                            }
//                        }
//                    } else {
//                        extracted("出口报关报关单号" + declaredocxbillno + "，未匹配到相同行的单一窗口报关单;", id, declaredocxbillno, yemBillno, data);
//                        CodeRuleInfo codeRule = CodeRuleServiceHelper.getCodeRule(data.getDataEntityType().getName(), data, null);
//                        String number = CodeRuleServiceHelper.getNumber(codeRule, data);
//                        data.set("billno", number);
//                        SaveServiceHelper.save(new DynamicObject[]{data});
//                        SaveServiceHelper.update(data);
//                    }
//                }
//                if (!"".equals(yemErroriskey)) {
//                    extracted(yemErroriskey, id, declaredocxbillno, yemBillno, data);
//                    CodeRuleInfo codeRule = CodeRuleServiceHelper.getCodeRule(data.getDataEntityType().getName(), data, null);
//                    String number = CodeRuleServiceHelper.getNumber(codeRule, data);
//                    data.set("billno", number);
//                    SaveServiceHelper.save(new DynamicObject[]{data});
//                    SaveServiceHelper.update(data);
//                } else {
//                    extracted("出口报关报关单号" + declaredocxbillno + "，匹配单一窗口报关单" + user.getString("billno") + "成功匹配;", id, declaredocxbillno, yemBillno, data);
//                    CodeRuleInfo codeRule = CodeRuleServiceHelper.getCodeRule(data.getDataEntityType().getName(), data, null);
//                    String number = CodeRuleServiceHelper.getNumber(codeRule, data);
//                    data.set("billno", number);
//                    SaveServiceHelper.save(new DynamicObject[]{data});
//                    SaveServiceHelper.update(data);
//                }
//            }
//        }
//    }
//

    /**
     * 出口报关单反写值
     */
//    private static void extracted(DynamicObject declaredocx, String yemCusdecstatusname, String declaredocxbillno, Date yemFiedatets, long id) {
//        declaredocx.set("yem_declarationstatus", yemCusdecstatusname);
//        declaredocx.set("yem_customsnumber", declaredocxbillno);
//        declaredocx.set("yem_exportdate", yemFiedatets);
//        declaredocx.set("yem_customsdocumentid", id);
//        if ("结关".equals(yemCusdecstatusname)) {
//            extracted(id);
//        }
//    }
    private static void extracted(long id) {
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_es_declaredocx", "", new QFilter[]{
//                new QFilter("yem_declarestatused", QCP.equals, "F"),
//                new QFilter("billstatus",QCP.equals,"C")
                new QFilter("id", QCP.equals, id)
        });
        for (DynamicObject loadSon : load) {
//            boolean yemEsDeclaredocx = BFTrackerServiceHelper.isPush("yem_es_declaredocx", (long) loadSon.getPkValue());
//            if (!yemEsDeclaredocx) {
            pushCreateBill(loadSon, "1731413160633589760", "yem_exportinvoice");
//            }
        }
    }

    /**
     * 生成单一窗口报关单日志
     */
//    private static void extracted(String yemErrorissues, long id, String billno, String yemBillno, DynamicObject data) {
//        data.set("yem_errorissues", yemErrorissues);
//        data.set("yem_customsid", id);
//        data.set("yem_customsnumber", billno);
//        data.set("yem_billno", yemBillno);
//        data.set("billstatus", "A");
//    }

    /**
     * 下推生成出口发票
     */
    private static void pushCreateBill(DynamicObject processingorderNow, String rule, String toNumber) {
        PushArgs pushArgs = setPushArgs(processingorderNow, toNumber, rule);
        ConvertOperationResult pushResult = ConvertServiceHelper.push(pushArgs);
        if (pushResult.isSuccess()) {
            MainEntityType targetMainType = EntityMetadataCache.getDataEntityType(toNumber);
            List<DynamicObject> targetBillObjs = pushResult.loadTargetDataObjects(new IRefrencedataProvider() {
                @Override
                public void fillReferenceData(Object[] objs, IDataEntityType dType) {
                    BusinessDataReader.loadRefence(objs, dType);
                }
            }, targetMainType);
            for (DynamicObject dt : targetBillObjs) {
                OperationResult save = OperationServiceHelper.executeOperate("save", dt.getDynamicObjectType().getName(), new DynamicObject[]{dt}, OperateOption.create());
                if (save.isSuccess()) {
//                                            OperationResult submit = OperationServiceHelper.executeOperate("submit", debCredNoteNumber, new Object[]{debCredNote.getPkValue()}, OperateOption.create());
//                                            if (submit.isSuccess()) {
//                                                OperationResult audit = OperationServiceHelper.executeOperate("audit", debCredNoteNumber, new Object[]{debCredNote.getPkValue()}, OperateOption.create());
//                                                if (audit.isSuccess()) {
//
//                                                }else{
//                                                    List<IOperateInfo> allErrorOrValidateInfo = audit.getAllErrorOrValidateInfo();
//                                                    String message = audit.getMessage();
//                                                    throw new KDBizException("审核关联生成的贷记单失败," + message + "，" + allErrorOrValidateInfo);
//                                                }
//                                            }else{
//                                                List<IOperateInfo> allErrorOrValidateInfo = submit.getAllErrorOrValidateInfo();
//                                                String message = submit.getMessage();
//                                                throw new KDBizException("提交关联生成的贷记单失败," + message + "，" + allErrorOrValidateInfo);
//                                            }
                } else {
                    List<IOperateInfo> allErrorOrValidateInfo = save.getAllErrorOrValidateInfo();
                    String message = save.getMessage();
                    throw new KDBizException("保存生成出口发票失败:," + message + "，" + allErrorOrValidateInfo);
                }
            }


        }
    }

    /**
     * 设置下推引擎
     */
    public static PushArgs setPushArgs(DynamicObject dataEntitie, String targetNumber, String ruleId) {
        String name = dataEntitie.getDynamicObjectType().getName();
        PushArgs pushArgs = new PushArgs();
        pushArgs.setSourceEntityNumber(name);
        pushArgs.setTargetEntityNumber(targetNumber);
        pushArgs.setRuleId(ruleId);
        pushArgs.setHasRight(true);
        pushArgs.setBuildConvReport(true);
        List<ListSelectedRow> selectedRows = new ArrayList<>();
        ListSelectedRow srcBill1 = new ListSelectedRow(dataEntitie.getPkValue());
        selectedRows.add(srcBill1);
        pushArgs.setSelectedRows(selectedRows);
        return pushArgs;
    }
}
