package com.yonge.cooleshow.biz.dal.support;

import com.alibaba.fastjson.JSON;
import com.yonge.cooleshow.biz.dal.entity.BaseMessage;
import com.yonge.cooleshow.biz.dal.entity.IMApiResultInfo;
import com.yonge.cooleshow.biz.dal.entity.IMTokenInfo;
import com.yonge.toolset.base.exception.BizException;
import io.rong.util.GsonUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.util.List;
import java.util.Objects;

/**
 * Created by weiqinxiao on 2019/2/28.
 */
@Component
public class IMHelper {

    private final static Logger log = LoggerFactory.getLogger(IMHelper.class);

    private static final String UTF8 = "UTF-8";

    @Autowired
    HttpHelper httpHelper;

    /**
     * 获取 Token 方法
     *
     * @param userId:用户        Id，最大长度 64 字节.是用户在 App 中的唯一标识码，必须保证在同一个 App 内不重复，重复的用户 Id 将被当作是同一用户。（必传）
     * @param name:用户名称，最大长度   128 字节.用来在 Push 推送时显示用户的名称.用户名称，最大长度 128 字节.用来在 Push 推送时显示用户的名称。（必传）
     * @param portraitUri:用户头像 URI，最大长度 1024 字节.用来在 Push 推送时显示用户的头像。（必传）
     * @return TokenResult
     **/
    public IMTokenInfo getToken(String userId, String name, String portraitUri) throws Exception {
        if (userId == null) {
            throw new IllegalArgumentException("Paramer 'userId' is required");
        }

        if (name == null) {
            throw new IllegalArgumentException("Paramer 'name' is required");
        }

        if (portraitUri == null) {
            throw new IllegalArgumentException("Paramer 'portraitUri' is required");
        }

        StringBuilder sb = new StringBuilder();
        sb.append("&userId=").append(URLEncoder.encode(userId, UTF8));
        sb.append("&name=").append(URLEncoder.encode(name, UTF8));
        sb.append("&portraitUri=").append(URLEncoder.encode(portraitUri, UTF8));
        String body = sb.toString();
        if (body.indexOf("&") == 0) {
            body = body.substring(1);
        }

        HttpURLConnection conn = httpHelper.createIMPostHttpConnection("/user/getToken.json", "application/x-www-form-urlencoded");
        httpHelper.setBodyParameter(body, conn);

        return JSON.parseObject(httpHelper.returnResult(conn, body), IMTokenInfo.class);
    }

    /**
     * 创建群组方法（创建群组，并将用户加入该群组，用户将可以收到该群的消息，同一用户最多可加入 500 个群，每个群最大至 3000 人，App
     * 内的群组数量没有限制.注：其实本方法是加入群组方法 /group/join 的别名。）
     *
     * @param userId:要加入群的用户 Id。（必传）
     * @param groupId:创建群组   Id。（必传）
     * @param groupName:群组   Id 对应的名称。（必传）
     * @return CodeSuccessResult
     **/
    public IMApiResultInfo createGroup(String[] userId, String groupId, String groupName)
            throws Exception {
        if (userId == null) {
            throw new IllegalArgumentException("Paramer 'userId' is required");
        }

        if (groupId == null) {
            throw new IllegalArgumentException("Paramer 'groupId' is required");
        }

        if (groupName == null) {
            throw new IllegalArgumentException("Paramer 'groupName' is required");
        }

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < userId.length; i++) {
            String child = userId[i];
            sb.append("&userId=").append(URLEncoder.encode(child, UTF8));
        }

        sb.append("&groupId=").append(URLEncoder.encode(groupId, UTF8));
        sb.append("&groupName=").append(URLEncoder.encode(groupName, UTF8));
        String body = sb.toString();
        if (body.indexOf("&") == 0) {
            body = body.substring(1);
        }

        HttpURLConnection conn = httpHelper
                .createIMPostHttpConnection("/group/create.json", "application/x-www-form-urlencoded");
        httpHelper.setBodyParameter(body, conn);

