package yem.wmc.imc.utils;


import com.alibaba.fastjson.JSONObject;
import kd.bos.bill.IBillWebApiPlugin;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.api.ApiResult;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.util.StringUtils;
import org.json.XML;
import yem.base.common.utils.BigDecimalUtils;

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

import static yem.wmc.imc.utils.JsonUtils.jsonToData;

/**
 * @author lipan
 * @date 2023/12/19 16:51
 * @className CaBillAddUpdataXML
 * @description
 */
public class CaBillAddUpdataXML implements IBillWebApiPlugin {

    @Override
    public ApiResult doCustomService(Map<String, Object> params) {
        List<Object> resultlist = Collections.synchronizedList(new ArrayList<>());
        boolean BollISSucces = false;
        String ErrMassage = "";
        String FID = "";
        String billno = "";
        JSONObject jsonData = null;
        String entityNumber = "";
        try {


            jsonData = JSONObject.parseObject(JSONObject.toJSONString(params));
            if (null != jsonData) {
                String jsion =XMLTOJosn(jsonData.getString("jsion"));
                String entityName = jsonData.getString("entityName");
                if (jsion != null) {
                    //获取进出口标记
                    JSONObject jsonObj = JSONObject.parseObject(jsion);
                    JSONObject REdata = jsonObj.getJSONObject("DecMessage");
                    JSONObject preDecHeadVo = (jsonObj.getJSONObject("DecMessage")).getJSONObject("DecHead");
//                    String cusIEFlag = (jsonObj.getJSONObject("DecMessage")).getJSONObject("DecHead").getString("IEFlag");
//                    String entryId = preDecHeadVo.getString("EntryId");
//                    if (cusIEFlag.equals("E")) {
//                        entityNumber = "CusDec_xml";
//                    } else {
//                        entityNumber = "CusDec_xml";
//                    }

                    // todo 将我的数据进行替换...
                    entityNumber = "yem_imc_esinvoice";   //注册表 单据编号
                    String entryId = "123456789";
                    entityName = "yem_imc_esinvoice"; // 表名
                   String originalJson = "{\"serialNo\":\"16bc3505-1dc4-41f1-aec8-0959fa072f32\",\"code\":\"200\",\"message\":\"OK\",\"data\":[{\"invoiceVO\":{\"purchaserBank\":\"浦发银行市南支行69050078801700000719\",\"amount\":24.68,\"machineCode\":\"661823722635\",\"purchaserAddressTel\":\"山东省青岛市城阳区宏祥一路17号18号楼0532-58567765\",\"sellerBank\":\"交通银行北京海淀支行110060576018800043070\",\"sellerName\":\"北京京东广能贸易有限公司\",\"remark\":\"dd75253569777(00001,<br/>282664465750)\",\"drewDate\":\"2023-10-23\",\"invoiceCode\":\"1100231130\",\"purchaserName\":\"斯坦德技术工程（青岛）有限公司\",\"checkCode\":\"85823800434253824556\",\"sellerTaxNo\":\"91110113MA019HUX48\",\"purchaserTaxNo\":\"91370222MA3QWRF42B\",\"detailList\":[{\"unitPrice\":12.48,\"taxRate\":0.130,\"amount\":12.48,\"unit\":\"盒\",\"quantity\":1,\"taxPreType\":0,\"taxPre\":1,\"zeroTax\":0,\"specification\":\"ARPM2001\",\"taxAmount\":1.62,\"goodsName\":\"*文具*晨光(M&G)文具0.5mm黑色直液式走珠笔 速干直液式中性笔 水笔全针管Z1 学生/办公用品12支 A\",\"revenueCode\":\"1060402010200000000\"},{\"taxRate\":0.130,\"amount\":-1.25,\"unit\":\"\",\"taxPreType\":0,\"taxPre\":1,\"zeroTax\":0,\"specification\":\"\",\"taxAmount\":-0.16,\"goodsName\":\"*文具*晨光(M&G)文具0.5mm黑色直液式走珠笔 速干直液式中性笔 水笔全针管Z1 学生/办公用品12支 A\",\"revenueCode\":\"1060402010200000000\"},{\"unitPrice\":3.54,\"taxRate\":0.130,\"amount\":14.16,\"unit\":\"卷\",\"quantity\":4,\"taxPreType\":0,\"taxPre\":1,\"zeroTax\":0,\"specification\":\"AJD97391\",\"taxAmount\":1.84,\"goodsName\":\"*文具*晨光(M&G)文具强力高粘度EVA泡棉双面胶带 36mm*5y(4.57m/卷)办公用品  单卷装AJD97391\",\"revenueCode\":\"1060401990000000000\"},{\"taxRate\":0.130,\"amount\":-0.71,\"unit\":\"\",\"taxPreType\":0,\"taxPre\":1,\"zeroTax\":0,\"specification\":\"\",\"taxAmount\":-0.09,\"goodsName\":\"*文具*晨光(M&G)文具强力高粘度EVA泡棉双面胶带 36mm*5y(4.57m/卷)办公用品  单卷装AJD97391\",\"revenueCode\":\"1060401990000000000\"}],\"invoiceType\":\"01\",\"sellerAddressTel\":\"北京市顺义区大孙各庄镇七大路后岭上段3号院57807000\",\"amountWithTax\":27.89,\"invoiceNo\":\"07476632\",\"invoiceStatus\":0,\"taxAmount\":3.21},\"invoiceVo\":null,\"invoiceCodeNo\":\"1100231130-07476632\",\"checkFlag\":true}]}";
                    JSONObject json1 = JSONObject.parseObject(originalJson);
                    JSONObject jsonObject = (JSONObject) json1.getJSONArray("data").get(0); // invoiceVO外面一层
                    REdata = jsonObject;

                    //从表中查询
//                    QFilter filter1 = new QFilter("billno", QCP.equals, entryId);
//                    DynamicObject simpleBill1 = BusinessDataServiceHelper.loadSingle(entityName, "id", new QFilter[]{filter1});
                    DynamicObject simpleBill1 = null;
                    if (simpleBill1 == null) {
                        // todo 从注册表中查询
                        QFilter qFilter = new QFilter("billno", QCP.equals, entityNumber);
                        DynamicObject[] yem_ca_billlogon_s = BusinessDataServiceHelper.load("yem_ca_billlogon",
                                "id,billno,billstatus", new QFilter[]{qFilter}, null);

                        // todo 测试开始....
                        if (yem_ca_billlogon_s != null && yem_ca_billlogon_s.length > 0) {
                            DynamicObject data = jsonToData(REdata.toString(), entityName, yem_ca_billlogon_s, entryId, REdata);
                            if (data != null) {
                                //处理运费保费杂费
//                                data = ManageYBZ(data); jl -注
                                OperationResult Operate5 = OperationServiceHelper.executeOperate("save", data.getDynamicObjectType().getName(), new DynamicObject[]{data}, OperateOption.create());

                    // todo 测试结束...
                                if (Operate5.isSuccess()) {
                                    if (data.getString("yem_cusdecstatusname").equals("结关")) {
//                                        data = CommonUtils.billingnote(data);  //todo 临时注销
                                    }
                                }
                                OperationResult Operate = OperationServiceHelper.executeOperate("save",
                                        data.getDynamicObjectType().getName(), new DynamicObject[]{data},
                                        OperateOption.create());
                                if (Operate.isSuccess()) {//保存成功
                                    billno = data.getString("billno");
                                    ErrMassage = "同步成功，单据编号为：" + billno;
                                    BollISSucces = true;
                                    FID = data.getString("id");
                                } else {
                                    //保存失败
                                    BollISSucces = false;
                                    ErrMassage = "单一窗口报关单保存失败！";
                                }
                            } else {
                                ErrMassage = "Json转DynamicObject失败，详情请联系管理员查看日志！";
                            }
                        } else {
                            ErrMassage = "关单单据注册中【" + entityName + "】单据编号未注册，保存失败";
                        }
                    } else {
                        ErrMassage = "单一窗口报关单已存在单据编号为【" + entryId + "】的单据，禁止新增！";
                    }
                }
                else{
                    ErrMassage = "获取到Json为空，获取失败";
                    Log(BollISSucces, FID, billno, ErrMassage, jsonData);
                }
            } else {
                ErrMassage = "获取到Json为空，获取失败";
                Log(false, FID, billno, ErrMassage, jsonData);
            }
        } catch (Exception e) {
            //获取到错误，记录错误日志
            ErrMassage = e.getMessage();
            Log(false, FID, billno, ErrMassage, jsonData);
        }
        Map<String, Object> resultMap = Map(BollISSucces, FID, billno, ErrMassage);
        resultlist.add(resultMap);
        return ApiResult.success(resultlist);
    }

