package nc.bs.ic.m45.sign.rule;

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.material.MaterialVO;
import nc.vo.bd.material.measdoc.MeasdocVO;
import nc.vo.bd.psn.PsndocVO;
import nc.vo.bd.stordoc.StordocVO;
import nc.vo.bd.supplier.SupplierVO;
import nc.vo.cmp.util.StringUtils;
import nc.vo.ic.m45.entity.PurchaseInVO;
import nc.vo.ic.m45.entity.PurchaseInBodyVO;
import nc.vo.ic.m45.entity.PurchaseInHeadVO;
import nc.vo.org.StockOrgVO;
import nc.vo.pub.BusinessException;
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.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 PurchaseReceiptRuleMES implements IRule<PurchaseInVO> {
    private static final String PURCHASE_IN_URL = "/GTHINKING/AjaxService/N_CGSJJSA/102223002.ashx/CGSH_INSERT"; // 采购收货单同步接口
    private static final String PURCHASE_DELETE_URL = "/GTHINKING/AjaxService/N_CGSJJSA/102223002.ashx/CGSH_DELETE"; // 采购收货单删除接口
    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);

    @Override
    public void process(PurchaseInVO[] purchaseInVOS) {
        try {
            if (purchaseInVOS == null || purchaseInVOS.length == 0) {
                obmlog.debug("AfterSigningSynchronizeRuleMES-没有需要处理的采购收货单");
                return;
            }
//            // 检查并筛选组织为电缆的采购收货单
            List<PurchaseInVO> filteredPurchaseInVOS = checkAndFilterBills(purchaseInVOS);
            if (filteredPurchaseInVOS.isEmpty()) {
                obmlog.debug("AfterSigningSynchronizeRuleMES-没有需要处理的需要同步的组织为电缆的采购收货单");
                return;
            }
            // 处理每个采购收货单
            for (PurchaseInVO purchaseInVO : filteredPurchaseInVOS) {
                PurchaseInHeadVO head = purchaseInVO.getHead();
                PurchaseInBodyVO[] bodys = purchaseInVO.getBodys();
                // 每次新增采购收货单前，先删除第三方系统中已有的数据，再进行新增
                String orderNo = head.getVbillcode();
                boolean deleteSuccess = deletePurchaseReceipt(orderNo);
                if (deleteSuccess) {
                    // 构建要发送的数据
                    JSONObject syncData = buildSyncData(head, bodys);
                    // 发送数据到MES系统
                    obmlog.debug("PurchaseReceiptRuleMES-准备发送采购收货单数据: " + orderNo);
                    httpPostOtherSys.sendToExternalSystem(PURCHASE_IN_URL, syncData);
                }
            }
        } catch (Exception e) {
            obmlog.error("AfterSigningSynchronizeRuleMES-处理异常:" + e.getMessage(), e);
            ExceptionUtils.wrappException(e);
        }
    }

    /**
     * 删除第三方系统中的采购收货单
     *
     * @param orderNo 要删除的采购收货单号
     * @return 删除操作是否成功
     * @throws BusinessException 业务异常
     */
    public boolean deletePurchaseReceipt(String orderNo) throws BusinessException {
        try {
            if (orderNo == null || orderNo.trim().isEmpty()) {
                throw new BusinessException("采购收货单号不能为空");
            }

            obmlog.debug("PurchaseReceiptRuleMES-准备删除第三方系统采购收货单: " + orderNo);

            // 构建请求数据
            JSONObject requestData = new JSONObject();
            JSONObject dataObj = new JSONObject();
            dataObj.put("orderNo", orderNo);
            requestData.put("Data", dataObj);

            // 初始化HTTP请求工具类
            IHttpPostOtherSys httpPostOtherSys = NCLocator.getInstance().lookup(IHttpPostOtherSys.class);

            // 发送删除请求
            String response = httpPostOtherSys.callMes(PURCHASE_DELETE_URL, requestData);
            obmlog.debug("PurchaseReceiptRuleMES-删除请求返回结果: " + response);

            // 解析返回结果
            JSONObject jsonResponse = JSONObject.parseObject(response);
            boolean isSuccess = jsonResponse.getBooleanValue("Success");
            String errorMessage = jsonResponse.getString("ErrorMessage");

            if (!isSuccess) {
                obmlog.error("PurchaseReceiptRuleMES-删除采购收货单失败: " + orderNo + ", 错误信息: " + errorMessage);
                throw new BusinessException("删除采购收货单失败: " + (errorMessage != null ? errorMessage : "未知错误"));
            }

            obmlog.debug("PurchaseReceiptRuleMES-成功删除采购收货单: " + orderNo);
            return true;
        } catch (Exception e) {
            obmlog.error("PurchaseReceiptRuleMES-删除采购收货单异常:" + e.getMessage(), e);
            throw new BusinessException("删除采购收货单时发生异常: " + e.getMessage(), e);
        }
    }

    /**
     * 检查并筛选需要同步的单据
     */
    private List<PurchaseInVO> checkAndFilterBills(PurchaseInVO[] purchaseInVOS) {
        List<PurchaseInVO> result = new ArrayList<>();
        for (PurchaseInVO vo : purchaseInVOS) {
            try {
                String code = transferCodeByPk(StockOrgVO.getDefaultTableName(), StockOrgVO.CODE, StockOrgVO.PK_STOCKORG, vo.getParentVO().getPk_org());
                if (httpPostOtherSys.checkIfIncludeOrg(code)) {
                    result.add(vo);
                }
            } catch (BusinessException e) {
                ExceptionUtils.wrappBusinessException("查询组织时发生错误");
            }
        }
        return result;
    }

    /**
     * 构建符合MES系统接口规范的请求数据
     */
    private JSONObject buildSyncData(PurchaseInHeadVO head, PurchaseInBodyVO[] bodys) throws BusinessException {
        // 创建请求数据
        JSONObject requestData = new JSONObject();
        JSONObject data = new JSONObject();
        // 设置收货单主表信息
        // 收货单号（必填）- 映射为vbillcode
        data.put("orderNo", head.getVbillcode());
        // 收货日期 - 映射为dbilldate (格式：yyyy-MM-dd)
        UFDate dbilldate = head.getDbilldate();
        data.put("orderDate", dbilldate != null ? dbilldate.toString().substring(0, 10) : null);
        // 收货类型 - 默认为"P"(外购)
        data.put("orderType", "P");
        // 事务类型
        data.put("type", "WGRK");
        // 仓库编码 - 映射为cwarehouseid
        data.put("storeId", transferCodeByPk(StordocVO.getDefaultTableName(), StordocVO.CODE,
                StordocVO.PK_STORDOC, head.getCwarehouseid()));
        // 采购部门ID（必填）- 映射为cdptvid
        data.put("departmentId", transferCodeByPk(DeptVersionVO.getDefaultTableName(), DeptVersionVO.CODE,
                DeptVersionVO.PK_VID, head.getCdptvid()));
        // 采购员 - 映射为cbizid
        String purchaser = transferCodeByPk(PsndocVO.getDefaultTableName(), PsndocVO.CODE,
                PsndocVO.PK_PSNDOC, head.getCbizid());
        data.put("purchaser", purchaser);
        // 供应商编码（必填）- 映射为cvendorid
        String supplyId = transferCodeByPk(SupplierVO.getDefaultTableName(), SupplierVO.CODE,
                SupplierVO.PK_SUPPLIER, head.getCvendorid());
        data.put("supplyId", supplyId);
        // 货币 - 暂无明确映射
        data.put("currency", "CNY");
        //汇率（必填）
        data.put("rate", 1);
        // 结算方式 - 默认为"S"(转账)
        data.put("settleType", "S");
        // 开票依据 - 默认为"S"(实收数)
        data.put("billBasis", "S");
        // 生成方式（必填）- 默认为"P"(按采购订单)
        data.put("genType", "P");
        // 分类（必填）- 默认为"N"(货物)
        data.put("costOrder", "N");
        // 是否退货（必填）- 映射为freplenishflag，如果为Y则为退货
        data.put("returned", head.getFreplenishflag() == null ? head.getFreplenishflag().booleanValue() : null);
        // 备注 - 映射为vnote
        data.put("remark", head.getVnote());
        // 维护人信息
        data.put("creatorNo", null); // 创建人工号
        data.put("creator", head.getBillmaker()); // 制单人
        data.put("creatTime", head.getDmakedate() != null ? head.getDmakedate().toString() : null); // 创建时间
        // 构建明细数据
        JSONArray details = new JSONArray();
        if (bodys != null) {
            for (PurchaseInBodyVO body : bodys) {
                JSONObject detailItem = new JSONObject();
                // 收货单号（必填）- 在buildSyncData方法中设置
                detailItem.put("orderNo", head.getVbillcode());
                // 收货单序号（必填）- 映射为行号(crowno)
                detailItem.put("orderSn", body.getCrowno());
                // 事务类型（必填）- 使用表体字段cbodytranstypecode
                detailItem.put("type", "WGRK");
                // 分类（必填）- 默认设置为"H" - H:货款, F:费用, L:劳务
                detailItem.put("costOrder", "H");
                // 采购订单号 - 来源单据号(vsourcebillcode)
                detailItem.put("poNo", body.getVsourcebillcode());
                // 采购订单序号 - 来源单据行号(vsourcerowno)
                detailItem.put("poSn", body.getVsourcerowno());
                // 物料编码（必填）- 映射为cmaterialvid
                String materialCode = transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE,
                        MaterialVO.PK_MATERIAL, body.getCmaterialvid());
                detailItem.put("materialId", materialCode);
                // 计量单位（必填）- 映射为castunitid而不是cunitid
                detailItem.put("unit", transferCodeByPk(MeasdocVO.getDefaultTableName(), MeasdocVO.CODE,
                        MeasdocVO.PK_MEASDOC, body.getCastunitid()));
                // 物料批号 - 映射为vbatchcode
                detailItem.put("batchNum", body.getVbatchcode());
                // 制令号 - 在BIP系统中没有对应字段，可以从自定义字段获取
                detailItem.put("productNum", body.getVbdef1()); // 假设存储在自定义字段1中
                // 换算系数（必填）- 映射为vchangerate
                String scaleFactor = body.getVchangerate();
                detailItem.put("scaleFactor", transferSpecialField(scaleFactor));
                // 税率（必填）- 映射为ntaxrate
                UFDouble taxRate = body.getNtaxrate();
                detailItem.put("taxRate", taxRate != null ? taxRate.doubleValue() : null);
                // 应收数量（必填）- 映射为nshouldassistnum
                UFDouble recQty = body.getNshouldassistnum();
                detailItem.put("recQty", recQty != null ? recQty.doubleValue() : null);
                // 主应收数量（必填）- 映射为nshouldnum
                UFDouble mainRecQty = body.getNshouldnum();
                detailItem.put("mainRecQty", mainRecQty != null ? mainRecQty.doubleValue() : null);
                // 辅应收数量 - 在BIP系统中没有明确对应字段
                detailItem.put("assitRecQty", null);
                // 原币含税价格 - 映射为npickupnum
                UFDouble priceIncludeTax = body.getNpickupnum();
                detailItem.put("priceIncludeTax", priceIncludeTax != null ? priceIncludeTax.doubleValue() : null);
                // 原币含税金额 - 映射为norigtaxmny
                UFDouble amountIncludeTax = body.getNorigtaxmny();
                detailItem.put("amountIncludeTax", amountIncludeTax != null ? amountIncludeTax.doubleValue() : null);
                // 原币无税价格 - 映射为norigprice
                UFDouble priceNoTax = body.getNorigprice();
                detailItem.put("priceNoTax", priceNoTax != null ? priceNoTax.doubleValue() : null);
                // 原币无税金额 - 映射为nqtnetprice
                UFDouble amountNoTax = body.getNqtnetprice();
                detailItem.put("amountNoTax", amountNoTax != null ? amountNoTax.doubleValue() : null);
                // 税额 - 映射为ntax
                UFDouble taxAmount = body.getNtax();
                detailItem.put("taxAmount", taxAmount != null ? taxAmount.doubleValue() : null);
                // 备注 - 映射为vnotebody
                detailItem.put("remark", body.getVnotebody());
                // 原收货单信息 - 如果是退货单，需要设置原单信息
                detailItem.put("oldOrderNo", null);
                detailItem.put("oldOrderSn", null);
                details.add(detailItem);
            }
        }
        data.put("Details", details);
        requestData.put("Data", data);
        obmlog.debug("PurchaseReceiptRuleMES-采购收货单请求数据: " + requestData.toJSONString());

        return requestData;
    }

    /**
     * 转换特殊字段  如 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 (StringUtils.isEmpty(pk)) {
            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();
    }
}
