package com.liquidnet.common.third.easemob.util;

import com.alibaba.fastjson.JSONObject;
import com.easemob.im.server.api.token.allocate.TokenResponse;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.common.third.easemob.config.EasemobConfig;
import com.liquidnet.common.third.easemob.constant.EasemobConstant;
import com.liquidnet.commons.lang.util.HttpUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.commons.lang.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;

import java.nio.charset.StandardCharsets;

/**
 * @author AnJiabin <anjiabin@zhengzai.tv>
 * @version V1.0
 * @Description: TODO
 * @class: EasemobUtil
 * @Package com.liquidnet.common.third.easemob.util
 * @Copyright: LightNet @ Copyright (c) 2021
 * @date 2021/9/6 16:08
 */
@Slf4j
@Component
public class EasemobUtil{
    @Autowired
    private EasemobConfig easemobConfig;

    @Autowired
    private RedisUtil redisUtil;

    private static MultiValueMap<String, String> commonHeader = new LinkedMultiValueMap();
    private static MultiValueMap<String, String> commonParams = new LinkedMultiValueMap();

    private String getAccessToken(){

        //构造请求参数
//        LinkedMultiValueMap<String, String> reqParam = CollectionUtil.linkedMultiValueMapStringString();
//        reqParam.add("grant_type", "client_credentials");
//        reqParam.add("client_id",CLIENT_ID);
//        reqParam.add("client_secret", CLIENT_SECRET);

        Object redisValue = redisUtil.get(EasemobConstant.API_ACCESS_TOKEN_REDIS_KEY);
        if(StringUtil.isNotNull(redisValue)&&StringUtil.isNotBlank(redisValue.toString())){
            log.info("getAccessToken cache token : {} ",redisValue);
            return redisValue.toString();
        }
        JSONObject json = new JSONObject();
        json.put("grant_type", "client_credentials");
        json.put("client_id", easemobConfig.getClientId());
        json.put("client_secret", easemobConfig.getClientSecret());

        String requestUrl = easemobConfig.getPreUrl() + EasemobConstant.GET_TOKEN_URL;
        log.info("getAccessToken--->>> request url : {}  body : {} ",requestUrl, json.toString());
        String response = HttpUtil.postJson(requestUrl,json.toString());
        log.info("getAccessToken--->>> response : {} ",response);
        TokenResponse tokenResponse = JsonUtils.fromJson(response,TokenResponse.class);
        log.info("getAccessToken--->>> response access_token : {} ",tokenResponse.asToken().getValue());
        log.info("getAccessToken--->>> token isValid json : {} ",tokenResponse.asToken().isValid());

        //设置缓存
        String token = tokenResponse.asToken().getValue();
        redisUtil.set(EasemobConstant.API_ACCESS_TOKEN_REDIS_KEY,token,EasemobConstant.API_ACCESS_TOKEN_EXPIRES_TIME_SECOND);
        return token;
        //result
//        {application=c785eced-c603-41c3-afe8-13ee3378540c, access_token=YWMt_rE7Rg8DEeyy6gf--JvBcwAAAAAAAAAAAAAAAAAAAAHHheztxgNBw6_oE-4zeFQMAgMAAAF7utOj1gBPGgANws4VZcHltyc-SPep4q09E0mqitzKe5IA6Npu-MqLBg, expires_in=5184000}
        //YWMtofR7bg8FEeyuuledizf-EgAAAAAAAAAAAAAAAAAAAAHHheztxgNBw6_oE-4zeFQMAgMAAAF7ut5fhQBPGgA4h21-XSZ9vq_q69wQlp3racC2cpUtlNHJfma547Ygkg
    }

    public void createUser(String userName,String password){
        this.createUser(userName,password,null);
    }

    public String createUser(String userName, String password, String nickName){
//        MultiValueMap<String, String> commonHeader = new LinkedMultiValueMap();
        commonHeader.clear();
        commonHeader.add("Authorization", "Bearer "+this.getAccessToken());

        JSONObject json = new JSONObject();
        json.put("username", userName);
        json.put("password", password);
        if(StringUtil.isNotEmpty(nickName)){
            json.put("nickname", nickName);
        }
        String requestUrl = easemobConfig.getPreUrl() + EasemobConstant.CREATE_USER_URL;
        log.info("createUsers--->>> request url : {}  body : {} ",requestUrl, json.toString());

        String response = null;
//        ObjectNode objectNode = JsonUtils.OM().createObjectNode();
        try {
            response = HttpUtil.postJson(requestUrl,json.toString(),commonHeader);
        } catch(HttpClientErrorException e) {
            log.error("createUser error", e);
            if(e.getRawStatusCode() == 400){
                JSONObject jsonObject = JsonUtils.fromJson(e.getResponseBodyAsString(), new TypeReference<JSONObject>() {});
                return jsonObject.toJSONString();
            }
        }catch (Exception e) {
            log.error("createUser error",e);
        }
        log.info("createUsers--->>> response : {} ",response);

        if (StringUtils.isEmpty(response)) {
            return response;
        }
        ObjectNode jsonObject = JsonUtils.fromJson(response,ObjectNode.class);
        ArrayNode arrayNode = (ArrayNode)jsonObject.get("entities");
        response = arrayNode.get(0).toString();
        return response;
        //result
//        {application=c785eced-c603-41c3-afe8-13ee3378540c, access_token=YWMt_rE7Rg8DEeyy6gf--JvBcwAAAAAAAAAAAAAAAAAAAAHHheztxgNBw6_oE-4zeFQMAgMAAAF7utOj1gBPGgANws4VZcHltyc-SPep4q09E0mqitzKe5IA6Npu-MqLBg, expires_in=5184000}
    }

    public void settingNoticeNickname(String nickname, String username) {
        try {
            commonHeader.clear();
            commonHeader.add("Authorization", "Bearer " + this.getAccessToken());
            commonParams.clear();
            commonParams.add("nickname", nickname);

            String url = easemobConfig.getPreUrl().concat(EasemobConstant.CREATE_USER_URL).concat("/").concat(username);
            String response = HttpUtil.put(url, commonParams, commonHeader);
            log.info("IM setting notice.nickname:[url={},nickname={},response={}]", url, nickname, response);
        } catch (HttpClientErrorException e) {
            String responseBodyAsString = e.getResponseBodyAsString(StandardCharsets.UTF_8);
            log.error("IM setting notice.nickname error:[request.status=400,msg={}]", responseBodyAsString);
        } catch (Exception e) {
            log.error("IM setting notice.nickname exception", e);
        }
    }
}