    public void Log(boolean BollISSucces, String FID, String billno, String ErrMassage, JSONObject jsonData) {
        Map<String, Object> resultMap = Map(BollISSucces, FID, billno, ErrMassage);
        //记录API日志
        String opdesc = "将中国国际贸易单一窗口同步至单一窗口报关单";
        ApilogUtils.Createlog(resultMap, billno, "单一窗口报关单", opdesc, "AddCusDec", jsonData);
    }

    public Map<String, Object> Map(boolean BollISSucces, String FID, String billno, String ErrMassage) {
        String description = "{\"data\":{\"BollISSucces\":\"" + BollISSucces + "\",\"FID\":\"" + FID + "\",\"ErrMassage\": \"" + ErrMassage + "\"}}";
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("description", description);
        resultMap.put("result", BollISSucces);
        resultMap.put("billno", billno);
        return resultMap;
    }

    /**
     * 处理运保杂
     */
    public DynamicObject ManageYBZ(DynamicObject yem_ca_billlogon) {
        if (yem_ca_billlogon != null) {
            //金额合计
            BigDecimal yem_sumdecltotal = yem_ca_billlogon.getBigDecimal("yem_sumdecltotal");
            //金额本位币
            BigDecimal yem_sumlocdecltotal = yem_ca_billlogon.getBigDecimal("yem_sumlocdecltotal");
            //进出口日期
            Date yem_fiedatets = yem_ca_billlogon.getDate("yem_fiedatets");
            BigDecimal yem_grosswt = yem_ca_billlogon.getBigDecimal("yem_grosswt");
            BigDecimal yem_exchangerate = yem_ca_billlogon.getBigDecimal("yem_exchangerate");//报关汇率
            if (yem_exchangerate.equals(BigDecimal.ZERO)) {
                //报关币别
                DynamicObject yem_currencybase = yem_ca_billlogon.getDynamicObject("yem_currencybase");
                if (yem_currencybase != null) {
                    yem_exchangerate = exchangerate(yem_fiedatets, yem_currencybase);
                    yem_sumlocdecltotal = yem_exchangerate.multiply(yem_sumdecltotal);
                    yem_ca_billlogon.set("yem_sumlocdecltotal", yem_sumlocdecltotal);
                }
            }
            //当前单据运费保费杂费汇总
            BigDecimal SumYBZ = BigDecimal.ZERO;
            //运费标志
            String yem_feemarkname = yem_ca_billlogon.getString("yem_feemarkname").toString();
            if (StringUtils.isNotEmpty(yem_feemarkname) && StringUtils.isNotNull(yem_feemarkname)) {
                DynamicObject yem_feecurrbase = yem_ca_billlogon.getDynamicObject("yem_feecurrbase");//运费币别
                if (yem_feecurrbase != null) {
                    BigDecimal yem_feerate = yem_ca_billlogon.getBigDecimal("yem_feerate");//运费/率
                    BigDecimal feemarkAmt = YBZAmt(yem_feemarkname, yem_fiedatets, yem_feerate, yem_feecurrbase, yem_sumdecltotal, yem_grosswt);
                    SumYBZ = SumYBZ.add(feemarkAmt);
                    yem_ca_billlogon.set("yem_feecurrtotal", feemarkAmt);//运费总额（RMB）
                }
            }
            //保费标志
            String yem_insurmarkname = yem_ca_billlogon.getString("yem_insurmarkname").toString();
            if (StringUtils.isNotEmpty(yem_insurmarkname) && StringUtils.isNotNull(yem_insurmarkname)) {
                DynamicObject yem_insurcurbase = yem_ca_billlogon.getDynamicObject("yem_insurcurbase");//保费币别
                if (yem_insurcurbase != null) {
                    BigDecimal yem_insurrate = yem_ca_billlogon.getBigDecimal("yem_insurrate");//保费/率
                    BigDecimal feemarkAmt = YBZAmt(yem_insurmarkname, yem_fiedatets, yem_insurrate, yem_insurcurbase, yem_sumdecltotal, yem_grosswt);
                    SumYBZ = SumYBZ.add(feemarkAmt);
                    yem_ca_billlogon.set("yem_insurcurtotal", feemarkAmt);//保费总额（RMB）
                }
            }
            //杂费标志
            String yem_othermarkname = yem_ca_billlogon.getString("yem_othermarkname").toString();
            if (StringUtils.isNotEmpty(yem_othermarkname) && StringUtils.isNotNull(yem_othermarkname)) {
                DynamicObject yem_othercubase = yem_ca_billlogon.getDynamicObject("yem_othercubase");//保费币别
                BigDecimal yem_otherrate = yem_ca_billlogon.getBigDecimal("yem_otherrate");//杂费/率
                BigDecimal feemarkAmt = YBZAmt(yem_othermarkname, yem_fiedatets, yem_otherrate, yem_othercubase, yem_sumdecltotal, yem_grosswt);
                SumYBZ = SumYBZ.add(feemarkAmt);
                yem_ca_billlogon.set("yem_othercutotal", feemarkAmt);//运费总额（RMB）
            }
            BigDecimal yem_fobtotal = BigDecimal.ZERO;
            BigDecimal yem_fobtotalusd = BigDecimal.ZERO;
            DynamicObjectCollection yem_ca_cddetailedentry = yem_ca_billlogon.getDynamicObjectCollection("yem_ca_cddetailedentry");
            for (int j = 0; j < yem_ca_cddetailedentry.size(); j++) {
                BigDecimal yem_fobamout = BigDecimal.ZERO;
                BigDecimal yem_fobusd = BigDecimal.ZERO;
                DynamicObject cddetailedentry = yem_ca_cddetailedentry.get(j);
                BigDecimal yem_gqty = cddetailedentry.getBigDecimal("yem_qty1");//数量
                BigDecimal yem_decltotal = cddetailedentry.getBigDecimal("yem_decltotal");//分录总额
                cddetailedentry.set("yem_rmbdecltotal", yem_decltotal.multiply(yem_exchangerate));//分录总额本位币
                if (SumYBZ.equals(BigDecimal.ZERO)) {
                    yem_fobamout = yem_decltotal.multiply(yem_exchangerate).setScale(2, BigDecimal.ROUND_HALF_UP);//FOB总价(RMB)
                    cddetailedentry.set("yem_fobamout", yem_fobamout);
                    if(!yem_gqty.equals(BigDecimal.ZERO)){
                        cddetailedentry.set("yem_fobprice", yem_fobamout.divide(yem_gqty, 10, BigDecimal.ROUND_UP));//FOB单价(RMB)
                    }
                    if((BigDecimal.ZERO).compareTo(yem_exchangerate) != 0) {
                        yem_fobusd = yem_fobamout.divide(yem_exchangerate, 10, BigDecimal.ROUND_UP).setScale(2, BigDecimal.ROUND_HALF_UP);
                    }
                    cddetailedentry.set("yem_usdfob", yem_fobusd);
                } else {
                    BigDecimal bl = yem_decltotal.divide(yem_sumdecltotal, 10, BigDecimal.ROUND_UP);
                    BigDecimal ybzrmb = SumYBZ.multiply(bl);
                    yem_fobamout = yem_decltotal.multiply(yem_exchangerate).subtract(ybzrmb).setScale(2, BigDecimal.ROUND_HALF_UP);
                    if((BigDecimal.ZERO).compareTo(yem_exchangerate) != 0) {
                        yem_fobusd = yem_fobamout.divide(yem_exchangerate, 10, BigDecimal.ROUND_UP).setScale(2, BigDecimal.ROUND_HALF_UP);
                    }
                    cddetailedentry.set("yem_fobamout", yem_fobamout);
                    if(!yem_gqty.equals(BigDecimal.ZERO)){
                        cddetailedentry.set("yem_fobprice", yem_fobamout.divide(yem_gqty, 10, BigDecimal.ROUND_UP));//FOB单价(RMB)
                    }
                    cddetailedentry.set("yem_usdfob", yem_fobusd);
                }
                yem_fobtotal = yem_fobtotal.add(yem_fobamout);
                yem_fobtotalusd = yem_fobtotalusd.add(yem_fobusd);
            }
            yem_ca_billlogon.set("yem_fobtotal", yem_fobtotal);
            yem_ca_billlogon.set("yem_usdfobtotal", yem_fobtotalusd);
        }
        return yem_ca_billlogon;
    }

