package nc.bs.mmpac.pickm.bp.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.bs.uapbd.util.ThirdPartyPostRequestUtil;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.itf.bd.material.baseinfo.IMaterialBaseInfoQueryService;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.pubitf.para.SysInitQuery;
import nc.vo.bd.material.MaterialVO;
import nc.vo.cmp.util.StringUtils;
import nc.vo.mmpac.pickm.entity.AggPickmVO;
import nc.vo.mmpac.pickm.entity.PickmHeadVO;
import nc.vo.mmpac.pickm.entity.PickmItemVO;
import nc.vo.org.OrgVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.ISuperVO;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.pub.SqlBuilder;
import nc.vo.scmpub.util.ArrayUtil;
import nc.vo.util.CloneUtil;

import java.util.*;

public class AfterApproveRuleSyncRZWMS implements IRule<AggPickmVO> {

    private static Log log = Log.getInstance("rzmomlog");

    private static BaseDAO dao = new BaseDAO();

    @Override
    public void process(AggPickmVO[] vos) {
        if (ArrayUtil.isEmpty(vos)) {
            return;
        }
        try {
            AggPickmVO[] cloneOrderVOS = (AggPickmVO[]) CloneUtil.deepClone(vos);
            // 检查并筛选领料组织
            List<AggPickmVO> newAggPickmVOS = checkAndFilterBillSrcOrg(cloneOrderVOS);
            if (newAggPickmVOS.isEmpty()) {
                return;
            }
            Boolean is55A2=checkSrcBillType(newAggPickmVOS);
            if(is55A2){
                //来源生产订单
                pushToRZMOMBy55A2(newAggPickmVOS.toArray(new AggPickmVO[0]));
            }else{
                //来源委外订单
                pushToRZMOMBy61(newAggPickmVOS.toArray(new AggPickmVO[0]));
            }
        } catch (Exception e) {
            ExceptionUtils.wrappException(e);
        }
    }

