
using Newtonsoft.Json;
using Mall.Common.Enum;
using Mall.IM.Service.Message.ResultModel;
using Mall.IM.Service.Model;
using Mall.IM.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Mall.IM.Service.Message
{

    /// <summary>
    /// 消息服务服务
    /// </summary>
    public class MessageService : BaseService
    {

        #region 请求消息配置
        /// <summary>
        /// 普通点对点消息
        /// </summary>
        private const String SENDMESSAGE = "msg/sendMsg.action";

        /// <summary>
        /// 批量普通点对点消息
        /// </summary>
        private const String SENDMOREMESSAGE = "msg/sendBatchMsg.action";


        /// <summary>
        /// 系统消息通知 ACCID
        /// </summary>
        private const String NOTICE_ACCID = "684cb79fe92f4687b4e3";

        /// <summary>
        /// 系统通知消息
        /// </summary>
        private const String NOTICE_CONTENT = "你有新的通知";

        /// <summary>
        /// 文本普通消息模板
        /// </summary>
        private const String TEXT_URL_TEMPLETE = "{0}?from={1}&ope=0&to={2}&type=0&body={3}";
        /// <summary>
        /// 文本群发普通消息模板
        /// </summary>
        private const String TEXT_ARRAY_URL_TEMPLETE = "{0}?fromAccid={1}&toAccids={2}&type=0&body={3}";


        #endregion

        #region 消息管理
        /// <summary>
        /// 发送系统消息
        /// </summary>
        /// <param name="sysMessageType">发送消息类型</param>
        /// <param name="to">接收用户</param>
        /// <returns></returns>
        public Result SendSysMessage(SysMessageType sysMessageType, String to)
        {
            Result result = null;
            String messageBody = String.Empty;
            String requestURL = String.Empty;
            switch (sysMessageType)
            {
                case SysMessageType.NOTICE:
                    messageBody = CreateTextMessageBody(NOTICE_CONTENT);
                    requestURL = String.Format(TEXT_URL_TEMPLETE, SENDMESSAGE, HttpUtility.UrlEncode(NOTICE_ACCID), HttpUtility.UrlEncode(to), HttpUtility.UrlEncode(messageBody));
                    break;
            }
            var apiResult = ApiRequestUtil.PostResponse<Result>(ServiceAddress, requestURL);
            result = apiResult.Data;
            return result;
        }
        /// <summary>
        /// 批量发送系统消息
        /// 人数不能超过500
        /// 此接口受频率控制，一个应用一分钟最多调用120次，超过会返回416状态码，并且被屏蔽一段时间
        /// </summary>
        /// <param name="sysMessageType">系统消息类型</param>
        /// <param name="toAccids">接收消息用户</param>
        /// <returns></returns>
        public MessageServiceGroupResult SendSysMessage(SysMessageType sysMessageType, List<String> toAccids)
        {
            if (toAccids == null || toAccids.Count == 0 || toAccids.Count > 500)
                return null;
            MessageServiceGroupResult result = null;
            String messageBody = String.Empty;
            String requestURL = String.Empty;
            String to = CreateAccidListBody(toAccids);
            switch (sysMessageType)
            {
                case SysMessageType.NOTICE:
                    messageBody = CreateTextMessageBody(NOTICE_CONTENT);
                    requestURL = String.Format(TEXT_ARRAY_URL_TEMPLETE, SENDMOREMESSAGE, HttpUtility.UrlEncode(NOTICE_ACCID), HttpUtility.UrlEncode(to), HttpUtility.UrlEncode(messageBody));
                    break;
            }
            var apiResult = ApiRequestUtil.PostResponse<MessageServiceGroupResult>(ServiceAddress, requestURL);
            result = apiResult.Data;
            return result;
        }
        /// <summary>
        /// 发送标准消息
        /// </summary>
        /// <param name="from">发送账号</param>
        /// <param name="to">接收账号</param>
        /// <param name="content">内容</param>
        /// <returns></returns>
        public MessageServiceGroupResult SendMessage(String from, String to, String content)
        {
            MessageServiceGroupResult result = null;
            String messageBody = String.Empty;
            String requestURL = String.Empty;
            messageBody = CreateTextMessageBody(content);
            requestURL = String.Format(TEXT_URL_TEMPLETE, SENDMESSAGE, HttpUtility.UrlEncode(from), HttpUtility.UrlEncode(to), HttpUtility.UrlEncode(messageBody));
            var apiResult = ApiRequestUtil.PostResponse<MessageServiceGroupResult>(ServiceAddress, requestURL);
            result = apiResult.Data;
            return result;
        }

        /// <summary>
        /// 批量发送系统通知,自定义内容
        /// 人数不能超过500
        /// 此接口受频率控制，一个应用一分钟最多调用120次，超过会返回416状态码，并且被屏蔽一段时间
        /// </summary>
        /// <param name="toAccids">接收账号</param>
        /// <returns></returns>
        public MessageServiceGroupResult SendNoticeMessage(String content, List<String> toAccids)
        {
            if (toAccids == null || toAccids.Count == 0 || toAccids.Count > 500)
                return null;
            MessageServiceGroupResult result = null;
            String messageBody = String.Empty;
            String requestURL = String.Empty;
            String to = CreateAccidListBody(toAccids);
            messageBody = CreateTextMessageBody(NOTICE_CONTENT);
            requestURL = String.Format(TEXT_ARRAY_URL_TEMPLETE, SENDMOREMESSAGE, HttpUtility.UrlEncode(NOTICE_ACCID), HttpUtility.UrlEncode(to), HttpUtility.UrlEncode(messageBody));
            var apiResult = ApiRequestUtil.PostResponse<MessageServiceGroupResult>(ServiceAddress, requestURL);
            result = apiResult.Data;

            return result;
        }

        #endregion

        #region 群管里

        /// <summary>
        /// 拉人进群
        /// </summary>
        /// <param name="tid">网易云通信服务器产生，群唯一标识，创建群时会返回，最大长度128字符</param>
        /// <param name="owner">群主用户帐号，最大长度32字符</param>
        /// <param name="members">	["aaa","bbb"](JSONArray对应的accid，如果解析出错会报414)，一次最多拉200个成员</param>
        /// <param name="magree">管理后台建群时，0不需要被邀请人同意加入群，1需要被邀请人同意才可以加入群。其它会返回414</param>
        /// <param name="msg">邀请发送的文字，最大长度150字符</param>
        /// <returns></returns>
        public TeamAddResult TeamAdd(string tid, string owner, List<String> members, int magree, string msg)
        {
            TeamAddResult result = null;
            String messageBody = String.Empty;
            String requestURL = String.Empty;
            String to = CreateAccidListBody(members);
            requestURL = $"team/add.action?tid={HttpUtility.UrlEncode(tid)}&owner={HttpUtility.UrlEncode(owner)}&members={HttpUtility.UrlEncode(to)}&msg={HttpUtility.UrlEncode(msg)}&magree={magree}";
            var apiResult = ApiRequestUtil.PostResponse<TeamAddResult>(ServiceAddress, requestURL);
            result = apiResult.Data;
            return result;
        }

        /// <summary>
        /// 更新群At信息
        /// </summary>
        /// <param name="tid">群聊ID</param>
        /// <param name="ats">ats内容集合</param>
        /// <returns></returns>
        public Result TeamUpdateAts(string tid, string ats)
        {
            Result result = null;
            String requestURL = String.Empty;
            requestURL = $"team/update.action?tid={HttpUtility.UrlEncode(tid)}&tname=mygroup";
            var apiResult = ApiRequestUtil.PostResponse<TeamAddResult>(ServiceAddress, requestURL);
            result = apiResult.Data;
            return result;
        }

        /// <summary>
        /// 创建群进群
        /// </summary>
        /// <param name="tname">群名称，最大长度64字符</param>
        /// <param name="owner">群主用户帐号，最大长度32字符</param>
        /// <param name="members">	["aaa","bbb"](JSONArray对应的accid，如果解析出错会报414)，一次最多拉200个成员</param>
        /// <param name="msg">邀请发送的文字，最大长度150字符</param>
        /// <param name="magree">管理后台建群时，0不需要被邀请人同意加入群，1需要被邀请人同意才可以加入群。其它会返回414</param>
        /// <param name="joinmode">群建好后，sdk操作时，0不用验证，1需要验证,2不允许任何人加入。其它返回414</param>
        /// <param name="invitemode">谁可以邀请他人入群，0-管理员(默认),1-所有人。其它返回414</param>
        /// <returns></returns>
        public TeamAddResult TeamCreate(string tname, string owner, List<String> members, string msg, int magree, int joinmode, int invitemode)
        {
            TeamAddResult result = null;
            String requestURL = String.Empty;
            String mb = CreateAccidListBody(members);
            requestURL = $"team/create.action?tname={HttpUtility.UrlEncode(tname)}&owner={HttpUtility.UrlEncode(owner)}&members={HttpUtility.UrlEncode(mb)}&msg={HttpUtility.UrlEncode(msg)}&magree={magree}&joinmode={joinmode}&beinvitemode=1&invitemode=1&invitemode={invitemode}";
            var apiResult = ApiRequestUtil.PostResponse<TeamAddResult>(ServiceAddress, requestURL);
            result = apiResult.Data;
            return result;
        }

        /// <summary>
        /// 踢人出群
        /// </summary>
        /// <param name="tid">网易云通信服务器产生，群唯一标识，创建群时会返回，最大长度128字符</param>
        /// <param name="owner">群主用户帐号，最大长度32字符</param>
        /// <param name="members">	["aaa","bbb"](JSONArray对应的accid，如果解析出错会报414)，一次最多踢拉200个成员</param>
        /// <returns></returns>
        public TeamAddResult TeamKick(string tid, string owner, List<String> members)
        {
            TeamAddResult result = null;
            String requestURL = String.Empty;
            String mb = CreateAccidListBody(members);
            requestURL = $"team/kick.action?tid={HttpUtility.UrlEncode(tid)}&owner={HttpUtility.UrlEncode(owner)}&members={HttpUtility.UrlEncode(mb)}";
            var apiResult = ApiRequestUtil.PostResponse<TeamAddResult>(ServiceAddress, requestURL);
            result = apiResult.Data;
            return result;
        }

        /// <summary>
        /// 修改群信息
        /// </summary>
        /// <param name="tid">网易云通信服务器产生，群唯一标识，创建群时会返回，最大长度128字符</param>
        /// <param name="owner">群主用户帐号，最大长度32字符</param>
        /// <param name="tname">	群名称，最大长度64字符</param>
        /// <returns></returns>
        public TeamAddResult TeamUpdate(string tid, string owner, string tname)
        {
            TeamAddResult result = null;
            String requestURL = String.Empty;
            requestURL = $"team/update.action?tid={HttpUtility.UrlEncode(tid)}&owner={HttpUtility.UrlEncode(owner)}&tname={HttpUtility.UrlEncode(tname)}";
            var apiResult = ApiRequestUtil.PostResponse<TeamAddResult>(ServiceAddress, requestURL);
            result = apiResult.Data;
            return result;
        }

        /// <summary>
        /// 解散群
        /// </summary>
        /// <param name="tid">网易云通信服务器产生，群唯一标识，创建群时会返回，最大长度128字符</param>
        /// <param name="owner">群主用户帐号，最大长度32字符</param>
        /// <returns></returns>
        public TeamAddResult TeamRemove(string tid, string owner)
        {
            TeamAddResult result = null;
            String requestURL = String.Empty;
            requestURL = $"team/remove.action?tid={HttpUtility.UrlEncode(tid)}&owner={HttpUtility.UrlEncode(owner)}";
            var apiResult = ApiRequestUtil.PostResponse<TeamAddResult>(ServiceAddress, requestURL);
            result = apiResult.Data;
            return result;
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 创建文本内容的JSON消息体
        /// </summary>
        /// <returns></returns>
        private String CreateTextMessageBody(String content)
        {
            var bodyObject = new { msg = content };
            String body = JsonConvert.SerializeObject(bodyObject);
            return body;
        }


        /// <summary>
        /// 创建用户数组
        /// </summary>
        /// <param name="accids"></param>
        /// <returns></returns>
        private String CreateAccidListBody(List<String> accids)
        {
            var body = JsonConvert.SerializeObject(accids);
            return body;
        }
        #endregion
    }
}
