package nccloud.api.uapbd.material.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import nc.bs.bd.assignservice.multiorg.MultiOrgAssignVO;
import nc.bs.bd.baseservice.ArrayClassConvertUtil;
import nc.bs.businessevent.IBusinessEvent;
import nc.bs.businessevent.IBusinessListener;
import nc.bs.businessevent.bd.BDCommonEvent;
import nc.bs.dao.BaseDAO;
import nc.bs.logging.Log;
import nc.bs.trade.business.HYPubBO;
import nc.bs.uapbd.util.MyHelper;
import nc.bs.uapbd.util.ThirdPartyPostRequestUtil;
import nc.jdbc.framework.processor.MapProcessor;
import nc.vo.bd.material.MaterialVO;
import nc.vo.bd.material.marbasclass.MarBasClassVO;
import nc.vo.org.OrgVO;
import nc.vo.pub.BusinessException;

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

/**
 * 箱变-物料新增修改后同步启源的物料
 *
 * @author mzr
 * @date 2025/08/20
 */
public class MaterialToQmsListener implements IBusinessListener {
    private static final String LOG_INFO_NAME = "qyMesLog";
    private static final Log logger = Log.getInstance(LOG_INFO_NAME);
    private static final String reqUrl = "/IF_QyErpApi.ashx?action=addwlxx";
    private Map<String, String> configParams;

    @Override
    public void doAction(IBusinessEvent event) throws BusinessException {
        BDCommonEvent e = (BDCommonEvent) event;
        String eventType = event.getEventType();
        Object[] objs = e.getObjs();

        // EventType是事件编码 1002-新增后 1004-修改后 1071-状态由停用变为启用后 1069-状态由启用变为停用后
        if ("1004".equals(eventType)) {
            MaterialVO[] useVOs = ArrayClassConvertUtil.convert(objs, MaterialVO.class);
            configParams = MyHelper.getConfigParams("xb-config", null);
            if (configParams.isEmpty()) {
                throw new BusinessException("箱变的QMS接口缺少配置");
            }
            buildSyncData(useVOs, eventType);
        } else if ("1071".equals(eventType) || "1069".equals(eventType)) {
            MaterialVO[] useVOs = ArrayClassConvertUtil.convert(objs, MaterialVO.class);
            configParams = MyHelper.getConfigParams("xb-config", null);
            if (configParams.isEmpty()) {
                throw new BusinessException("箱变的QMS接口缺少配置");
            }
            buildSyncData(useVOs, eventType);
        } else if ("1009".equals(eventType)) {
            // 物料可见性范围-分配后 1009
            configParams = MyHelper.getConfigParams("xb-config", null);
            if (configParams.isEmpty()) {
                throw new BusinessException("箱变的QMS接口缺少配置");
            }
            HYPubBO hyPub = new HYPubBO();
            List<MaterialVO> voList = new ArrayList<>();
            for (Object obj : objs) {
                MultiOrgAssignVO vo = (MultiOrgAssignVO) obj;
                String pkMaterial = vo.getPk_doc();
                String pkOrg = vo.getPk_org();
                String orgCode = (String) hyPub.findColValue(OrgVO.getDefaultTableName(), OrgVO.CODE, "dr =0 and pk_org = '" + pkOrg + "' ");
                // 检查当前组织是否为箱变
                if (checkIfOrg(orgCode, configParams)) {
                    continue;
                }
                MaterialVO materialVO = (MaterialVO) hyPub.queryByPrimaryKey(MaterialVO.class, pkMaterial);
                voList.add(materialVO);
            }
            if (!voList.isEmpty()) {
                MaterialVO[] useVOs = voList.toArray(new MaterialVO[0]);
                buildSyncData(useVOs, eventType);
            }

        }
    }

