package com.sunda.spmscommon.utils;


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 cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * Token认证测试
 * <p>
 *   认证过程主要采用RSA非对称加密算法
 *
 * @author 
 */
@Slf4j
public class OAMainUtils {

    /**
     *      * 模拟缓存服务
     *      
     */
    private static final Map<String, String> SYSTEM_CACHE = new HashMap<>();

    /**
     *      * ecology系统发放的授权许可证(appid)
     *      
     */
    private static final String APPID = "44977cbe-6f5f-4f72-89bd-d0a22156f463";

    public static void main(String[] args) {
        Map<String, Object> rl = new HashMap<String, Object>();
        rl.put("requestName", "test");
        rl.put("workflowId", 4526);

        List<Map<String, Object>> aas = new ArrayList<Map<String, Object>>();
        Map<String, Object> ol = new HashMap<String, Object>();
        ol.put("fieldName", "riqi");
        ol.put("fieldValue", "2022-10-10");
        aas.add(ol);

        ol = new HashMap<String, Object>();
        ol.put("fieldName", "fx");
        ol.put("fieldValue", "test");
        aas.add(ol);
        rl.put("mainData", JSONUtil.parseArray(aas).toString());

        String jsonParams = JSONUtil.parseObj(rl).toString();


        oaRestFul("http://oatest2.sunda.com:9002", "/api/workflow/paService/doCreateRequest", rl,"1");
    }

    /**
     *      * 第一步：
     *      *
     *      * 调用ecology注册接口,根据appid进行注册,将返回服务端公钥和Secret信息
     *      
     */
    public static Map<String, Object> oaRegist(String address) {

        //获取当前系统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);

        //调用ECOLOGY系统接口进行注册
        String data = HttpRequest.post(address + "/api/ec/dev/auth/regist")
                .header("appid", APPID)
                .header("cpk", publicKey)
                .timeout(20000)
                .execute().body();

        // 打印ECOLOGY响应信息
        System.out.println("oaRegist()：" + data);
        Map<String, Object> datas = JSONUtil.parseObj(data);

        //ECOLOGY返回的系统公钥
        SYSTEM_CACHE.put("SERVER_PUBLIC_KEY", StrUtil.nullToEmpty((String) datas.get("spk")));
        //ECOLOGY返回的系统密钥
        SYSTEM_CACHE.put("SERVER_SECRET", StrUtil.nullToEmpty((String) datas.get("secrit")));
        return datas;
    }


