package com.fjhx;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fjhx.utils.Assert;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.*;

@Slf4j
public class ImClient {

    private static final RestTemplate restTemplate = new RestTemplate();
    private static final String baseUrl = "https://console.tim.qq.com/";
    private static final TLSSigAPIv2 tlsSigAPIv2 = new TLSSigAPIv2(ImConfig.sdkappid, ImConfig.key);

//    public static void main(String[] args) {
//        getGroup("test1");

//        setPortrait("test3","测试nickName3");

//        createUsers("test4", "test5");

//        addFriends("test1", Arrays.asList("test4", "test5"), "group1", "group2");

//        System.err.println(getFriends("test1", Arrays.asList("test2", "test3", "test4", "test5")).toJSONString());
//    }

    /**
     * 导入帐号
     * <p>
     *
     * @param userId  （必填）用户id，长度不超过32个字节
     * @param nick    用户昵称
     * @param faceUrl 用户头像 URL
     * @link { https://cloud.tencent.com/document/product/269/1608 }
     */
    public static void createUser(String userId, String nick, String faceUrl) {
        Map<String, String> requestBody = new HashMap<>();
        requestBody.put("UserID", userId);
        requestBody.put("Nick", nick);
        requestBody.put("FaceUrl", faceUrl);

        JSONObject result = call(getUrl("v4/im_open_login_svc/account_import"), requestBody);
        validation(result, "导入帐号");
    }

    /**
     * 导入多个账号
     * <p>
     *
     * @param userIds （必填）用户id列表
     * @link { https://cloud.tencent.com/document/product/269/4919 }
     */
    public static void createUsers(String... userIds) {
        Assert.eqTrue(userIds.length <= 100, "批量添加数量不能大于100");

        Map<Object, Object> requestBody = new HashMap<>();
        requestBody.put("Accounts", Arrays.asList(userIds));

        JSONObject result = call(getUrl("v4/im_open_login_svc/multiaccount_import"), requestBody);
        validation(result, "导入多个账号");
    }

    /**
     * 设置资料
     * <p>
     *
     * @param fromAccount （必填）账号列表
     * @link { https://cloud.tencent.com/document/product/269/1640 }
     * @link ProfileItem字段 { https://cloud.tencent.com/document/product/269/1500#.E6.A0.87.E9.85.8D.E8.B5.84.E6.96.99.E5.AD.97.E6.AE.B5 }
     */
    public static void setPortrait(String fromAccount, String nickName) {

        HashMap<String, String> item = new HashMap<>();
        item.put("Tag", "Tag_Profile_IM_Nick");
        item.put("Value", nickName);

        Map<Object, Object> requestBody = new HashMap<>();
        requestBody.put("From_Account", fromAccount);
        requestBody.put("ProfileItem", Collections.singletonList(item));

        JSONObject result = call(getUrl("v4/profile/portrait_set"), requestBody);
        validation(result, "设置资料");
    }


    /**
     * 导入好友
     * <p>
     *
     * @link { https://cloud.tencent.com/document/product/269/8301 }
     */
    public static void addFriends(String fromAccount, List<String> toAccountList, String groupName) {

        List<Map<String, Object>> addFriendItem = new ArrayList<>();

        for (String toAccount : toAccountList) {
            Map<String, Object> item = new HashMap<>();
            item.put("To_Account", toAccount);
            item.put("AddSource", "AddSource_Type_service");
            item.put("GroupName", Collections.singletonList(groupName));
            addFriendItem.add(item);
        }

        HashMap<String, Object> requestBody = new HashMap<>();
        requestBody.put("From_Account", fromAccount);
        requestBody.put("AddFriendItem", addFriendItem);

        JSONObject result = call(getUrl("v4/sns/friend_import"), requestBody);
        validation(result, "导入好友");
    }

    /**
     * 拉取分组
     * <p>
     *
     * @link { https://cloud.tencent.com/document/product/269/54763 }
     */
    private static JSONArray getGroup(String fromAccount) {
        String url = getUrl("v4/sns/group_get");
        HashMap<String, Object> requestBody = new HashMap<>();
        requestBody.put("From_Account", fromAccount);
        requestBody.put("NeedFriend", "Need_Friend_Type_Yes");

        JSONObject result = call(url, requestBody);
        validation(result, "拉取分组");

        return result.getJSONArray("result");
    }

    /**
     * 拉取指定好友
     * <p>
     *
     * @link { https://cloud.tencent.com/document/product/269/8609 }
     * @link TagList字段： { https://cloud.tencent.com/document/product/269/1500 }
     */
    private static JSONArray getFriends(String fromAccount, String... toAccount) {
        String url = getUrl("v4/sns/friend_get_list");

        HashMap<String, Object> requestBody = new HashMap<>();
        requestBody.put("From_Account", fromAccount);
        requestBody.put("To_Account", Arrays.asList(toAccount));
        // 额外查询昵称字段
        requestBody.put("TagList", Collections.singletonList("Tag_Profile_IM_Nick"));

        JSONObject result = call(url, requestBody);
        validation(result, "拉取指定好友");

        return result.getJSONArray("InfoItem");
    }

    /**
     * 获取请求url
     *
     * @param suffix 请求连接后缀
     * @return 请求url
     */
    private static String getUrl(String suffix) {
        return baseUrl + suffix + String.format("?sdkappid=%s&identifier=%s&usersig=%s&random=%s&contenttype=json",
                ImConfig.sdkappid, ImConfig.identifier, tlsSigAPIv2.genUserSig(ImConfig.identifier, ImConfig.expire),
                RandomUtil.randomNumbers(32));
    }

    /**
     * 调用im
     *
     * @param url         请求url
     * @param requestBody 请求体
     * @return 请求结果
     */
    private static JSONObject call(String url, Object requestBody) {
        ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(url, requestBody, JSONObject.class);
        JSONObject body = Objects.requireNonNull(responseEntity.getBody());
        log.info(body.toJSONString());
        return body;
    }

    /**
     * 验证调用是否成功
     *
     * @param result  返回值
     * @param explain 提示
     */
    private static void validation(JSONObject result, String explain) {
        Integer errorCode = result.getInteger("ErrorCode");
        if (errorCode != 0) {
            String error = explain + "失败，错误码：" + errorCode;
            log.error(error);
            throw new ServiceException(error);
        }
    }

}
