package nc.bs.so.m30.rule.approve;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Log;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.vo.bd.balatype.BalaTypeVO;
import nc.vo.bd.currtype.CurrtypeVO;
import nc.vo.bd.cust.CustomerVO;
import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.bd.material.MaterialVO;
import nc.vo.bd.material.measdoc.MeasdocVO;
import nc.vo.bd.psn.PsndocVO;
import nc.vo.org.SalesOrgVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.billtype.BilltypeVO;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.pub.SqlBuilder;
import nc.vo.so.m30.entity.SaleOrderVO;
import nc.vo.so.m30.entity.SaleOrderHVO;
import nc.vo.so.m30.entity.SaleOrderBVO;
import nc.vo.vorg.DeptVersionVO;
import nccloud.pubift.commen.itf.utils.IHttpPostOtherSys;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

/**
 * 销售订单审批后推送MES金思维系统
 */
public class AfterApprovingSynchronizeRuleMES implements IRule<SaleOrderVO> {
    private static final String SALE_ORDER_URL = "/GTHINKING/AjaxService/N_XSSJJSA/102397000.ashx/XSDD_INSERT"; // 销售订单同步接口
    private static final String logginfo = "OALOG";
    private static final Log obmlog = Log.getInstance(logginfo);
    private static final BaseDAO dao = new BaseDAO();
    // 初始化HTTP请求工具类
    IHttpPostOtherSys httpPostOtherSys = NCLocator.getInstance().lookup(IHttpPostOtherSys.class);

    public AfterApprovingSynchronizeRuleMES() {
    }

    @Override
    public void process(SaleOrderVO[] saleOrderVOs) {
        try {
            if (saleOrderVOs == null || saleOrderVOs.length == 0) {
                obmlog.debug("AfterApprovingSynchronizeRuleMES-没有需要处理的销售订单");
                return;
            }
            // 筛选组织为电缆的销售订单
            List<SaleOrderVO> filteredSaleOrderVOS = checkAndFilterBills(saleOrderVOs);
            if (filteredSaleOrderVOS.isEmpty()) {
                obmlog.debug("AfterApprovingSynchronizeRuleMES-没有需要处理的组织为电缆的需要同步的销售订单");
                return;
            }
            // 处理每个销售订单
            for (SaleOrderVO saleOrderVO : filteredSaleOrderVOS) {
                SaleOrderHVO head = saleOrderVO.getParentVO();
                SaleOrderBVO[] bodys = saleOrderVO.getChildrenVO();
                // 构建要发送的数据
                JSONObject syncData = buildSyncData(head, bodys);
                // 发送数据到金思维系统
                httpPostOtherSys.sendToExternalSystem(SALE_ORDER_URL, syncData);
            }
        } catch (Exception e) {
            obmlog.error("AfterApprovingSynchronizeRuleMES-处理异常:" + e.getMessage(), e);
            ExceptionUtils.wrappException(e);
        }
    }


