package nc.bs.mmpac.pmo.pac0002.bp.rule;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import nc.bs.dao.BaseDAO;
import nc.bs.logging.Log;
import nc.bs.logging.Logger;
import nc.bs.trade.business.HYPubBO;
import nc.bs.uapbd.util.MyHelper;
import nc.bs.uapbd.util.ThirdPartyPostRequestUtil;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.itf.arap.goldentax.SysParaInitQuery;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.jdbc.framework.processor.MapProcessor;
import nc.vo.ic.m4d.entity.MaterialOutBodyVO;
import nc.vo.ic.m4d.entity.MaterialOutVO;
import nc.vo.mmpac.pmo.pac0002.entity.PMOAggVO;
import nc.vo.mmpac.pmo.pac0002.entity.PMOHeadVO;
import nc.vo.mmpac.pmo.pac0002.entity.PMOItemVO;
import nc.vo.org.FactoryVO;
import nc.vo.pub.BusinessException;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.pub.SqlBuilder;
import nc.vo.scmpub.util.ArrayUtil;
import nccloud.commons.lang.StringUtils;

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

/**
 * 流程生产订单审批后推送艾普MES
 *
 * @author mzr
 * @date 2025/7/3
 */
public class AfterApproveSyncEpicMesRule implements IRule<PMOAggVO> {

    private static final String LOG_INFO_NAME = "DLDZLOG";

    private static final Log obmlog = Log.getInstance(LOG_INFO_NAME);

    private static final String MES_PMO_SYNC_URL = "/prj-v5-web/ext/api/wrokOrder";

    private static final BaseDAO dao = new BaseDAO();

    @Override
    public void process(PMOAggVO[] pmoAggVOS) {
        if (ArrayUtil.isEmpty(pmoAggVOS)) {
            return;
        }
        try {
            List<PMOAggVO> filteredOrders = checkAndFilterBillSrcOrg(pmoAggVOS);
            if (filteredOrders.isEmpty()) {
                obmlog.debug("没有符合条件的生产订单需要同步到艾普MES系统。");
                return;
            }

            obmlog.info("开始同步生产订单到艾普MES系统，符合条件的订单数量: " + filteredOrders.size());
            JSONArray jsonArray = new JSONArray();
            // 推送到艾普MES系统
            for (PMOAggVO aggVO : filteredOrders) {
                PMOHeadVO head = aggVO.getParentVO();
                PMOItemVO[] bodys = aggVO.getChildrenVO();

                if (bodys == null || bodys.length == 0) {
                    obmlog.warn("生产订单 " + head.getVbillcode() + " 没有行信息，跳过同步。");
                    continue;
                }
                JSONObject data = buildSyncData(aggVO);
                pushData(data);

                JSONObject buildSyncData= buildSyncData1(aggVO);
                jsonArray.add(buildSyncData);
            }
            if(jsonArray.size() > 0) {
                pushData("/prj-v5-web/ext/api/releaseNo",jsonArray);
            }

            obmlog.info("生产订单同步到艾普MES系统处理完成。");


        } catch (Exception e) {
            obmlog.error("同步生产订单到艾普MES系统失败: " + e.getMessage(), e);
            ExceptionUtils.wrappException(e);
        }
    }

    /**
     * 调用MES接口并处理特定错误
     *
     * @param param 请求体
     * @throws BusinessException 如果发生非特定可忽略的错误
     */
    private void pushData(JSONObject param) throws BusinessException {
        String responseString = null;
        try {
            String baseUrl = SysParaInitQuery.getParaString("GLOBLE00000000000000", "EPICMESURL");
            String requestUrl = baseUrl + MES_PMO_SYNC_URL;
            responseString = ThirdPartyPostRequestUtil.sendPostRequest(requestUrl, param.toJSONString());
            obmlog.info(" 艾普MES系统原始返回: " + responseString);

            JSONObject jsonResponse = JSONObject.parseObject(responseString);
        } catch (Exception e) {
            obmlog.error(" 调用MES或处理响应时发生错误。原始响应: " + responseString + " 错误: " + e.getMessage(), e);
            throw new BusinessException("调用MES或处理响应时发生错误：" + e.getMessage(), e);
        }
    }

