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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import nc.bs.dao.BaseDAO;
import nc.bs.logging.Log;
import nc.bs.uapbd.util.ThirdPartyPostRequestUtil;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.pubitf.para.SysInitQuery;

import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.cmp.util.StringUtils;
import nc.vo.ic.m4c.entity.SaleOutBodyVO;
import nc.vo.ic.m4c.entity.SaleOutHeadVO;
import nc.vo.ic.m4c.entity.SaleOutVO;
import nc.vo.org.OrgVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
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.MathTool;
import nc.vo.pubapp.pattern.pub.SqlBuilder;
import nc.vo.scmpub.util.ArrayUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * @Classname AfterSigningSynchronizeRuleRZ
 * @Description TODO
 * @Version 1.0.0
 * @Date 2025/5/16 9:01
 * @Created by ame
 */
public class AfterSigningSynchronizeRuleRZ implements IRule<SaleOutVO> {
    private static Log log = Log.getInstance("rzmomlog");

    private static BaseDAO dao = new BaseDAO();

    @Override
    public void process(SaleOutVO[] saleOutVOS) {
        if (ArrayUtil.isEmpty(saleOutVOS)) {
            return;
        }
        try {
            //检查并筛选销售出库单据为互感器公司
            List<SaleOutVO> newSaleOutVOS = checkAndFilterBillSrcOrg(saleOutVOS);
            if (newSaleOutVOS == null || newSaleOutVOS.size() < 1) {
                return;
            }
            pushToRZMOM(newSaleOutVOS.toArray(new SaleOutVO[0]));
        } catch (Exception e) {
            log.error("同步销售出库到锐制系统失败: " + e.getMessage(), e);
            ExceptionUtils.wrappException(e);
        }
    }

    private List<SaleOutVO> checkAndFilterBillSrcOrg(SaleOutVO[] saleOutVOS) throws BusinessException {
        List<SaleOutVO> aggvoList = new ArrayList<>();
        for (SaleOutVO aggvo : saleOutVOS) {
            String pkOrg = aggvo.getHead().getPk_org();
            String orgCode = transferCodeByPk(OrgVO.getDefaultTableName(), OrgVO.CODE, OrgVO.PK_ORG, pkOrg);
            if ("C022".equals(orgCode) && aggvo.getBodys() != null && aggvo.getBodys().length > 0) {
                aggvoList.add(aggvo);
            }
        }
        return aggvoList;
    }

    private void pushToRZMOM(SaleOutVO[] saleOutVOS) throws BusinessException {
        String rzwmsip = SysInitQuery.getParaString("GLOBLE00000000000000", "RZWMSIP");
        JSONObject jsonObject = new JSONObject();
        JSONObject data = new JSONObject();
        JSONObject dataIn = new JSONObject();
        JSONObject dataIn2 = new JSONObject();
        JSONArray details = new JSONArray();
        //根据行数量正负拆分数组-并判断
        UFBoolean isPosValue=checkNumSymbol(saleOutVOS);
        //单笔/批量按明细传
        for (SaleOutVO saleOutVO : saleOutVOS) {
            SaleOutHeadVO head = saleOutVO.getHead();
            SaleOutBodyVO[] bodys = saleOutVO.getBodys();
            // 构建需要同步的数据
            buildSyncData(head, bodys, details,isPosValue);

        }
        if(isPosValue.booleanValue()){
            //正向
            jsonObject.put("dataflow", "用友BIP→RZMOMv6");
            jsonObject.put("actionCode", "cpfhtzdb");
        }else{
            //反向
            jsonObject.put("dataflow", "用友BIP→RZMOMv6");
            jsonObject.put("actionCode", "thsqb");
        }
        dataIn2.put("Details", details);
        dataIn.put("Data", dataIn2);
        data.put("data", dataIn);
        jsonObject.put("data", data);
        log.error("销售出库签字推送锐制请求报文：" + jsonObject.toJSONString());
        String result = ThirdPartyPostRequestUtil.sendPostRequest(rzwmsip, jsonObject.toJSONString());
        JSONObject resultObj = JSONObject.parseObject(result);
        if ("false".equals(resultObj.getString("success"))) {
            throw new BusinessException("RZMOM同步失败，原因：" + resultObj.getString("msg"));
        } else {
            log.error("RZMOM同步成功，返回参数【" + resultObj.toJSONString() + "】");
        }
    }

