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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.logging.Log;
import nc.bs.trade.business.HYPubBO;
import nc.bs.trade.business.HYSuperDMO;
import nc.bs.uapbd.util.MyHelper;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.jdbc.framework.processor.MapProcessor;
import nc.uif.pub.exception.UifException;
import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.cmp.util.StringUtils;
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.OrgVO;
import nc.vo.pub.BusinessException;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.scmpub.util.ArrayUtil;
import nc.vo.util.CloneUtil;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * BIP 系统将生产订单类型为“内配订单 ”的生产订单按照物料编码+项目号向PLM 传递设计任务， PLM 方接收后根据项目号，与成套产品设计任务挂载到相同位置。
 */
public class AfterApproveSyncPLMRule implements IRule<PMOAggVO> {

    private static final String LOG_INFO_NAME = "dldzlog";

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

    private String plmBaseUrl = "";
    private String plmUser = "";
    private String token = "";
    private static final String tokenUrl = "/sipmweb/api/oauth";
    // 生产订单按照物料编码+项目号向PLM 传递设计任务
    private String pmourl = "/sipmweb/api/bip/createProduct";


    private Map<String, String> configParams;
    @Override
    public void process(PMOAggVO[] pmoAggVOS) {
        if (ArrayUtil.isEmpty(pmoAggVOS)) {
            return;
        }
        try {
            configParams= getConfigParams("Dldz-config");
            PMOAggVO[] cloneOrderVOS = (PMOAggVO[]) CloneUtil.deepClone(pmoAggVOS);
            // 检查并筛选生产订单
            List<PMOAggVO> filteredOrders = checkAndFilterBillSrcOrg(cloneOrderVOS);
            if (filteredOrders.isEmpty()) {
                return;
            }

            // 推送到锐制系统
            pushToRZMOM(filteredOrders);
        } catch (Exception e) {
            logDl.error("同步生产订单到RZ系统失败: " + e.getMessage());
            ExceptionUtils.wrappException(e);
        }
    }

    private void pushToRZMOM(List<PMOAggVO> array) throws BusinessException, IOException {
        List<Map<String, Object>> resultList = new ArrayList<>();
        if (array == null || array.size() == 0) {
           return;
        }

        for (PMOAggVO vo : array) {
            // 每个 PMOAggVO 对应一个 Map 对象
            Map<String, Object> request = new HashMap<>();

            // 获取父 VO（假设大部分字段在 ParentVO 中）
            PMOHeadVO parentVO = vo.getParentVO();
            // 获取子 VO（假设部分自定义字段在 ChildVO 或表体 VO 中）
            PMOItemVO[]  childVO = vo.getChildrenVO(); // 或其他子 VO 如 getBodyVO()
           for (PMOItemVO itemVO : childVO) {
               // 1. 产品品号 (cmaterialvid -> 物料编码)
               if (itemVO != null) {
//                   NO	产品品号	 cmaterialvid	物料编码
//                   NAME	产品名称	name	物料名称
//                   ASUSER34	项目名称	project_name	项目名称
//                   ASUSER28	生产计划号	vsrccode	来源单据号	销售订单号
//                   AB012	数量	nastnum	数量
//                   GSDM	公司代码
//                   MATERIALSISSUEDATE	主材下发时间	vdef17	主材下发时间
//                   MAINASSISTMATERIALSDATE	主辅材下发时间	vdef19	主辅材下发时间
//                   ASSISTMATERIALSDATE	辅材下发时间	vdef18	辅材下发时间
//                   DRAWINGPICKINGDATE	图纸下发时间	表体自定义项	图纸下发时间
                   HYPubBO hybo = new HYPubBO();
                   Object no = hybo.findColValue("bd_material", "code", "pk_material = '"+itemVO.getCmaterialvid()+"' ");

                   Object name = hybo.findColValue("bd_material", "name", "pk_material = '"+itemVO.getCmaterialvid()+"' ");
                   Object pk_project = hybo.findColValue("bd_project", "project_name", " pk_project = '" + itemVO.getCprojectid() + "' ");

                   Object GSDM = hybo.findColValue("org_factory", "code", " pk_factory = '" + parentVO.getPk_org() + "' ");

                   request.put("no",no);

                   request.put("name",name);

                   request.put("ASUSER34", pk_project);

                   request.put("ASUSER28", itemVO.getVsrccode());
                   request.put("AB012", itemVO.getNastnum());

                   request.put("GSDM", GSDM);
                   request.put("MATERIALSISSUEDATE", itemVO.getVdef17());
                   request.put("MAINASSISTMATERIALSDATE", itemVO.getVdef18());
                   request.put("ASSISTMATERIALSDATE", itemVO.getVdef19());
                   request.put("DRAWINGPICKINGDATE", itemVO.getVdef20()); // 替换为实际字段名，如 getVdef20()
                   // 将组装好的 Map 添加到结果列表
                   resultList.add(request);
               }


           }
            // 创建 Jackson 核心对象
            ObjectMapper objectMapper = new ObjectMapper();

            // 转换为 JSON 数组字符串（本质是 JSONArray 格式）
            String jsonArrayStr = objectMapper.writeValueAsString(resultList);
            // 获取PLM的参数
            Map<String, String> configParams = getConfigParams("Dldz-config");
            if (configParams == null || configParams.isEmpty()) {
                throw new BusinessException("未配置PLM参数");
            }
            plmBaseUrl = configParams.get("plmBaseUrl");
            plmUser = configParams.get("plmUser");
            token = getToken();
            logDl.info("请求参数 ："+jsonArrayStr);
            String responseString= this.doPost(plmBaseUrl+pmourl,jsonArrayStr);
            logDl.info("返回结果 ："+responseString);
            Gson gson = new Gson();
            Map result = gson.fromJson(responseString, Map.class);
            if (!result.get("success").toString().equals("true")) {
                throw new BusinessException(result.get("msg").toString());
            }

        }

    }