    /**
     * 检查并筛选需要同步的单据
     */
    private List<PMOAggVO> checkAndFilterBillSrcOrg(PMOAggVO[] pmoAggVOS) throws BusinessException {
        List<PMOAggVO> aggvoList = new ArrayList<>();
        for (PMOAggVO aggVo : pmoAggVOS) {
            String pkOrg = aggVo.getParentVO().getPk_org();
            String orgCode = MyHelper.transferField(FactoryVO.getDefaultTableName(), FactoryVO.CODE, FactoryVO.PK_FACTORY, pkOrg);
            // 检查当前组织是否为电力电子
            if (MyHelper.checkIfDldzOrg(orgCode)) {
                aggvoList.add(aggVo);
            }
        }
        // 按照部门区分生产订单，只传消弧车间、电容车间、成套车间（部门是配置项）

        return aggvoList;
    }

    /**
     * 组装数据
     */
    private JSONObject buildSyncData(PMOAggVO aggVO) throws BusinessException {
        JSONObject data = new JSONObject();
        PMOHeadVO headVo = aggVO.getParentVO();
        // PMOItemVO[] pmoItems = aggVO.getChildrenVO();
        JSONObject orderParam = new JSONObject();
        orderParam.put("id", null); // 唯一标识（主键）
        orderParam.put("siteCode", null);// 工厂编码
        orderParam.put("contractNo", null);// 合同号
        orderParam.put("workOrderCode", headVo.getVbillcode());// 工单号
        orderParam.put("qty", null); // 计划数量，字符串类型
        orderParam.put("produCode", null); // 产品编码
        orderParam.put("produName", null); // 产品名称
        orderParam.put("bomCode", null); // BOM 编码
        orderParam.put("planBeginDate", null); // 计划开始时间（毫秒级时间戳）
        orderParam.put("planEndDate", null); // 计划完成时间（毫秒级时间戳）
        orderParam.put("endDate", null); // 试验结束时间（毫秒级时间戳）
        orderParam.put("type", "I"); // 类型：I:新增 U:修改 D:删除
        orderParam.put("auditCode", "Y"); // 审核状态（Y:已审核 N:未审核）
        orderParam.put("contractName", null); // 合同名称
        orderParam.put("transferPlanTime", null); // 生产转检计划时间（格式为YYYY-MM-DD）
        orderParam.put("receiptScheduledTime", null); // 完工入库时间（格式为YYYY-MM-DD）
        String pkOrg = headVo.getPk_org();
        String selectFields = FactoryVO.CODE + "," + FactoryVO.NAME;
        Map<String, Object> orgMap = MyHelper.transferFields(FactoryVO.getDefaultTableName(), selectFields, FactoryVO.PK_FACTORY, pkOrg);
        orderParam.put("companyCode", orgMap.get(FactoryVO.CODE)); // 公司编码
        orderParam.put("companyName", orgMap.get(FactoryVO.NAME)); // 公司名称
        JSONArray orderArr = new JSONArray();
        orderArr.add(orderParam);
        // 流程生产订单
        data.put("workOrders", orderArr);
        data.put("mrls", getPickmInfo(headVo.getPrimaryKey())); // 备料计划
        //       {
        //           "workOrders": [// 流程生产订单
        //           {
        //               "id": null,                          // 唯一标识（主键）
        //                   "siteCode": "04",                    // 工厂编码
        //                   "contractNo": "HDDK0111325",        // 合同号
        //                   "workOrderCode": "DSF01-2501230028",// 工单号
        //                   "qty": "1.000",                      // 计划数量（字符串类型）
        //                   "produCode": "103248250005",        // 产品编码
        //                   "produName": "150KV滤抗-特高压宝塔山（试装）-低端", // 产品名称
        //                   "bomCode": "103248250005",          // BOM 编码
        //                   "planBeginDate": 1751328000000,     // 计划开始时间（毫秒级时间戳）
        //                   "planEndDate": 1751328000000,       // 计划结束时间（毫秒级时间戳）
        //                   "endDate": 1751328000000,            // 试验结束时间（毫秒级时间戳）
        //                   "type": null,                        // 类型（I:新增 U:修改 D:删除）
        //                   "auditCode": "Y",                    // 审核码（Y:已审核 N:未审核）
        //                   "contractName": "特高压宝塔山±800 千伏换流站工程", // 合同名称
        //                   "transferPlanTime": "2025-07-01",   // 生产转检计划时间（格式：YYYY-MM-DD）
        //                   "receiptScheduledTime": "2025-07-01", // 完工入库时间（格式：YYYY-MM-DD）
        //                   "companyCode": "DLDZ",              // 公司编码
        //                   "companyName": "泰开电力电子"       // 公司名称
        //           }
        // ],
        //           "mrls": [ 备料计划
        //           {
        //               "workOrderCode": "DSF01-2501230028",// 工单号
        //                   "mrlCode": "2305050447",           // 物料编码
        //                   "mrlName": "铝加工件",             // 物料名称
        //                   "qty": 1.000,                        // 数量（浮点数）
        //                   "unit": "套"                         // 单位
        //           }
        // ]
        //       }

        return data;
    }