    private UFBoolean checkNumSymbol(SaleOutVO[] saleOutVOS) throws BusinessException {
        UFBoolean hasPositive = UFBoolean.FALSE;
        UFBoolean hasNegative = UFBoolean.FALSE;

        for (SaleOutVO saleOutVO : saleOutVOS) {
            SaleOutBodyVO[] bodys = saleOutVO.getBodys();
            for (SaleOutBodyVO body : bodys){
                if(MathTool.compareTo(body.getNshouldassistnum(), UFDouble.ZERO_DBL)>=0){
                    hasPositive=UFBoolean.TRUE;
                }else{
                    hasNegative=UFBoolean.TRUE;
                }
            }
        }
        if(hasPositive.booleanValue()&&hasNegative.booleanValue()){
            throw new BusinessException("销售出库签字推送锐制失败，原因：签字不允许存在正负数量的单据");
        }
        return hasPositive;
    }

    private void buildSyncData(SaleOutHeadVO head, SaleOutBodyVO[] bodys, JSONArray details,UFBoolean isPosValue) throws BusinessException {

        String vbillcode = head.getVbillcode();//单据号
        String vtrantypecode = head.getVtrantypecode();//出入库类型编码
        //部门
//        String cdptCode =transferCodeByPk(DeptVO.getDefaultTableName(), DeptVO.CODE,DeptVO.PK_DEPT,head.getCdptid());

        for (SaleOutBodyVO body : bodys) {
            JSONObject singleObj = new JSONObject();
            String cgeneralhid = body.getCgeneralhid();//表头主键
            String cgeneralbid = body.getCgeneralbid();//表体主键
            String crowno = body.getCrowno();//行号
            String cmaterialvid = body.getCmaterialvid();//物料
            String casscustid = body.getCasscustid();//客户
            String cbodywarehouseid = body.getCbodywarehouseid();//仓库
            UFDate dbizdate = body.getDbizdate();//出库日期
            singleObj.put("wbid", cgeneralhid + "_" + cgeneralbid + "_" + vtrantypecode);//第三方系统主键id
            singleObj.put("wbpid", cgeneralhid);//第三方系统分组id
            singleObj.put("operate", 1);//operate	int	操作状态	必填	1新增/修改、2删除（删除时只需上传wbid）
            if(isPosValue.booleanValue()){
                singleObj.put("djly", 1013);//djly	varchar(20)	来源单据
            }else {
                singleObj.put("djly", 1012);//djly	varchar(20)	来源单据
            }

            singleObj.put("djbh_id", cgeneralhid);//单据id
            singleObj.put("djbh", vbillcode);//单据编号
            singleObj.put("djxh", crowno);//单据序号
            singleObj.put("djrq", dbizdate.toString());//单据日期--出库日期


            //第三方系统物料名称id--编码
            singleObj.put("wlbm_wbid", cmaterialvid);


            if(isPosValue.booleanValue()){
                //单据数量
                singleObj.put("djsl", body.getNshouldassistnum().getDouble());
            }else {
                //单据数量
                singleObj.put("djsl", MathTool.abs(body.getNshouldassistnum()).getDouble()); //负数取绝对值
            }
            //第三方系统客户id--编码
            singleObj.put("khbh_wbid", casscustid);
            //订单编号
            singleObj.put("ddbh", body.getVsourcebillcode());
            //订单序号
            singleObj.put("ddxh", body.getVsourcerowno());
            //送达地点-code
            singleObj.put("sddd", cbodywarehouseid);
            //第三方系统仓库id -code
            singleObj.put("ckbh_wbid", cbodywarehouseid);
            //部门
            singleObj.put("bzsm", head.getCdptid());

            // 添加两个字段 项目号 和 项目名称 使用 vbdef1 和 vbdef10
            singleObj.put("wlzdycs06", transferCodeByPk("bd_defdoc", DefdocVO.CODE, DefdocVO.PK_DEFDOC, body.getVbdef1()));
            singleObj.put("wlzdycs11", body.getVbdef10());
            //签发标记
            singleObj.put("qfbj", 1);
            //操作状态  1新增/修改、2删除（删除时只需上传wbid）
            singleObj.put("operate", 1);
            details.add(singleObj);
        }
    }


    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();
    }

}