        return JSON.parseObject(httpHelper.returnResult(conn, body), IMApiResultInfo.class);
    }


    /**
     * 将用户加入指定群组，用户将可以收到该群的消息，同一用户最多可加入 500 个群，每个群最大至 3000 人。
     *
     * @param userId:要加入群的用户  Id，可提交多个，最多不超过 1000 个。（必传）
     * @param groupId:要加入的群   Id。（必传）
     * @param groupName:要加入的群 Id 对应的名称。（必传）
     * @return CodeSuccessResult
     **/
    @Async
    public IMApiResultInfo joinGroup(String[] userId, String groupId, String groupName)
            throws Exception {
        if (userId == null) {
            throw new IllegalArgumentException("Paramer 'userId' is required");
        }

        if (groupId == null) {
            throw new IllegalArgumentException("Paramer 'groupId' is required");
        }

        if (groupName == null) {
            throw new IllegalArgumentException("Paramer 'groupName' is required");
        }

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < userId.length; i++) {
            String child = userId[i];
            sb.append("&userId=").append(URLEncoder.encode(child, UTF8));
        }

        sb.append("&groupId=").append(URLEncoder.encode(groupId, UTF8));
        sb.append("&groupName=").append(URLEncoder.encode(groupName, UTF8));
        String body = sb.toString();
        if (body.indexOf("&") == 0) {
            body = body.substring(1);
        }

        HttpURLConnection conn = httpHelper
                .createIMPostHttpConnection("/group/join.json", "application/x-www-form-urlencoded");
        httpHelper.setBodyParameter(body, conn);

        return JSON.parseObject(httpHelper.returnResult(conn, body), IMApiResultInfo.class);
    }


    /**
     * 退出群组方法（将用户从群中移除，不再接收该群组的消息.）
     *
     * @param userId:要退出群的用户 Id.（必传）
     * @param groupId:要退出的群  Id.（必传）
     * @return CodeSuccessResult
     **/
    public IMApiResultInfo quit(String[] userId, String groupId) throws Exception {
        if (userId == null) {
            throw new IllegalArgumentException("Paramer 'userId' is required");
        }

        if (groupId == null) {
            throw new IllegalArgumentException("Paramer 'groupId' is required");
        }

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < userId.length; i++) {
            String child = userId[i];
            sb.append("&userId=").append(URLEncoder.encode(child, UTF8));
        }

        sb.append("&groupId=").append(URLEncoder.encode(groupId, UTF8));
        String body = sb.toString();
        if (body.indexOf("&") == 0) {
            body = body.substring(1);
        }

        HttpURLConnection conn = httpHelper
                .createIMPostHttpConnection("/group/quit.json", "application/x-www-form-urlencoded");
        httpHelper.setBodyParameter(body, conn);

        return JSON.parseObject(httpHelper.returnResult(conn, body), IMApiResultInfo.class);
    }


    /**
     * 解散群组方法。（将该群解散，所有用户都无法再接收该群的消息。）
     *
     * @param userId:操作解散群的用户 Id。（必传）
     * @param groupId:要解散的群   Id。（必传）
     * @return CodeSuccessResult
     **/
    public IMApiResultInfo dismiss(String userId, String groupId) throws Exception {
        if (userId == null) {
            throw new IllegalArgumentException("Paramer 'userId' is required");
        }

        if (groupId == null) {
            throw new IllegalArgumentException("Paramer 'groupId' is required");
        }

        StringBuilder sb = new StringBuilder();
        sb.append("&userId=").append(URLEncoder.encode(userId, UTF8));
        sb.append("&groupId=").append(URLEncoder.encode(groupId, UTF8));
        String body = sb.toString();
        if (body.indexOf("&") == 0) {
            body = body.substring(1, body.length());
        }

        HttpURLConnection conn = httpHelper
                .createIMPostHttpConnection("/group/dismiss.json", "application/x-www-form-urlencoded");
        httpHelper.setBodyParameter(body, conn);

        return JSON.parseObject(httpHelper.returnResult(conn, body), IMApiResultInfo.class);
    }


    /**
     * 发送群组消息方法（以一个用户身份向群组发送消息，单条消息最大 128k.每秒钟最多发送 20 条消息，每次最多向 3 个群组发送，如：一次向 3 个群组发送消息，示为 3 条消息。）
     *
     * @param fromUserId:发送人用户                         Id 。（必传）
     * @param toGroupId:接收群Id，提供多个本参数可以实现向多群发送消息，最多不超过 3 个群组。（必传）
     * @return CodeSuccessResult
     **/
    public IMApiResultInfo publishMessage(String fromUserId, String toGroupId, BaseMessage message) throws Exception {
        String[] toGroupIds = new String[1];
        toGroupIds[0] = toGroupId;
        return publishMessage(fromUserId, null, toGroupIds, message, "", "", 0,
                0, 0, 0, 0);
    }

    public IMApiResultInfo publishMessage(String fromUserId, String toGroupId, BaseMessage message, Integer isIncludeSender) throws Exception {
        String[] toGroupIds = new String[1];
        toGroupIds[0] = toGroupId;
        return publishMessage(fromUserId, null, toGroupIds, message, "", "", 0,
                0, isIncludeSender, 0, 0);
    }

    //定向消息 toUserId 指向对应的人
    public IMApiResultInfo publishMessage(String fromUserId, String toUserId, String toGroupId, BaseMessage message) throws Exception {
        String[] toGroupIds = new String[1];
        toGroupIds[0] = toGroupId;
        return publishMessage(fromUserId, toUserId, toGroupIds, message, "", "", 0,
                0, 0, 0, 0);
    }

    public IMApiResultInfo publishMessage(String fromUserId, String toUserId, String[] toGroupId,
                                          BaseMessage message, String pushContent, String pushData, Integer isPersisted,
                                          Integer isCounted, Integer isIncludeSender, Integer isStatus, Integer isMentioned)
            throws Exception {
        if (fromUserId == null) {
            throw new IllegalArgumentException("Paramer 'fromUserId' is required");
        }

        if (toGroupId == null) {
            throw new IllegalArgumentException("Paramer 'toGroupId' is required");
        }

        if (message == null) {
            throw new IllegalArgumentException("Paramer 'message' is required");
        }

        StringBuilder sb = new StringBuilder();
        sb.append("&fromUserId=").append(URLEncoder.encode(fromUserId, UTF8));

        //定向消息
        if (toUserId != null) {
            sb.append("&toUserId=").append(URLEncoder.encode(toUserId, UTF8));
        }

        for (int i = 0; i < toGroupId.length; i++) {
            String child = toGroupId[i];
            sb.append("&toGroupId=").append(URLEncoder.encode(child, UTF8));
        }

        String msgStr = message.toString();
        log.info("publish msg: {}", msgStr);
        sb.append("&objectName=").append(URLEncoder.encode(message.getObjectName(), UTF8));
        sb.append("&content=").append(URLEncoder.encode(msgStr, UTF8));

        if (pushContent != null) {
            sb.append("&pushContent=").append(URLEncoder.encode(pushContent, UTF8));
        }

        if (pushData != null) {
            sb.append("&pushData=").append(URLEncoder.encode(pushData, UTF8));
        }

        if (isPersisted != null) {
            sb.append("&isPersisted=").append(URLEncoder.encode(isPersisted.toString(), UTF8));
        }

        if (isCounted != null) {
            sb.append("&isCounted=").append(URLEncoder.encode(isCounted.toString(), UTF8));
        }

        if (isIncludeSender != null) {
            sb.append("&isIncludeSender=")
                    .append(URLEncoder.encode(isIncludeSender.toString(), UTF8));
        }

        if (isMentioned != null) {
            sb.append("&isMentioned=").append(URLEncoder.encode(isMentioned.toString(), UTF8));
        }

        String body = sb.toString();
        if (body.indexOf("&") == 0) {
            body = body.substring(1, body.length());
        }

        String url;
        if (isStatus != null && isStatus.intValue() == 1) {
            url = "/statusmessage/group/publish.json";
        } else {
            url = "/message/group/publish.json";
        }

        HttpURLConnection conn = httpHelper
                .createIMPostHttpConnection(url, "application/x-www-form-urlencoded");
        httpHelper.setBodyParameter(body, conn);

        return JSON.parseObject(httpHelper.returnResult(conn, body), IMApiResultInfo.class);
    }

    /**
     * 创建聊天室
     *
     * @param chatRoomId:   要创建的聊天室 Id，长度不超过 64 字节
     * @param chatRoomName: 聊天室的名称，每次可创建多个聊天室。
     * @return IMApiResultInfo
     * @throws Exception
     */
    public IMApiResultInfo createChatRoom(String chatRoomId, String chatRoomName) throws Exception {
        if (chatRoomId == null) {
            throw new BizException("房间Uid不能为空");
        }

        if (chatRoomName == null) {
            throw new BizException("房间名称不能为空");
        }

        StringBuilder sb = new StringBuilder();
        chatRoomId = "[" + chatRoomId + "]";
        sb.append("&chatroom").append(URLEncoder.encode(chatRoomId, UTF8));
        sb.append("=");
        sb.append(URLEncoder.encode(chatRoomName, UTF8));
        String body = sb.toString();
        if (body.indexOf("&") == 0) {
            body = body.substring(1);
        }

        HttpURLConnection conn = httpHelper
                .createIMPostHttpConnection("/chatroom/create.json", "application/x-www-form-urlencoded");
        httpHelper.setBodyParameter(body, conn);

        return (IMApiResultInfo) GsonUtil.fromJson(httpHelper.returnResult(conn), IMApiResultInfo.class);
    }


    /**
     * 销毁聊天室
     *
     * @param chatroomIds 聊天室 ID 列表（必传）
     * @return
     */
    public IMApiResultInfo deleteChrm(List<String> chatroomIds)
            throws Exception {
        if (chatroomIds == null) {
            throw new BizException("房间Uid不能为空");
        }
        StringBuilder sb = new StringBuilder();
        for (String child : chatroomIds) {
            sb.append("&chatroomId=").append(URLEncoder.encode(child, UTF8));
        }
        String body = sb.toString();
        if (body.indexOf("&") == 0) {
            body = body.substring(1);
        }
        HttpURLConnection conn = httpHelper.createIMPostHttpConnection("/chatroom/destroy.json", "application/x-www-form-urlencoded");
        httpHelper.setBodyParameter(body, conn);

        return (IMApiResultInfo) GsonUtil.fromJson(httpHelper.returnResult(conn), IMApiResultInfo.class);

    }

    /**
     * 发送房间消息
     *
     * @param fromUserId   发送人id
     * @param toChatroomId 房间uid
     * @param message      发送的消息
     */
    public IMApiResultInfo publishRoomMessage(String fromUserId, String toChatroomId, BaseMessage message) throws Exception {
        String[] toChatroomIds = new String[1];
        toChatroomIds[0] = toChatroomId;
        return publishRoomMessage(fromUserId, toChatroomIds, message);
    }

    public IMApiResultInfo publishRoomMessage(String fromUserId, String[] toChatroomIds, BaseMessage message) throws Exception {
        if (StringUtils.isBlank(fromUserId)) {
            throw new BizException("发送人不能为空");
        }
        if (Objects.isNull(toChatroomIds)) {
            throw new BizException("房间Uid不能为空");
        }
        if (Objects.isNull(message)) {
            throw new BizException("消息不能为空");
        }

        StringBuilder sb = new StringBuilder();
        sb.append("&fromUserId=").append(URLEncoder.encode(fromUserId, UTF8));

        for (String child : toChatroomIds) {
            sb.append("&toChatroomId=").append(URLEncoder.encode(child, UTF8));
        }

        String msgStr = GsonUtil.toJson(message);
        log.info("publish msg: {}", msgStr);
        sb.append("&objectName=").append(URLEncoder.encode(message.getObjectName(), UTF8));
        sb.append("&content=").append(URLEncoder.encode(msgStr, UTF8));
        sb.append("&isIncludeSender=1");

        String body = sb.toString();
        if (body.indexOf("&") == 0) {
            body = body.substring(1);
        }

        HttpURLConnection conn = httpHelper
                .createIMPostHttpConnection("/message/chatroom/publish.json", "application/x-www-form-urlencoded");
        httpHelper.setBodyParameter(body, conn);

        return (IMApiResultInfo) GsonUtil.fromJson(httpHelper.returnResult(conn), IMApiResultInfo.class);
    }

    /**
     * 查询用户是否在聊天室
     *
     * @param chatroomId 要查询的聊天室 ID（必传）
     * @param userId     要查询的用户 ID（必传）
     */
    public IMApiResultInfo isInChartRoom(String chatroomId, String userId) throws Exception {
        if (chatroomId == null) {
            throw new BizException("房间Uid不能为空");
        }
        if (userId == null) {
            throw new BizException("用户不能为空");
        }
        String body = "&chatroomId=" + URLEncoder.encode(chatroomId, UTF8) +
                "&userId=" + URLEncoder.encode(userId, UTF8);
        if (body.indexOf("&") == 0) {
            body = body.substring(1);
        }

        HttpURLConnection conn = httpHelper.createIMPostHttpConnection("/chatroom/user/exist.json", "application/x-www-form-urlencoded");
        httpHelper.setBodyParameter(body, conn);

        return (IMApiResultInfo) GsonUtil.fromJson(httpHelper.returnResult(conn), IMApiResultInfo.class);
    }

}