    public BigDecimal exchangerate(Date yem_fiedatets, DynamicObject yem_currencybase) {
        BigDecimal exchangerate = BigDecimal.ZERO;
        if (yem_currencybase != null) {
            Date Min = DateUtils.getMinMonthDate(yem_fiedatets);
            Date max = DateUtils.getMaxMonthDate(yem_fiedatets);
            QFilter filter = new QFilter("yem_date", QCP.large_equals, Min)
                    .and(new QFilter("yem_date", QCP.less_equals, max));
            //查查询字段标
            String yem_curr = yem_currencybase.getString("number");
            String Fileid = "yem_" + yem_curr.toLowerCase();//将字段标识转换为小写
            DynamicObject[] erpcurrency = BusinessDataServiceHelper.load("yem_bd_centralrate",
                    "id,name,number,yem_date," + Fileid + "",
                    new QFilter[]{filter}, "yem_date");
            if (erpcurrency != null && erpcurrency.length > 0) {
                DynamicObject yem_ca_billlogon = erpcurrency[0];
                if (yem_ca_billlogon != null) {
                    exchangerate = BigDecimalUtils.toBigDecimal(yem_ca_billlogon.getString(Fileid)).divide(BigDecimalUtils.one_handred);
                }
            }
        }
        return exchangerate;
    }