    private List<PMOAggVO> checkAndFilterBillSrcOrg(PMOAggVO[] cloneOrderVOS) throws BusinessException, IOException {
        List<PMOAggVO> filteredOrders = new ArrayList<PMOAggVO>();

        for (PMOAggVO pmoAggVO : cloneOrderVOS) {
            ;
            String pkOrg = pmoAggVO.getParentVO().getPk_org();
            String orgCode = MyHelper.transferField(OrgVO.getDefaultTableName(), OrgVO.CODE, OrgVO.PK_ORG, pkOrg);
            // 检查当前组织是否为电力电子
            if (MyHelper.checkIfDldzOrg(orgCode, configParams)) {
                continue;
            }
            if(pmoAggVO.getParentVO().getVtrantypecode().equals("55A2-Cxx-08")){
                filteredOrders.add(pmoAggVO);
            }
        }


        return filteredOrders;
    }
    public Map<String, String> getConfigParams(String code) {
        Map<String, String> map = new HashMap<>();
        String strWhere = " pk_defdoclist in (select pk_defdoclist from bd_defdoclist where code='[code]' and dr=0 ) and dr=0";
        strWhere = strWhere.replace("[code]", code);
        try {
            DefdocVO[] defdocVOs = (DefdocVO[]) new HYSuperDMO().queryByWhereClause(DefdocVO.class, strWhere);
            if (defdocVOs != null) {
                for (DefdocVO defdocVO : defdocVOs) {
                    String value = StringUtils.isEmpty(defdocVO.getMemo()) ? defdocVO.getName() : defdocVO.getMemo();
                    map.put(defdocVO.getCode().trim(), value);
                }
            }
        } catch (DAOException e) {
            logDl.error("Failed to get config parameters for code: " + code, e);
        }
        return map;
    }
    private String doPost(String requestUrl, String param) throws IOException {
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(500);
        cm.setDefaultMaxPerRoute(50);

        RequestConfig globalConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) // 连接池获取连接超时
                .setConnectTimeout(5000) // 连接建立超时
                .setSocketTimeout(20000) // 等待响应超时
                .setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();

        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
                .setDefaultRequestConfig(globalConfig).build();
        HttpPost post = new HttpPost(requestUrl);
        post.setHeader("Content-Type", "application/json;charset=UTF-8");
        post.setEntity(new StringEntity(param, "utf-8"));
        String responseString = httpClient.execute(post, response -> EntityUtils.toString(response.getEntity()));
        return responseString;

    }




    /**
     * 获取token
     */
    private String getToken() throws IOException, BusinessException {
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("uname", plmUser);
        tokenMap.put("f", "true");
        String tokenStr = doGet(plmBaseUrl + tokenUrl, tokenMap);
        logDl.error("GetPlmFileUtil-getToken-tokenStr = " + tokenStr);
        JSONObject jsonObject = JSONObject.parseObject(tokenStr);
        String token = jsonObject.getString("errmsg");
        if (token == null || token.isEmpty()) {
            throw new BusinessException("PLM鉴权失败");
        }
        return token;
    }
    private String doGet(String requestUrl, Map<String, String> paramMap) throws IOException {
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(5000);
        cm.setDefaultMaxPerRoute(500);

        RequestConfig globalConfig = RequestConfig.custom().setConnectionRequestTimeout(50000) // 连接池获取连接超时
                .setConnectTimeout(50000) // 连接建立超时
                .setSocketTimeout(200000) // 等待响应超时
                .setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();

        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
                .setDefaultRequestConfig(globalConfig).build();
        StringBuilder param = new StringBuilder("?");
        if (paramMap != null) {
            for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                param.append(entry.getKey());
                param.append("=");
                param.append(entry.getValue());
                param.append("&");
            }
            param.deleteCharAt(param.length() - 1);
        }
        String url = requestUrl + param;
        HttpGet get = new HttpGet(url);
        String responseString = httpClient.execute(get, response -> EntityUtils.toString(response.getEntity()));
        get.releaseConnection();
        return responseString;
    }
}