    /**
     * 构建符合金思维系统接口规范的请求数据
     */
    private JSONObject buildSyncData(SaleOrderHVO head, SaleOrderBVO[] bodys) throws BusinessException {
        obmlog.debug("AfterApprovingSynchronizeRuleMES-开始处理销售订单: " + head.getVbillcode());
        // 创建请求数据
        JSONObject requestData = new JSONObject();
        JSONObject data = new JSONObject();
        // 销售订单号 这里超长了 改为手动输入
        data.put("orderNo", head.getVbillcode());
        // 客户订单号
        data.put("customOrderNo", null);
        // 订单日期（必填，格式为YYYY-MM-DD）
        UFDate dbilldate = head.getDbilldate();
        data.put("orderDate", dbilldate != null ? dbilldate.toString().substring(0, 10) : null);
        // 订单类别（非必填）
        data.put("orderType", transferCodeByPk(BilltypeVO.TABLENAME, BilltypeVO.PK_BILLTYPECODE, BilltypeVO.PK_BILLTYPE_ID, head.getCtrantypeid()));
        // 生成方式
        data.put("generation", "Z");
        // 客户编码（必填，最大长度8）
        String customerCode = transferCodeByPk(CustomerVO.getDefaultTableName(), CustomerVO.CODE, CustomerVO.PK_CUSTOMER, head.getCcustomerid());
        data.put("customId", customerCode);
        data.put("seller", transferCodeByPk(PsndocVO.getDefaultTableName(), PsndocVO.NAME, PsndocVO.PK_PSNDOC, head.getCemployeeid()));
        // 销售部门编码（必填，最大长度8）
        String deptCode = transferCodeByPk(DeptVersionVO.getDefaultTableName(), DeptVersionVO.CODE, DeptVersionVO.PK_VID, head.getCdeptvid());
        data.put("departmentId", deptCode);
        // 联系人（非必填）
        data.put("contacts", null);
        // 联系电话（非必填）
        data.put("contactNum", null);
        // "X"或"S" 这里只翻译了code 还需要判断
        data.put("settlementType", transferCodeByPk(BalaTypeVO.getDefaultTableName(), BalaTypeVO.CODE, BalaTypeVO.PK_BALATYPE, head.getCbalancetypeid()));
        // 货币（必填，最大长度3）
        String currencyCode = transferCodeByPk(CurrtypeVO.getDefaultTableName(), CurrtypeVO.CODE, CurrtypeVO.PK_CURRTYPE, head.getCorigcurrencyid());
        data.put("currency", currencyCode);
        // 汇率 表体nexchangerate
        data.put("exchangeRate", 1);
        // 其他非必填字段一律设为null
        data.put("priceListId", null);
        data.put("invoicingUnit", transferCodeByPk(CustomerVO.getDefaultTableName(), CustomerVO.CODE, CustomerVO.PK_CUSTOMER, head.getCinvoicecustid()));
        data.put("contractNo", null);
        data.put("projectNo", null);
        data.put("salesAreaId", null);
        data.put("deliveryAreaId", null);
        data.put("discount", null);
        data.put("paymentType", null);
        data.put("warranty", null);
        data.put("retentionAmount", null);
        data.put("prepayment", null);
        data.put("payment", null);
        data.put("salesChannels", null);
        data.put("transportMode", null);
        data.put("transportProxy", null);
        data.put("packing", null);
        data.put("deliveryAddress", null);
        data.put("labelDemand", null);
        data.put("skillsDemand", null);
        data.put("contractType", null);
        data.put("deliveryRemarks", null);
        data.put("remarks", head.getVnote());
        // 构建明细数据 - 只填必填字段
        JSONArray details = new JSONArray();
        if (bodys != null) {
            for (SaleOrderBVO body : bodys) {
                JSONObject detailItem = new JSONObject();
                detailItem.put("productNum", transferCodeByPk("bd_defdoc", DefdocVO.CODE, DefdocVO.PK_DEFDOC, body.getVbdef1()));
                // 以下字段需要表体的字段
                // 需求日期 表体dreceivedate
                UFDate dreceivedate = body.getDreceivedate();
                data.put("demandDate", dreceivedate != null ? dreceivedate.toString().substring(0, 10) : null);
                // 计划发货日期 表体dsenddate
                UFDate dsenddate = body.getDsenddate();
                data.put("deliveryDate", dsenddate != null ? dsenddate.toString().substring(0, 10) : null);
                // 以下表体所需字段
                // 序号
                detailItem.put("sequenceNum", body.getCrowno());
                // 合同序号
                detailItem.put("contractNum", null);
                // 物料编码
                String materialCode = transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, body.getCmaterialvid());
                detailItem.put("materialId", materialCode);
                // 计量单位
                detailItem.put("unit", transferCodeByPk(MeasdocVO.getDefaultTableName(), MeasdocVO.CODE, MeasdocVO.PK_MEASDOC, body.getCunitid()));
                // 换算系数
                detailItem.put("scaleFactor", body.getVchangerate() != null ? transferSpecialField(body.getVchangerate()) : null);
                // 增值税率
                UFDouble taxRate = body.getNtaxrate();
                detailItem.put("vatRate", taxRate != null ? taxRate.toString() : null);
                // 需求数量
                UFDouble num = body.getNastnum();
                detailItem.put("quantity", num != null ? num.getDouble() : null);
                // 主需求数量
                UFDouble mainNum = body.getNnum();
                detailItem.put("mainQuantity", mainNum != null ? mainNum.getDouble() : null);
                // 含税价格
                UFDouble taxPrice = body.getNqtorigtaxprice();
                detailItem.put("price", taxPrice != null ? taxPrice.getDouble() : null);
                // 含税金额
                UFDouble taxAmount = body.getNorigtaxmny();
                detailItem.put("amount", taxAmount != null ? taxAmount.getDouble() : null);
                // 无税单价
                UFDouble noTaxPrice = body.getNqtorigprice();
                detailItem.put("noTaxPrice", noTaxPrice != null ? noTaxPrice.getDouble() : null);
                // 无税金额
                UFDouble noTaxAmount = body.getNorigmny();
                detailItem.put("noTaxAmount", noTaxAmount != null ? noTaxAmount.getDouble() : null);
                UFDate dreceivedate1 = body.getDreceivedate();
                detailItem.put("demandDate", dreceivedate1 != null ? dreceivedate1.toString().substring(0, 10) : null);
                UFDate dsenddate1 = body.getDsenddate();
                detailItem.put("deliveryDate", dsenddate1 != null ? dsenddate1.toString().substring(0, 10) : null);
                // 传递电缆公司的组织编码
                detailItem.put("factoryId", transferCodeByPk(SalesOrgVO.getDefaultTableName(), SalesOrgVO.CODE, SalesOrgVO.PK_SALESORG, head.getPk_org()));
                detailItem.put("customMtId", null);

                // 销售订单新增两个字段 vbdef22-->MES客户订单号 vbdef13-->MES客户订单序号
                detailItem.put("customNo", body.getVbdef22()); // 客户订单号
                detailItem.put("customSN", body.getVbdef13()); // 客户订单序号
                // 添加是否定制
                detailItem.put("customized", body.getVbdef18());
                detailItem.put("remarks", null);
                // 添加自定义行号
                JSONArray properties = new JSONArray();
                JSONObject property = new JSONObject();
                // 行号
                property.put("propertyFiled", "SXZF15");
                property.put("propertyValue", body.getCsaleorderbid());
                // 新增三个字段属性 销售订单交易类型编码
                JSONObject property1 = new JSONObject();
                JSONObject property2 = new JSONObject();
                property1.put("propertyFiled", "SXZF19");
                property1.put("propertyValue", head.getVtrantypecode()); // 订单类型编码
                // 销售订单主键
                property2.put("propertyFiled", "SXZF20");
                property2.put("propertyValue", head.getCsaleorderid()); // 表头主键
                properties.add(property);
                properties.add(property1);
                properties.add(property2);
                detailItem.put("properties", properties);
                details.add(detailItem);
            }
        }
        data.put("DETAILS", details);
        requestData.put("Data", data);
        return requestData;
    }

    /**
     * 检查订单是否符合同步条件
     */
    private List<SaleOrderVO> checkAndFilterBills(SaleOrderVO[] saleOutVOS) {
        List<SaleOrderVO> result = new ArrayList<>();
        for (SaleOrderVO vo : saleOutVOS) {
            try {
                String code = transferCodeByPk(SalesOrgVO.getDefaultTableName(), SalesOrgVO.CODE, SalesOrgVO.PK_SALESORG, vo.getParentVO().getPk_org());
                if (httpPostOtherSys.checkIfIncludeOrg(code)) {
                    result.add(vo);
                }
            } catch (BusinessException e) {
                ExceptionUtils.wrappBusinessException("查询组织时出现问题");
            }
        }
        return result;
    }


    /**
     * 转换特殊字段  如 1/1 转换为小数 1.0
     */

    private String transferSpecialField(String field) {
        if (field == null || field.trim().isEmpty()) {
            return null;
        }
        String[] split = field.split("/");
        if (split.length == 2) {
            String numStr = split[0].trim();
            String denStr = split[1].trim();
            if (denStr.equals("0")) {
                return "0.00"; // 分母不能为零
            }
            try {
                BigDecimal numerator = new BigDecimal(numStr);
                BigDecimal denominator = new BigDecimal(denStr);
                return numerator.divide(denominator, 2, RoundingMode.HALF_UP).toString();
            } catch (NumberFormatException e) {
                return field; // 非法数字，返回原字段
            }
        }
        return field;
    }

    /**
     * 根据主键查询编码
     */
    private String transferCodeByPk(String tableName, String selectField, String pkField, String pk) throws BusinessException {
        if (pk == null || pk.trim().isEmpty()) {
            return null;
        }
        SqlBuilder sqlBuilder = new SqlBuilder();
        sqlBuilder.append(" select " + selectField);
        sqlBuilder.append(" from " + tableName);
        sqlBuilder.append(" where ");
        sqlBuilder.append(pkField, pk);
        Object o = dao.executeQuery(sqlBuilder.toString(), new ColumnProcessor());
        if (o == null) {
            throw new BusinessException("未查询到编码信息，sql【" + sqlBuilder + "】");
        }
        return o.toString();
    }
}