    private Boolean checkSrcBillType(List<AggPickmVO> newAggPickmVOS) throws BusinessException {
        UFBoolean is61=UFBoolean.FALSE;
        UFBoolean is55A2=UFBoolean.FALSE;
        for (AggPickmVO aggPickmVO : newAggPickmVOS) {
            String vfirstbilltype = aggPickmVO.getParentVO().getVfirstbilltype();
            if("61".equals(vfirstbilltype)){
                is61=UFBoolean.TRUE;
            }else if("55A2".equals(vfirstbilltype)){
                is55A2=UFBoolean.TRUE;
            }
        }
        if(is55A2.booleanValue()&&is61.booleanValue()){
            throw new BusinessException("备料计划推送锐制失败，原因：不允许源头单据类型为生产订单和委外订单的单据同时审批");
        }
        return is55A2.booleanValue();
    }
    private void buildSyncDataBy55A2(PickmHeadVO head, PickmItemVO[] bodys, JSONArray details) throws BusinessException {
        Integer fsourcetype = head.getFsourcetype();
        if(fsourcetype!=0){
            return;
        }
        for (PickmItemVO body : bodys) {
            JSONObject singleObj = new JSONObject();
            String vsourcebillcode = head.getVsourcebillcode();
            String wlbm_wbid =body.getCbmaterialvid();

            String scgx_wbid =head.getVstdprocid();
            //wbid	varchar (200)	第三方系统主键id
            singleObj.put("wbid", head.getCpickmid()+"_"+body.getCpickm_bid()); // 第三方系统主键id
            //wbzbid	varchar (200)	第三方系统分组id
            singleObj.put("wbzbid", head.getCpickmid());
            //operate	int	操作状态	必填	1新增/修改、2删除（删除时只需上传wbid）
            singleObj.put("operate", "1");

            //wbqjpx	varchar(2000)	全局排序	必填	BOM表物料行号
            singleObj.put("wbqjpx", body.getVrowno());

            //scjh_wbid	varchar(100)	第三方系统生产计划ID	必填	生产计划号外部ID，一般ERP系统的生产订单号。
            singleObj.put("scjh_wbid", head.getCsourcebillid());

            //jhxh	numeric(5)	计划序号	-生产订单行号
            singleObj.put("jhxh", head.getVsourcebillrowno());

            singleObj.put("wlbm_wbid", wlbm_wbid); // 第三方系统材料id

            //bomlx	int	BOM类型	必填	默认=0，即传入生产BOM（1为包装BOM）。
            singleObj.put("bomlx", 0);

            singleObj.put("dwyl", body.getNunituseastnum().getDouble()); // 单位用量nunituseastnum
            singleObj.put("djyl", body.getNplanoutastnum().getDouble()); // 单据用量
            singleObj.put("clyl", body.getNplanoutastnum().getDouble()); // 材料用量

//            String rccode = transferCodeByPk(RcVO.getDefaultTableName(), RcVO.VRCCODE, RcVO.CRCID, head.getVstdprocid());
            singleObj.put("scgx_wbid", body.getVbdef11());
//            singleObj.put("scgx_wbid", rccode); // 第三方系统使用工序id

            //sdbj	int	锁定标记	必填	默认1：正常业务ERP审核后，传输至锐制MOM
            singleObj.put("sdbj", 1);
            //shbj	int	审核标记	必填	默认1：正常业务ERP审核后，传输至锐制MOM
            singleObj.put("shbj", 1);

            //jylxbm --
            singleObj.put("jylxbm", head.getVbusitype());
            details.add(singleObj);

        }
    }
    private void buildSyncDataBy61(PickmHeadVO head, PickmItemVO[] bodys, JSONArray details) throws BusinessException {
        Integer fsourcetype = head.getFsourcetype();
        if(fsourcetype!=1){
            return;
        }
        for (PickmItemVO body : bodys) {
            JSONObject singleObj = new JSONObject();
            String vsourcebillcode = head.getVsourcebillcode();
            String wlbm_wbid =body.getCbmaterialvid();

            String scgx_wbid =head.getVstdprocid();
            //wbid	varchar (200)	第三方系统主键id
            singleObj.put("wbid", head.getCpickmid()+"_"+body.getCpickm_bid()); // 第三方系统主键id
            //wbzbid	varchar (200)	第三方系统分组id
            singleObj.put("wbpid", head.getCpickmid());
            //operate	int	操作状态	必填	1新增/修改、2删除（删除时只需上传wbid）
            singleObj.put("operate", "1");
            //djly	varchar(20)	来源单据	必填	取值read_djlyb中编号
            //领料通知默认1011
            singleObj.put("djly", "1011");

            //_id	varchar(50)	单据id	必填	后台该单据类型的唯一ID
            singleObj.put("djbh_id", head.getCpickmid());

            //djbh	varchar(100)	单据编号	必填	前台单据编号
            singleObj.put("djbh", head.getVbillcode());

            //djxh	numeric(5)	单据序号	必填	前台单据序号
            singleObj.put("djxh", body.getVrowno());

            //djrq	datetime	单据日期	必填
            singleObj.put("djrq", head.getDmakedate().toString());

            //wlbm_wbid	varchar(100)	第三方系统物料名称id	必填	物料编码的后台ID
            singleObj.put("wlbm_wbid", wlbm_wbid);

            //djsl	numeric(18,3)	单据数量	必填
            UFDouble djsl = body.getNplanoutastnum() == null ? UFDouble.ZERO_DBL : body.getNplanoutastnum();
            singleObj.put("djsl", djsl.getDouble());

            //sddd	varchar(510)送达地点	必填	传仓库名称，要求上位ERP仓库名称不重复。
//            singleObj.put("sddd", transferCodeByPk(StordocVO.getDefaultTableName(), StordocVO.NAME, StordocVO.PK_STORDOC, body.getCoutstockid()));

            //ckbh_wbid	varchar(100)	第三方系统仓库id	必填	储区根据仓库默认，同仓库多储区时，两者必填；
//            singleObj.put("ckbh_wbid",body.getCoutstockid());

            //qfbj	int	签发标记	必填	默认1；上位系统审核传至MOM	1
            singleObj.put("qfbj", 1);

            //cght_wbid	varchar(100)	第三方系统合同id	必填	委外订单主键ID
            singleObj.put("cght_wbid",head.getCfirstbillid());
            //htbh	varchar(100)	合同号	 	委外订单单据号
            singleObj.put("htbh",head.getVfirstbillcode());

            //cght_wbid	varchar(100)	第三方系统合同id	必填
//            singleObj.put("cght_wbid", transferCodeByPk("bd_defdoc", DefdocVO.CODE, DefdocVO.PK_DEFDOC, body.getVbdef5()));
            details.add(singleObj);

        }
    }