    public BigDecimal YBZAmt(String yem_feemarkname, Date yem_fiedatets, BigDecimal yem_feerate, DynamicObject yem_feecurrbase, BigDecimal yem_sumdecltotal, BigDecimal grosswt) {
        BigDecimal amt = BigDecimal.ZERO;
        if (yem_feecurrbase != null) {
            BigDecimal yem_feecurrexchangerate = exchangerate(yem_fiedatets, yem_feecurrbase);//运费汇率
            if (yem_feemarkname.equals("单价")) {
                BigDecimal yem_grosswt = grosswt.divide(BigDecimalUtils.one_thousand);//毛重
                amt = yem_grosswt.multiply(yem_feerate).multiply(yem_feecurrexchangerate);
            } else if (yem_feemarkname.equals("率")) {
                BigDecimal feerate = yem_feerate.divide(BigDecimalUtils.one_handred);
                amt = yem_sumdecltotal.multiply(feerate).multiply(yem_feecurrexchangerate);
            } else if (yem_feemarkname.equals("总价")) {
                amt = yem_feerate.multiply(yem_feecurrexchangerate);
            }
        }
        return amt;
    }

    public String XMLTOJosn(String xmltext)
    {
        String josn = null;
        try {
            org.json.JSONObject jsonObject = XML.toJSONObject(xmltext);
            String jsonString = jsonObject.toString();
            return jsonString;
        }
        catch (Exception e)
        {
            josn = "XML 转 josn 转换失败";
            return josn;
        }
    }

}