    /**
     *      * 第二步：
     *      *
     *      * 通过第一步中注册系统返回信息进行获取token信息
     *      
     */
    public static Map<String, Object> oaGetoken(String address) {
        // 从系统缓存或者数据库中获取ECOLOGY系统公钥和Secret信息
        String secret = SYSTEM_CACHE.get("SERVER_SECRET");
        String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");

        // 如果为空,说明还未进行注册,调用注册接口进行注册认证与数据更新
        if (Objects.isNull(secret) || Objects.isNull(spk)) {
            oaRegist(address);
            // 重新获取最新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);

        //调用ECOLOGY系统接口进行注册
        String data = HttpRequest.post(address + "/api/ec/dev/auth/applytoken")
                .header("appid", APPID)
                .header("secret", encryptSecret)
                .header("time", "3600")
                .execute().body();

        System.out.println("oaGetoken()：" + data);
        Map<String, Object> datas = JSONUtil.parseObj(data);

        //ECOLOGY返回的token
        // TODO 为Token缓存设置过期时间
        SYSTEM_CACHE.put("SERVER_TOKEN", StrUtil.nullToEmpty((String) datas.get("token")));

        return datas;
    }

    /**
     *      * 第三步：
     *      *
     *      * 调用ecology系统的rest接口，请求头部带上token和用户标识认证信息
     *      *
     *      * @param address ecology系统地址
     *      * @param api rest api 接口地址(该测试代码仅支持GET请求)
     *      * @param jsonParams 请求参数json串
     *      *
     *      * 注意：ECOLOGY系统所有POST接口调用请求头请设置 "Content-Type","application/x-www-form-urlencoded; charset=utf-8"
     *      
     */
    public static String oaRestFul(String address, String api, Map<String, Object> jsonParams,String userId) {
        //ECOLOGY返回的token
        //String token = SYSTEM_CACHE.get("SERVER_TOKEN");
        String token = null;
        if (StrUtil.isEmpty(token)) {
            token = (String) oaGetoken(address).get("token");
        }

        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);

        //{"msgcode":1,"hasRight":true,"api_status":true,"data":
        // {"subcompanyid":"1",     ？？？
        // "workcode":"0113390",    工号
        // "line":"IT线(It line)",   分线
        // "departmentid":"127",    部门编码
        // "mobile":"18302060852",
        // "telephone":"",
        // "subcompanyname":"森大国际",  公司名称？
        // "jobtitleid":"7226",     ？？？
        // "managerid":"1416",      ？？？
        // "point":"广州(Guangzhou)",   分点
        // "jobtitlename":"开发工程师",   岗位？？？
        // "departmentname":"系统开发与架构部",   部门名称
        // "name":"黄志聪",
        // "managername":"揭增乾",  上级领导
        // "company":"中国(China)",   公司名称？
        // "id":"1204",            用户ID
        // "email":"huangzhicong@sunda.com",
        // "status":"1"}}
        ///api/custom/hr/user/getUserInfoByWorkcode?workcode=0112448
        ///api/custom/hr/user/getUseridByWorkcode?workcode=0112448
        String userInfo = HttpRequest.get(address + "/api/custom/hr/user/getUserInfoByWorkcode?workcode="+userId)
                .header("appid", APPID)
                .header("token", token)
                .header("userid", encryptUserid1)
                .header("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
                .execute().body();
        JSONObject userDoc = JSONObject.parseObject(userInfo);
        log.info("推送数据到OA返回-userDoc:"+userDoc.toJSONString());
        String id = "";
        String departmentid = "";
        if("true".equals(userDoc.getString("api_status"))){
            String data = userDoc.getString("data");
            JSONObject dataJson = JSONObject.parseObject(data);
            id = dataJson.getString("id");
            departmentid = dataJson.getString("departmentid");
        }
        jsonParams.put("departmentid",departmentid );

        log.info("推送数据到OA返回-id:"+id);
        String encryptUserid = rsa.encryptBase64(id, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
        //调用ECOLOGY系统接口
        log.info("推送数据到OA-api:"+address + api);
        log.info("推送数据到OA-jsonParams:" + jsonParams);
        log.info("推送数据到OA-token:"+token);
        log.info("推送数据到OA-userId:"+userId);
        log.info("推送数据到OA-encryptUserid:"+encryptUserid);
        String data = HttpRequest.post(address + api)
                .header("appid", APPID)
                .header("token", token)
                .header("userid", encryptUserid)
                .header("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
                //.body(jsonParams)
                .form(jsonParams)
                .execute().body();
        System.out.println(" oaRestFul()：" + data);
        return data;

    }


    //获取OA审批日志
    public static String getOaProssLog(String address, String api, String userId) {
        //ECOLOGY返回的token
        String token = null;
        if (StrUtil.isEmpty(token)) {
            token = (String) oaGetoken(address).get("token");
        }

        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);

        String userInfo = HttpRequest.get(address + "/api/custom/hr/user/getUserInfoByWorkcode?workcode="+userId)
                .header("appid", APPID)
                .header("token", token)
                .header("userid", encryptUserid1)
                .header("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
                .execute().body();
        JSONObject userDoc = JSONObject.parseObject(userInfo);
        String id = "";
        String departmentid = "";
        if("true".equals(userDoc.getString("api_status"))){
            String data = userDoc.getString("data");
            JSONObject dataJson = JSONObject.parseObject(data);
            id = dataJson.getString("id");
            departmentid = dataJson.getString("departmentid");
        }

        String encryptUserid = rsa.encryptBase64(id, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
        //调用ECOLOGY系统接口
        String data = HttpRequest.get(address + api)
                .header("appid", APPID)
                .header("token", token)
                .header("userid", encryptUserid)
                .header("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
                .execute().body();

        System.out.println(" oaRestFul()：" + data);
        return data;

    }

    public static String oaRestFull( String userId,String oaUrl) {
        //ECOLOGY返回的token
        //String token = SYSTEM_CACHE.get("SERVER_TOKEN");
        String token = null;
        if (StrUtil.isEmpty(token)) {
            token = (String) oaGetoken(oaUrl).get("token");
        }

        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);
        String userInfo = HttpRequest.get(oaUrl + "/api/custom/hr/user/getUserInfoByWorkcode?workcode="+userId)
                .header("appid", APPID)
                .header("token", token)
                .header("userid", encryptUserid1)
                .header("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
                .execute().body();
        return  userInfo;
    }
}