    private List<AggPickmVO> checkAndFilterBillSrcOrg(AggPickmVO[] aggPickmVOS) throws BusinessException {
        List<AggPickmVO> aggvoList = new ArrayList<>();
        List<AggPickmVO> finalList = new ArrayList<>();

        for (AggPickmVO aggvo : aggPickmVOS) {
            String pkOrg = aggvo.getParentVO().getPk_org();
            String orgCode = transferCodeByPk(OrgVO.getDefaultTableName(), OrgVO.CODE, OrgVO.PK_ORG, pkOrg);
            //过滤上游不是生产订单和委外订单的备料计划
            String vfirstbilltype = aggvo.getParentVO().getVfirstbilltype();
            String vdef20 = aggvo.getParentVO().getVdef20();
            if(vdef20==null||"N".equals(vdef20)){
                if ("C022".equals(orgCode)&& 1 == aggvo.getParentVO().getFbillstatus()&&aggvo.getChildrenVO()!=null && aggvo.getChildrenVO().length > 0) {
                    if("61".equals(vfirstbilltype)||"55A2".equals(vfirstbilltype)){
                        //2025年7月2日10点33分--新增不传--表体物料编码前三位为103时不传
                        //获取表体物料信息
                        aggvoList.add(aggvo);
                    }
                }
            }

        }
        //再次筛选
        //2025年7月2日10点33分--新增不传--表体物料编码前三位为103时不传
        //获取表体物料信息
        if(aggvoList.isEmpty()){
            return aggvoList;
        }
        Set<String> materialpks=new HashSet<>();
        for (AggPickmVO aggvo : aggvoList) {
            PickmItemVO[] items = (PickmItemVO[]) aggvo.getChildren(PickmItemVO.class);
            for (PickmItemVO item : items) {
                String cbmaterialvid = item.getCbmaterialvid();
                materialpks.add(cbmaterialvid);
            }
        }
        if(materialpks.isEmpty()){
            return aggvoList;
        }
        //根据物料id查询物料信息
        MaterialVO[] vos = NCLocator.getInstance().lookup(IMaterialBaseInfoQueryService.class).queryDataByPks(materialpks.toArray(new String[0]));
        //组装Map
        Map<String, String> materialMap = new HashMap<>();
        if(vos==null || vos.length<1){
            throw new BusinessException("Failed to query material info , please check !!!");
        }
        for (MaterialVO vo : vos) {
            String cmaterialvid = vo.getPk_material();
            String cmaterialcode =vo.getCode();
            materialMap.put(cmaterialvid, cmaterialcode);
        }
        //筛选行数据
        for (AggPickmVO aggvo : aggvoList) {
            List<PickmItemVO> newItems = new ArrayList<>();
            PickmItemVO[] items = (PickmItemVO[]) aggvo.getChildren(PickmItemVO.class);
            for (PickmItemVO item : items) {
                String cmaterialvid = item.getCbmaterialvid();
                if (materialMap.containsKey(cmaterialvid)) {
                    String materialCode = materialMap.get(cmaterialvid);
                    if(!materialCode.startsWith("103")){
                        newItems.add(item);
                    }
                }
            }
            if (!newItems.isEmpty()) {
                aggvo.setChildren(PickmItemVO.class,newItems.toArray(new PickmItemVO[0]));
                finalList.add(aggvo);
            }
        }
        return finalList;
    }

    private void pushToRZMOMBy55A2(AggPickmVO[] aggPickmVOS) throws BusinessException {
        String rzwmsip = SysInitQuery.getParaString("GLOBLE00000000000000", "RZWMSIP");
        JSONObject jsonObject = new JSONObject();
        JSONObject dataIn = new JSONObject();
        JSONObject dataIn2 = new JSONObject();
        JSONArray details = new JSONArray();
        jsonObject.put("dataflow", "用友BIP→RZMOMv6");
        jsonObject.put("actionCode", "scbomb");

        for (AggPickmVO aggPickmVO : aggPickmVOS) {
            PickmHeadVO head = aggPickmVO.getParentVO();
            PickmItemVO[] bodys = (PickmItemVO[]) aggPickmVO.getChildrenVO();
            buildSyncDataBy55A2(head, bodys, details);
        }
        dataIn2.put("Details", details);
        dataIn.put("Data", dataIn2);
        jsonObject.put("data", dataIn);
        log.error("生产BOW推送锐制请求报文：" + jsonObject.toJSONString());
        String result = ThirdPartyPostRequestUtil.sendPostRequest(rzwmsip, jsonObject.toJSONString());
        JSONObject resultObj = JSONObject.parseObject(result);
        if (resultObj == null || !"true".equals(resultObj.getString("success"))) {
            String errorMsg = resultObj == null ? "接口返回为空" : resultObj.getString("msg");
            throw new BusinessException("RZ同步失败，原因：" + errorMsg);
        }else{
            log.error("RZMOM同步成功，返回参数【"+resultObj.toJSONString()+"】");
        }
    }
    private void pushToRZMOMBy61(AggPickmVO[] aggPickmVOS) throws BusinessException {
        String rzwmsip = SysInitQuery.getParaString("GLOBLE00000000000000", "RZWMSIP");
        JSONObject jsonObject = new JSONObject();
        JSONObject dataIn = new JSONObject();
        JSONObject dataIn2 = new JSONObject();
        JSONArray details = new JSONArray();
        jsonObject.put("dataflow", "用友BIP→RZMOMv6");
        jsonObject.put("actionCode", "wwfhtzdb");

        for (AggPickmVO aggPickmVO : aggPickmVOS) {
            PickmHeadVO head = aggPickmVO.getParentVO();
            PickmItemVO[] bodys = (PickmItemVO[]) aggPickmVO.getChildrenVO();
            buildSyncDataBy61(head, bodys, details);
        }
        dataIn2.put("Details", details);
        dataIn.put("Data", dataIn2);
        jsonObject.put("data", dataIn);
        log.error("生产BOW推送锐制请求报文：" + jsonObject.toJSONString());
        String result = ThirdPartyPostRequestUtil.sendPostRequest(rzwmsip, jsonObject.toJSONString());
        JSONObject resultObj = JSONObject.parseObject(result);
        if (resultObj == null || !"true".equals(resultObj.getString("success"))) {
            String errorMsg = resultObj == null ? "接口返回为空" : resultObj.getString("msg");
            throw new BusinessException("RZ同步失败，原因：" + errorMsg);
        }else{
            log.error("RZMOM同步成功，返回参数【"+resultObj.toJSONString()+"】");
        }
    }
    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();
    }

}