    /**
     * 构建同步数据
     */
    private void buildSyncData(MaterialVO[] useVOs, String eventType) throws BusinessException {
        for (MaterialVO vo : useVOs) {
            // 判断物料的业务单元是否是箱变公司，不是则跳过
            String pkOrg = vo.getPk_org();
            String orgCode = MyHelper.transferField(OrgVO.getDefaultTableName(), OrgVO.CODE, OrgVO.PK_ORG, pkOrg);
            if (!"1009".equals(eventType) && checkIfOrg(orgCode, configParams)) {
                continue;
            }
            // 字段值翻译
            String pk_marbasclass = vo.getPk_marbasclass();
            String mrlTypeName = MyHelper.getStrValByCondition(MarBasClassVO.getDefaultTableName(), MarBasClassVO.NAME,
                    "pk_marbasclass = '" + pk_marbasclass + "'");
            // 计量单位
            String pkMaterial = vo.getPk_material();
            Map unitMap = getGoodsInfo(pkMaterial);

            // 1=未启用;2=已启用;3=已停用;
            Integer enablestate = vo.getEnablestate();
            String statusCode = (3 == enablestate) ? "1" : "0";
            // 组装数据
            JSONObject singleObj = new JSONObject();
            // 批次编号，用于唯一标识当前传输的物料数据批次，便于追溯和批量处理
            long cts = System.currentTimeMillis();
            singleObj.put("batchid", cts);
            JSONObject contentObj = new JSONObject();
            contentObj.put("meswlbh", vo.getCode()); // 启源物料编码
            contentObj.put("bipwlbh", vo.getCode()); // BIP物料编码
            contentObj.put("wlmc", vo.getName()); // 物料名称
            contentObj.put("wlxhgg", vo.getMaterialtype() + vo.getMaterialspec()); // 物料型号规格
            contentObj.put("wlfl", mrlTypeName); // 物料分类
            contentObj.put("sjjldw", unitMap.get("unitname")); // 设计计量单位
            contentObj.put("cgjldw", unitMap.get("deputy_unitname")); // 采购计量单位
            contentObj.put("zhxs", unitMap.getOrDefault("convertRate", "1.00")); // 转换系数
            contentObj.put("flag_fq", statusCode); // 1/0 传递1代表物料废弃
            contentObj.put("bz", vo.getMemo()); // 备注信息
            JSONArray contentArr = new JSONArray();
            contentArr.add(contentObj);
            singleObj.put("Content", contentArr);
            /*
              {
                "batchid": "10001",
                "Content": [
                  {
                    "meswlbh": "ACC26711", 启源物料编码
                    "bipwlbh": "ACC26711", BIP物料编码
                    "wlmc": "铜排",物料名称
                    "wlxhgg": "15558190831", 物料型号规格
                    "wlfl": "铜排", 物料分类
                    "cpfl": "", 如果物料是产品需要填写产品分类
                    "sjjldw": "根", 设计计量单位
                    "cgjldw": "KG", 采购计量单位
                    "zhxs": "6", 转换系数，用于实物单位与采购单位的换算（即 1 根铜排的长度为 6.00 米），精确到两位小数，提升换算准确性
                    "bz": "备注" 备注信息
                  }
                ]
              }
             */
            pushData(singleObj);
        }
    }

    /**
     * 推送同步数据
     */
    private void pushData(JSONObject param) throws BusinessException {
        // String jsonString = param.toJSONString();
        // 转json字符串的时候保留null值
        String jsonStr = JSON.toJSONString(param,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullStringAsEmpty
        );
        logger.error("QMS-Material-param = " + jsonStr);
        // NCCForUAPLogger.debug("QMS-Material-param = " + jsonStr);
        String baseUrl = configParams.get("qmsBaseUrl");
        String requestUrl = baseUrl + reqUrl;
        logger.error("QMS-Material-url = " + requestUrl);
        String result = ThirdPartyPostRequestUtil.sendPostRequest(requestUrl, jsonStr);
        JSONObject resultObj = JSONObject.parseObject(result);
        logger.error("QMS-Material-res = " + result);

        if (!"success".equals(resultObj.getString("success"))) {
            // throw new BusinessException("QMS-Material-error:" + resultObj.getString("msg"));
            logger.error("QMS-Material-error,result[" + resultObj.toJSONString() + "]");
        }
    }

    private Map getGoodsInfo(String pkMaterial) throws BusinessException {
        String sql = " select a.pk_measdoc, c.name unitname, b.pk_measdoc deputyUnit, d.name deputy_unitname, nvl(b.measrate, '1/1') measrate " +
                "from bd_material a " +
                "left join bd_materialconvert b on a.pk_material = b.pk_material " +
                "left join bd_measdoc c on a.pk_measdoc = c.pk_measdoc " +
                "left join bd_measdoc d on b.pk_measdoc = d.pk_measdoc " +
                "where a.pk_material = '" + pkMaterial + "' ";
        Map map = (Map) new BaseDAO().executeQuery(sql, new MapProcessor());
        map.put("convertRate", MyHelper.transferSpecialField(map.get("measrate") + ""));
        return map;
    }

    private boolean checkIfOrg(String code, Map<String, String> configParams) throws BusinessException {
        String targetCode = configParams.get("xbOrg");
        if (targetCode == null || nc.vo.am.common.util.StringUtils.isEmpty(targetCode)) {
            throw new BusinessException("未配置组织参数");
        }
        String[] orgItem = targetCode.split(",");
        for (String orgCode : orgItem) {
            if (!orgCode.isEmpty() && orgCode.equals(code)) {
                return false;
            }
        }
        return true;
    }

}
