package com.api.meeting.cusvideo.util;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.lang.UUID;
import cn.hutool.http.ContentType;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import weaver.conn.RecordSet;
import weaver.file.Prop;
import weaver.general.BaseBean;
import weaver.general.StaticObj;
import weaver.general.Util;
import weaver.hrm.resource.ResourceComInfo;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @Description:
 * @Author: lj
 * @CreateTime: 2023-06-05 15:51
 * @Version: 1.0
 */
public class YealinkVideoUtil {
    private static BaseBean logger = new BaseBean();
    private static final String YEA_LINK_TOKEN_KEY = "YEA_LINK_TOKEN_KEY";
    private static StaticObj cache = StaticObj.getInstance();

    /**
     * 执行post请求
     *
     * @param url
     * @param header
     * @param body
     * @return
     */
    public static JSONObject doPost(String url, String token, Map<String, String> header, JSONObject body) {
        try {
            logger.writeLog("^^^ YealinkVideoUtil.doPost : url = " + url);
            if (header == null) header = new HashMap<>();
            if (!header.containsKey("Authorization")) header.put("Authorization", "Bearer " + token);
            if (!header.containsKey("timestamp")) header.put("timestamp", System.currentTimeMillis() + "");
            if (!header.containsKey("nonce")) header.put("nonce", UUID.randomUUID().toString(true));
            if (body == null) body = new JSONObject();
            logger.writeLog("^^^ YealinkVideoUtil.doPost : url = " + url
                    + " , header = " + JSONObject.toJSONString(header)
                    + " , body = " + body.toJSONString()
            );
            HttpResponse response = HttpRequest.post(url)
                    .charset(StandardCharsets.UTF_8)
                    .addHeaders(header)
                    .body(body.toJSONString())
                    .execute()
                    .charset(StandardCharsets.UTF_8);
            String result = response.body();
            logger.writeLog("^^^ YealinkVideoUtil.doPost : url = " + url + " , result = " + result);
            JSONObject resultJson = JSONObject.parseObject(result);
            if (response.getStatus() != 200) {
                throw new RuntimeException("[" + resultJson.getString("code") + "]" + resultJson.getString("message"));
            }
            return resultJson;
        } catch (Exception e) {
            logger.writeLog("^^^ YealinkVideoUtil.doPost : 接口[" + url + "]请求失败！！！", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 执行get请求
     *
     * @param url
     * @param token
     */
    public static JSONObject doGet(String url, String token, Map<String, String> header, JSONObject body) {
        try {
            logger.writeLog("^^^ YealinkVideoUtil.doGet : url = " + url);
            if (header == null) header = new HashMap<>();
            if (!header.containsKey("Authorization")) header.put("Authorization", "Bearer " + token);
            if (!header.containsKey("timestamp")) header.put("timestamp", System.currentTimeMillis() + "");
            if (!header.containsKey("nonce")) header.put("nonce", UUID.randomUUID().toString(true));
            if (body == null) body = new JSONObject();
            logger.writeLog("^^^ YealinkVideoUtil.doGet : url = " + url
                    + " , header = " + JSONObject.toJSONString(header)
                    + " , body = " + body.toJSONString()
            );
            HttpResponse response = HttpRequest.get(url)
                    .charset(StandardCharsets.UTF_8)
                    .addHeaders(header)
                    .contentType(ContentType.JSON.getValue())
                    .form(body)
                    .execute()
                    .charset(StandardCharsets.UTF_8);
            String result = response.body();
            logger.writeLog("^^^ YealinkVideoUtil.doGet : url = " + url + " , result = " + result);
            JSONObject resultJson = JSONObject.parseObject(result);
            if (response.getStatus() != 200) {
                throw new RuntimeException("[" + resultJson.getString("code") + "]" + resultJson.getString("message"));
            }
            return resultJson;
        } catch (Exception e) {
            logger.writeLog("^^^ YealinkVideoUtil.doGet : 接口[" + url + "]请求失败！！！", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 执行put请求
     *
     * @param url
     * @param token
     * @param header
     * @param body
     * @return
     */
    public static JSONObject doPut(String url, String token, Map<String, String> header, JSONObject body) {
        try {
            logger.writeLog("^^^ YealinkVideoUtil.doPut : url = " + url);
            if (header == null) header = new HashMap<>();
            if (!header.containsKey("Authorization")) header.put("Authorization", "Bearer " + token);
            if (!header.containsKey("timestamp")) header.put("timestamp", System.currentTimeMillis() + "");
            if (!header.containsKey("nonce")) header.put("nonce", UUID.randomUUID().toString(true));
            if (body == null) body = new JSONObject();
            logger.writeLog("^^^ YealinkVideoUtil.doPut : url = " + url
                    + " , header = " + JSONObject.toJSONString(header)
                    + " , body = " + body.toJSONString()
            );
            HttpResponse response = HttpRequest.put(url)
                    .charset(StandardCharsets.UTF_8)
                    .addHeaders(header)
                    .body(body.toJSONString())
                    .execute()
                    .charset(StandardCharsets.UTF_8);
            String result = response.body();
            logger.writeLog("^^^ YealinkVideoUtil.doPut : url = " + url + " , result = " + result);
            JSONObject resultJson = JSONObject.parseObject(result);
            if (response.getStatus() != 200) {
                throw new RuntimeException("[" + resultJson.getString("code") + "]" + resultJson.getString("message"));
            }
            return resultJson;
        } catch (Exception e) {
            logger.writeLog("^^^ YealinkVideoUtil.doPut : 接口[" + url + "]请求失败！！！", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 执行delete方法
     *
     * @param url
     * @param token
     * @param header
     * @param body
     * @return
     */
    public static JSONObject doDelete(String url, String token, Map<String, String> header, JSONObject body) {
        try {
            logger.writeLog("^^^ YealinkVideoUtil.doDelete : url = " + url);
            if (header == null) header = new HashMap<>();
            if (!header.containsKey("Authorization")) header.put("Authorization", "Bearer " + token);
            if (!header.containsKey("timestamp")) header.put("timestamp", System.currentTimeMillis() + "");
            if (!header.containsKey("nonce")) header.put("nonce", UUID.randomUUID().toString(true));
            if (body == null) body = new JSONObject();
            logger.writeLog("^^^ YealinkVideoUtil.doDelete : url = " + url
                    + " , header = " + JSONObject.toJSONString(header)
                    + " , body = " + body.toJSONString()
            );
            List<String> queryList = new ArrayList<>();
            for (Object key : body.keySet()) {
                if (key != null) {
                    queryList.add(key + "=" + body.getString((String) key));
                }
            }
            if (queryList.size() > 0) {
                if (url.contains("?")) {
                    url += "&";
                } else {
                    url += "?";
                }
                url += StringUtils.join(queryList, "&");
            }
            HttpResponse response = HttpRequest.delete(url)
                    .charset(StandardCharsets.UTF_8)
                    .addHeaders(header)
                    .contentType(ContentType.JSON.getValue())
                    .execute()
                    .charset(StandardCharsets.UTF_8);
            String result = response.body();
            logger.writeLog("^^^ YealinkVideoUtil.doDelete : url = " + url + " , result = " + result);
            JSONObject resultJson = JSONObject.parseObject(result);
            if (response.getStatus() != 200) {
                throw new RuntimeException("[" + resultJson.getString("code") + "]" + resultJson.getString("message"));
            }
            return resultJson;
        } catch (Exception e) {
            logger.writeLog("^^^ YealinkVideoUtil.doDelete : 接口[" + url + "]请求失败！！！", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 获取token
     *
     * @param appKey
     * @param appSecret
     * @return
     */
    public static String getToken(String host, String appKey, String appSecret) {
        String token = "";
        try {
            //1、从缓存中获取
            Object object = cache.getObject(YEA_LINK_TOKEN_KEY);
            if (object != null) {
                JSONObject tokenObj = JSONObject.parseObject((String) object);
                if (tokenObj != null) {
                    long expires_in = tokenObj.getLongValue("expires_in");
                    if (expires_in > System.currentTimeMillis()) {
                        token = tokenObj.getString("access_token");
                    } else {
                        cache.removeObject(YEA_LINK_TOKEN_KEY);
                    }
                }
            }
            if (StringUtils.isBlank(token)) {//去获取token
                //请求头
                Map<String, String> header = new HashMap<>();
                header.put("Authorization", "Basic " + Base64.encode(appKey + ":" + appSecret));
                header.put("timestamp", System.currentTimeMillis() + "");
                header.put("nonce", UUID.randomUUID().toString(true));
                //请求体
                JSONObject body = new JSONObject();
                body.put("grant_type", "client_credentials");
                //构建请求url
                String url = host + "/token";
                //执行请求
                logger.writeLog("^^^ YealinkVideoUtil.getToken : url = " + url);
                logger.writeLog("^^^ YealinkVideoUtil.getToken : header = " + JSONObject.toJSONString(header));
                logger.writeLog("^^^ YealinkVideoUtil.getToken : body = " + body.toJSONString());
                HttpResponse response = HttpRequest.post(url)
                        .charset(StandardCharsets.UTF_8)
                        .addHeaders(header)
                        .body(body.toJSONString())
                        .execute()
                        .charset(StandardCharsets.UTF_8);
                String result = response.body();
                logger.writeLog("^^^ YealinkVideoUtil.getToken : url = " + url + " , result = " + result);
                JSONObject resultJson = JSONObject.parseObject(result);
                if (response.getStatus() != 200) {
                    throw new RuntimeException("[" + resultJson.getString("code") + "]" + resultJson.getString("message"));
                }
                //设置过期时间
                int expires_in = resultJson.getIntValue("expires_in");
                resultJson.put("expires_in", System.currentTimeMillis() + expires_in * 1000L);
                //缓存token
                cache.putObject(YEA_LINK_TOKEN_KEY, resultJson.toJSONString());
                token = resultJson.getString("access_token");
            }
            return token;
        } catch (Exception e) {
            logger.writeLog("^^^ YealinkVideoUtil.getToken : error !!!", e);
            throw new RuntimeException("Token获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取yealink的用户id
     *
     * @param host
     * @param token
     * @param userId
     * @return
     */
    public static String getYeaLinkUserId(String host, String token, String userId) {
        String value = "";
        String hrmYeaLinkCusFieldName = Util.null2String(Prop.getPropValue("qc2281950", "hrmYeaLinkCusFieldName"));
        String hrmYeaLinkIdCusFieldScope = Util.null2s(Prop.getPropValue("qc2281950", "hrmYeaLinkIdCusFieldScope"), "-1");
        RecordSet rs = new RecordSet();
        new BaseBean().writeLog("^^^ YealinkVideoUtil.getYeaLinkUserId : userId = " + userId
                + " , hrmYeaLinkCusFieldName = " + hrmYeaLinkCusFieldName
                + " , hrmYeaLinkIdCusFieldScope = " + hrmYeaLinkIdCusFieldScope);
        rs.executeQuery("select " + hrmYeaLinkCusFieldName + " from cus_fielddata " +
                "where scope='HrmCustomFieldByInfoType' and scopeid=? and id=?", hrmYeaLinkIdCusFieldScope, userId);
        if (rs.next()) {
            value = Util.null2String(rs.getString(1));
        }
        if (StringUtils.isBlank(value)) {
            //如果为空，则这里需要去添加用户，以获得返回后的亿联用户ID
            value = addYeaLinkUser(userId, host, token);
        }
        return value;
    }

    /**
     * 添加yealink用户
     *
     * @param userId
     * @param host
     * @param token
     * @return
     */
    public static String addYeaLinkUser(String userId, String host, String token) {
        try {
            ResourceComInfo comInfo = new ResourceComInfo();
            JSONObject body = new JSONObject();
            body.put("name", comInfo.getLastname(userId));
            body.put("extension", comInfo.getWorkcode(userId));
            String mobile = getUserMobile(Util.getIntValue(userId));//comInfo.getMobile(userId);
            body.put("mobile", mobile);
            //判断手机号是否存在
            if (StringUtils.isBlank(mobile)) {
                throw new RuntimeException("手机号[mobile]不能为空");
            }
            //先查询亿联是否存在用户
            String yeaLinkUserId = queryYeaLinkUserId(host, token, mobile);
            if (StringUtils.isBlank(yeaLinkUserId)) {
                String url = host + "/users";
                JSONObject resultObj = doPost(url, token, null, body);
                //取出ID
                yeaLinkUserId = resultObj.getString("id");
            }
            //更新到人力资源自定义表中
            updateHrmYeaLinkUserId(userId, yeaLinkUserId);
            return yeaLinkUserId;
        } catch (Exception e) {
            logger.writeLog("^^^ YealinkVideoUtil.addYeaLinkUser : error !!!", e);
            throw new RuntimeException("添加亿联用户失败：" + e.getMessage());
        }
    }

    /**
     * 获取脱敏前的手机号
     * @param uid
     * @return
     */
    public static String getUserMobile(int uid) {
        RecordSet rs = new RecordSet();
        rs.setEncrypt(false);
        rs.executeQuery("select mobile from hrmresource where id=?", uid);
        rs.next();
        return Util.null2String(rs.getString(1));
    }

    /**
     * 根据手机号查询用户
     *
     * @param mobile
     * @return
     */
    private static String queryYeaLinkUserId(String host, String token, String mobile) {
        JSONObject body = new JSONObject();
        body.put("mobile", mobile);
        body.put("limit", 1);
        String url = host + "/users";
        JSONObject resultObj = doGet(url, token, null, body);
        //取出数据
        JSONArray dataArr = resultObj.getJSONArray("data");
        if (dataArr != null && dataArr.size() > 0) {
            JSONObject dataObj = dataArr.getJSONObject(0);
            String phone = Util.null2String(dataObj.getString("mobile"));
            if (mobile.equals(phone)) {
                return Util.null2String(dataObj.getString("id"));
            }
        }
        return null;
    }

    /**
     * 更新自定义字段值
     *
     * @param yeaLinkUserId
     */
    private static void updateHrmYeaLinkUserId(String userId, String yeaLinkUserId) {
        String hrmYeaLinkCusFieldName = Util.null2String(Prop.getPropValue("qc2281950", "hrmYeaLinkCusFieldName"));
        String hrmYeaLinkIdCusFieldScope = Util.null2s(Prop.getPropValue("qc2281950", "hrmYeaLinkIdCusFieldScope"), "-1");
        RecordSet rs = new RecordSet();
        new BaseBean().writeLog("^^^ YealinkVideoUtil.updateHrmYeaLinkUserId : userId = " + userId
                + " , hrmYeaLinkCusFieldName = " + hrmYeaLinkCusFieldName
                + " , hrmYeaLinkIdCusFieldScope = " + hrmYeaLinkIdCusFieldScope);
        String sql = "select * from cus_fielddata where scope='HrmCustomFieldByInfoType' and scopeid=? and id=?";
        rs.executeQuery(sql, hrmYeaLinkIdCusFieldScope, userId);
        if (rs.next()) {//存在记录做更新
            sql = "update cus_fielddata set " + hrmYeaLinkCusFieldName +
                    "=? where scope='HrmCustomFieldByInfoType' and scopeid=? and id=?";
            List params = Arrays.asList(yeaLinkUserId, hrmYeaLinkIdCusFieldScope, userId);
            boolean flag = rs.executeUpdate(sql, params.toArray());
            if (!flag) {
                logger.writeLog("^^^ YealinkVideoUtil.updateHrmYeaLinkUserId : execute update sql error , sql = " + sql
                        + " , params = " + JSONObject.toJSONString(params));
            }
        } else {//不存在记录做新增
            sql = "insert into cus_fielddata (scope,scopeid,id," + hrmYeaLinkCusFieldName + ") " +
                    "values ('HrmCustomFieldByInfoType',?,?,?)";
            List params = Arrays.asList(hrmYeaLinkIdCusFieldScope, userId, yeaLinkUserId);
            boolean flag = rs.executeUpdate(sql, params.toArray());
            if (!flag) {
                logger.writeLog("^^^ YealinkVideoUtil.updateHrmYeaLinkUserId : execute insert sql error , sql = " + sql
                        + " , params = " + JSONObject.toJSONString(params));
            }
        }

    }

}
