package com.sunda.spmscommon.utils;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.sunda.spmscommon.feign.IFeignServiceCommon;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import lombok.extern.slf4j.Slf4j;

/**
 * 通过ESB获取OA的token类
 * @author 0113389
 *
 */
@Slf4j
@Component
public class OaFlowCreateUtils {
	
	@Autowired
	private IFeignServiceCommon iFeignServiceCommon;
	
	// 缓存数据
	private static final Map<String, String> SYSTEM_CACHE = new HashMap<>();
	
	// ecology系统发放的授权许可证(appid)
	private static final String APPID = "44977cbe-6f5f-4f72-89bd-d0a22156f463";
	
	
	public Map<String, Object> oaRegist(String targetId) {
		Map<String, Object> datas = new HashMap<>();
		datas.put("status", false);
		datas.put("msg", "获取oa Regist接口失败");
		try {
			//获取当前系统RSA加密的公钥
			RSA rsa = new RSA();
			String publicKey = rsa.getPublicKeyBase64();
			String privateKey = rsa.getPrivateKeyBase64();
			// 客户端RSA私钥
			SYSTEM_CACHE.put("LOCAL_PRIVATE_KEY", privateKey);
			// 客户端RSA公钥
			SYSTEM_CACHE.put("LOCAL_PUBLIC_KEY", publicKey);
			// 调用ESB接口
			JSONObject setToSapData = new JSONObject();
			String mqUuid = UUID.randomUUID().toString();
			JSONObject REQUEST = new JSONObject();
			JSONObject ESB_ATTRS = new JSONObject();
			JSONObject REQUEST_DATA = new JSONObject();
			ESB_ATTRS.put("Application_ID", "00020000000002");
			ESB_ATTRS.put("Transaction_ID", mqUuid);
			ESB_ATTRS.put("App_ID", "SPMS");
			ESB_ATTRS.put("Target_ID", targetId);
			REQUEST_DATA.put("Operation", "Z_OA_APP_REGIST");
			REQUEST_DATA.put("Type", "Z_OA_APP_REGIST");
			Map<String, Object> sendHead = new HashMap<>();
			sendHead.put("appid", APPID);
			sendHead.put("cpk", publicKey);
			REQUEST_DATA.put("SendHead", sendHead);
			REQUEST.put("ESB_ATTRS", ESB_ATTRS);
			REQUEST.put("REQUEST_DATA", REQUEST_DATA);
			setToSapData.put("REQUEST", REQUEST);
			log.info("获取oa Regist接口传参："+setToSapData.toJSONString());
			JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(setToSapData));
			log.info("获取oa Regist接口返回："+message.toJSONString());
			if (message != null) {
				JSONObject returnData = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
				Boolean status = returnData.getBoolean("status");
				String msg = returnData.getString("msg");
				if (status) {
					//ECOLOGY返回的系统公钥
					SYSTEM_CACHE.put("SERVER_PUBLIC_KEY", StrUtil.nullToEmpty((String) returnData.getString("spk")));
					//ECOLOGY返回的系统密钥
					SYSTEM_CACHE.put("SERVER_SECRET", StrUtil.nullToEmpty((String) returnData.getString("secrit")));
					datas.put("status", status);
					datas.put("msg", "获取oa Regist接口成功："+msg);
				} else {
					datas.put("msg", "获取oa Regist接口失败："+msg);
				}
			}
			
		} catch (Exception e) {
			log.info("获取oa Regist接口调用失败："+e);
		}
        return datas;
    }
	
	/**
	 * 第二步，获取OAtoken
	 * @param targetId
	 * @return
	 */
	public Map<String, Object> oaGetoken(String targetId) {
		Map<String, Object> datas = new HashMap<>();
		datas.put("status", false);
		datas.put("msg", "获取oa token接口失败");
		try {
			// 从系统缓存或者数据库中获取ECOLOGY系统公钥和Secret信息
			String secret = SYSTEM_CACHE.get("SERVER_SECRET");
			String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
			
			// 如果为空,说明还未进行注册,调用注册接口进行注册认证与数据更新
			if (Objects.isNull(secret) || Objects.isNull(spk)) {
				Map<String, Object> oaRegistMap = oaRegist(targetId);
				if (!(boolean) oaRegistMap.get("status")) {
					return oaRegistMap;
				}
				// 重新获取最新ECOLOGY系统公钥和Secret信息
				secret = SYSTEM_CACHE.get("SERVER_SECRET");
				spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
			}
			// 公钥加密,所以RSA对象私钥为null
			RSA rsa = new RSA(null, spk);
			//对秘钥进行加密传输，防止篡改数据
			String encryptSecret = rsa.encryptBase64(secret, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
			// 调用接口获取OA TOKEN
			JSONObject setToSapData = new JSONObject();
			String mqUuid = UUID.randomUUID().toString();
			JSONObject REQUEST = new JSONObject();
			JSONObject ESB_ATTRS = new JSONObject();
			JSONObject REQUEST_DATA = new JSONObject();
			ESB_ATTRS.put("Application_ID", "00020000000002");
			ESB_ATTRS.put("Transaction_ID", mqUuid);
			ESB_ATTRS.put("App_ID", "SPMS");
			ESB_ATTRS.put("Target_ID", targetId);
			REQUEST_DATA.put("Operation", "Z_OA_GET_TOKEM");
			REQUEST_DATA.put("Type", "Z_OA_GET_TOKEM");
			Map<String, Object> sendHead = new HashMap<>();
			sendHead.put("appid", APPID);
			sendHead.put("secret", encryptSecret);
			sendHead.put("time", "3600");
			REQUEST_DATA.put("SendHead", sendHead);
			REQUEST.put("ESB_ATTRS", ESB_ATTRS);
			REQUEST.put("REQUEST_DATA", REQUEST_DATA);
			setToSapData.put("REQUEST", REQUEST);
			log.info("获取oa token接口传参："+setToSapData.toJSONString());
			JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(setToSapData));
			log.info("获取oa TOKEN接口返回："+message.toJSONString());
			if (message != null) {
				JSONObject returnData = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
				Boolean status = returnData.getBoolean("status");
				String msg = returnData.getString("msg");
				if (status) {
					//ECOLOGY返回的token
					SYSTEM_CACHE.put("SERVER_TOKEN", StrUtil.nullToEmpty((String) returnData.getString("token")));
					datas.put("status", status);
					datas.put("token", returnData.getString("token"));
					datas.put("msg", "获取oa token接口成功："+msg);
				} else {
					datas.put("msg", "获取oa token接口失败："+msg);
				}
			}
		} catch (Exception e) {
			log.info("获取oa TOKEN接口调用失败："+e);
		}
        return datas;
    }
	
	/**
	 * 推送OA创建流程
	 * @param targetId
	 * @param jsonParams
	 * @param userId
	 * @return
	 */
	public Map<String, Object> oaRestFul(String targetId, Map<String, Object> jsonParams,String userId) {
		Map<String, Object> datas = new HashMap<>();
		datas.put("status", false);
		datas.put("msg", "推送OA创建流程失败");
        // 获取token
		Map<String, Object> oaGetokenMap = oaGetoken(targetId);
		if (!(boolean) oaGetokenMap.get("status")) {
        	return oaGetokenMap;
        }
		String token = oaGetokenMap.get("token").toString();
        String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
        //封装请求头参数
        RSA rsa = new RSA(null, spk);
        //对用户信息进行加密传输,暂仅支持传输OA用户ID
        String encryptUserid1 = rsa.encryptBase64("1", CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
        JSONObject userDoc = null;
        try {
        	// 调用接口获取OA用户信息
        	JSONObject setToSapData = new JSONObject();
        	String mqUuid = UUID.randomUUID().toString();
        	JSONObject REQUEST = new JSONObject();
        	JSONObject ESB_ATTRS = new JSONObject();
        	JSONObject REQUEST_DATA = new JSONObject();
        	ESB_ATTRS.put("Application_ID", "00020000000002");
        	ESB_ATTRS.put("Transaction_ID", mqUuid);
        	ESB_ATTRS.put("App_ID", "SPMS");
        	ESB_ATTRS.put("Target_ID", targetId);
        	REQUEST_DATA.put("Operation", "Z_OA_GET_USER_INFO_BY_WORKCODE");
        	REQUEST_DATA.put("Type", "Z_OA_GET_USER_INFO_BY_WORKCODE");
        	Map<String, Object> sendHead = new HashMap<>();
        	sendHead.put("appid", APPID);
        	sendHead.put("token", token);
        	sendHead.put("userid", encryptUserid1);
        	Map<String, Object> sendURL = new HashMap<>();
        	sendURL.put("workcode", userId);
        	REQUEST_DATA.put("SendHead", sendHead);
        	REQUEST_DATA.put("SendURL", sendURL);
        	REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        	REQUEST.put("REQUEST_DATA", REQUEST_DATA);
        	setToSapData.put("REQUEST", REQUEST);
        	log.info("获取oa用户信息接口传参："+setToSapData.toJSONString());
        	JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(setToSapData));
        	log.info("获取oa用户信息接口返回："+message.toJSONString());
    		JSONObject returnData = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
    		Boolean status = returnData.getBoolean("api_status");
    		String msg = returnData.getString("msg");
    		if (status) {
    			userDoc = returnData.getJSONObject("data");
    			datas.put("status", status);
    			datas.put("msg", "获取oa用户信息接口成功："+msg);
    		} else {
    			datas.put("msg", "获取OA用户信息接口失败："+msg);
    			return datas;
    		}
        } catch (Exception e) {
        	log.info("获取oa用户信息接口调用失败："+e);
        	datas.put("status", false);
    		datas.put("msg", "获取oa用户信息接口调用失败:"+e.getLocalizedMessage());
    		return datas;
        }
        String id = "";
//        String departmentid = "";
        if(userDoc != null){
            id = userDoc.getString("id");
//            departmentid = userDoc.getString("departmentid");
        }
//        jsonParams.put("departmentid",departmentid );
        String encryptUserid = rsa.encryptBase64(id, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
        // 调用接口在OA创建流程
        try {
        	// 调用接口获取OA用户信息
        	JSONObject setToSapData = new JSONObject();
        	String mqUuid = UUID.randomUUID().toString();
        	JSONObject REQUEST = new JSONObject();
        	JSONObject ESB_ATTRS = new JSONObject();
        	JSONObject REQUEST_DATA = new JSONObject();
        	ESB_ATTRS.put("Application_ID", "00020000000002");
        	ESB_ATTRS.put("Transaction_ID", mqUuid);
        	ESB_ATTRS.put("App_ID", "SPMS");
        	ESB_ATTRS.put("Target_ID", targetId);
        	REQUEST_DATA.put("Operation", "Z_OA_FLOW_CREATE_REQUEST");
        	REQUEST_DATA.put("Type", "Z_OA_FLOW_CREATE_REQUEST");
        	Map<String, Object> sendHead = new HashMap<>();
        	sendHead.put("appid", APPID);
        	sendHead.put("token", token);
        	sendHead.put("userid", encryptUserid);
        	REQUEST_DATA.put("SendHead", sendHead);
        	REQUEST_DATA.put("SendData", jsonParams);
        	REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        	REQUEST.put("REQUEST_DATA", REQUEST_DATA);
        	setToSapData.put("REQUEST", REQUEST);
        	log.info("创建OA流程所传参数："+setToSapData.toJSONString());
        	JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(setToSapData));
        	log.info("创建OA流程接口返回："+message.toJSONString());
        	JSONObject returnData = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
        	String status = returnData.getString("code");
        	String msg = returnData.getString("errMsg");
        	if ("SUCCESS".equals(status)) {
        		datas.put("status", true);
        		JSONObject obj = returnData.getJSONObject("data");
        		datas.put("requestid", obj.getString("requestid"));
        		datas.put("msg", "创建OA流程成功："+msg);
        	} else {
        		datas.put("msg", "创建OA流程接口失败："+msg);
        		datas.put("status", false);
        	}
        } catch (Exception e) {
        	log.info("推送OA创建流程接口调用失败："+e);
        	datas.put("status", false);
    		datas.put("msg", "推送OA创建流程接口调用失败:"+e.getLocalizedMessage());
        }
        return datas;
    }

}