    /**
     * 备料计划数据封装
     *
     * @param sourceId 流程生产订单唯一标识
     * @return
     * @throws BusinessException
     */
    private JSONArray getPickmInfo(String sourceId) throws BusinessException {
        JSONArray pickmArr = new JSONArray();
        if (StringUtils.isEmpty(sourceId) || "~".equals(sourceId)) {
            return pickmArr;
        }
        SqlBuilder sqlBuilder = new SqlBuilder();
        sqlBuilder.append(" select c.code mrlCode, c.name mrlName, d.name unit, b.nplanoutastnum qty");
        sqlBuilder.append(" from mm_pickm_b b");
        sqlBuilder.append(" left join mm_pickm a on b.cpickmid = a.cpickmid");
        sqlBuilder.append(" left join bd_material c on b.cbmaterialid = c.pk_material");
        sqlBuilder.append(" left join bd_measdoc d on b.cbastunitid = d.pk_measdoc");
        sqlBuilder.append(" where b.dr = 0");
        sqlBuilder.append(" and ");
        sqlBuilder.append("a.csourcebillid", sourceId);
        List<Map<String, Object>> result = (List<Map<String, Object>>) dao.executeQuery(sqlBuilder.toString(), new MapListProcessor());
        for (Map<String, Object> objectMap : result) {
            JSONObject bodyJson = new JSONObject();
            bodyJson.put("mrlCode", objectMap.get("mrlCode"));// 物料编码
            bodyJson.put("mrlName", objectMap.get("mrlName"));// 物料名称
            bodyJson.put("qty", objectMap.get("qty"));// 数量
            bodyJson.put("unit", objectMap.get("unit"));// 单位
            pickmArr.add(bodyJson);
        }
        return pickmArr;

    }

    /**
     * 转换特殊字段  如 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 JSONObject buildSyncData1(PMOAggVO vo ) throws BusinessException {
//        [
//        {
//            "siteCode": "", // 工厂编码
//                "workOrderCode": "", // 工单号
//                "companyCode": "DLDZ", //公司编码
//                "companyName": "泰开电力电子",//公司名称
//                "releaseNo": [] // 出厂编号
//        }
//]

        JSONObject obj = new JSONObject();
        obj.put("siteCode", vo.getParentVO().getVbillcode()); // 已存在的billCode字段
        obj.put("workOrderCode", null);

        BaseDAO dao = new BaseDAO();
        String orgsql = "select code,name from org_factory where pk_factory = '" + vo.getParentVO().getPk_org() + "' ";
        Map<String,Object> tr = (Map<String, Object>) dao.executeQuery( orgsql,  new MapProcessor());
        obj.put("companyCode", tr.get("code"));
        obj.put("companyName", tr.get("name"));
        JSONArray jsonArray = new JSONArray();
        for (PMOItemVO item: vo.getChildrenVO()){
            HYPubBO hybo = new HYPubBO();
            Object materialtype = hybo.findColValue("bd_material_v", "materialtype", "pk_source = '" + item.getCmaterialid() + "' ");

            String detailItem = materialtype+vo.getParentVO().getDbilldate().toStdString().substring(0,3)+vo.getParentVO().getDbilldate().toStdString().substring(5,6)+"0001";
            jsonArray.add(detailItem);
        }
        obj.put("releaseNo", jsonArray);

        return   obj;
    }
    private void pushData(String requestUrl, JSONArray param) throws BusinessException {
        String baseUrl = SysParaInitQuery.getParaString("GLOBLE00000000000000", "EPICMESURL");
        baseUrl="http://192.168.55.39:8080";
        requestUrl = baseUrl + requestUrl;
        String result = ThirdPartyPostRequestUtil.sendPostRequest(requestUrl, param.toJSONString());
        JSONObject resultObj = JSONObject.parseObject(result);
        Logger.error("EpicMes-Material-req = " + result);

        if ("false".equals(resultObj.getString("success"))) {
            throw new BusinessException("EpicMes-Material-failerror:" + resultObj.getString("msg"));
        } else {
            Logger.error("EpicMes-Material-suc,result[" + resultObj.toJSONString() + "]");
        }
    }

}
