
using Newtonsoft.Json;
using Mall.Common.Models;
using Mall.Common;
using Mall.Common.Enum;
using Mall.IM.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace Mall.IM.Service.Message
{

    /// <summary>
    /// 推送服务
    /// </summary>
    public class PushService : BaseService
    {

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

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

        /// <summary>
        /// XMApp系统消息推送 ACCID
        /// </summary>
        public const String XMApp_PUSH_ACCID = "684cb79fe92f46877777";
        /// <summary>
        /// Web系统消息推送 ACCID
        /// </summary>
        public const String Web_PUSH_ACCID = "684cb79fe92f46888888";

        /// <summary>
        /// 文本普通消息推送模板
        /// </summary>
        public const String TEXT_URL_PUSH_TEMPLETE = "{0}?from={1}&ope=0&to={2}&type=0&body={3}&option={4}&ext={5}&payload={6}";
        /// <summary>
        /// 文本群发普通消息推送模板
        /// </summary>
        public const String TEXT_ARRAY_URL_PUSH_TEMPLETE = "{0}?fromAccid={1}&toAccids={2}&type=0&body={3}&option={4}&ext={5}&payload={6}";

        #endregion

        #region 推送管理

        /// <summary>
        /// 系统推送,自定义内容
        /// </summary>
        /// <param name="to">接收账号</param>
        /// <returns></returns>
        public MessageServiceGroupResult PushMessage(String to, String content)
        {
            MessageServiceGroupResult result = null;
            String messageBody = String.Empty;
            String requestURL = String.Empty;
            messageBody = CreateTextMessageBody(content);
            string optionBody = CreatePushMessageOption();
            requestURL = String.Format(TEXT_URL_PUSH_TEMPLETE, SENDMESSAGE, HttpUtility.UrlEncode(XMApp_PUSH_ACCID), HttpUtility.UrlEncode(to), HttpUtility.UrlEncode(messageBody), HttpUtility.UrlEncode(optionBody));
            var apiResult = ApiRequestUtil.PostResponse<MessageServiceGroupResult>(ServiceAddress, requestURL);
            result = apiResult.Data;

            return result;
        }

        /// <summary>
        /// 系统推送,自定义内容
        /// 人数不能超过500
        /// 此接口受频率控制，一个应用一分钟最多调用120次，超过会返回416状态码，并且被屏蔽一段时间
        /// </summary>
        /// <param name="toAccids">接收账号</param>
        /// <param name="empId">发送人员工id</param>
        /// <param name="content">消息内容</param>
        /// <param name="title">标题</param>
        /// <param name="pushType">推送类型</param>
        /// <param name="pushLogType">推送日志记录类型</param>
        /// <param name="extras">额外信息</param>
        /// <param name="IsRecordLog">是否记录日志</param>
        /// <returns></returns>
        public MessageServiceGroupResult PushMessage(List<EmAccoutIdModel> toAccids, int? empId, String content, string title, SysTemPushTypeEnum pushType, SystemPushLogTypeEnum pushLogType, Dictionary<string, object> extras = null,bool IsRecordLog=true)
        {
            MessageServiceGroupResult result = new MessageServiceGroupResult();
            int pageSize = 450;
            int totalPage = 0;
            if (IsRecordLog)
            {
                Task.Run(() =>
                {
                    SavePushLog(toAccids, empId, content, title, pushType, pushLogType, extras);
                });
            }

            if (toAccids == null || toAccids.Count == 0)
            {
                return null;
            }
            if (toAccids.Count % pageSize == 0)
            {
                totalPage = toAccids.Count / pageSize;
            }
            else
            {
                totalPage = toAccids.Count / pageSize+1;
            }
            if (toAccids.Count > pageSize)
            {
                for (int pageIndex = 1; pageIndex <= totalPage; pageIndex++)
                {
                    if (pageIndex > 1)
                    {
                        Thread.Sleep(60 * 1000);//暂停60秒
                    }
                    var tempList = toAccids.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                    if (tempList != null && tempList.Count > 0)
                    {
                        result = TempPush(tempList, empId, content, title, pushType, pushLogType, extras);
                    }
                }
            }
            else
            {
                result = TempPush(toAccids, empId, content, title, pushType, pushLogType, extras);
            }
            return result;
        }

        public MessageServiceGroupResult TempPush(List<EmAccoutIdModel> toAccids, int? empId, String content, string title, SysTemPushTypeEnum pushType, SystemPushLogTypeEnum pushLogType, Dictionary<string, object> extras = null)
        {
            MessageServiceGroupResult result = null;
            String requestURL = String.Empty;
            String to = CreateAccidListBody(toAccids);
            string messageBody = CreateTextMessageBody(content);
            string ext = "";
            if (extras != null)
            {
                ext = JsonConvert.SerializeObject(extras);
            }
            switch (pushLogType)
            {
                case SystemPushLogTypeEnum.XMApp:
                    requestURL = String.Format(TEXT_ARRAY_URL_PUSH_TEMPLETE, SENDMOREMESSAGE, HttpUtility.UrlEncode(XMApp_PUSH_ACCID), HttpUtility.UrlEncode(to), HttpUtility.UrlEncode(messageBody), HttpUtility.UrlEncode(CreatePushMessageOption()), HttpUtility.UrlEncode(ext), HttpUtility.UrlEncode(ext));
                    break;
                case SystemPushLogTypeEnum.Web:
                    requestURL = $"msg/sendBatchMsg.action?fromAccid={HttpUtility.UrlEncode(Web_PUSH_ACCID)}&toAccids={ HttpUtility.UrlEncode(to)}&type=0&body={HttpUtility.UrlEncode(messageBody)}&option={ HttpUtility.UrlEncode(CreateWebPushMessageOption())}&ext={HttpUtility.UrlEncode(ext)}";
                    break;
                case SystemPushLogTypeEnum.OfficialAccount:
                    break;
                case SystemPushLogTypeEnum.Applet:
                    break;
                default:
                    break;
            }
            var apiResult = ApiRequestUtil.PostResponse<MessageServiceGroupResult>(ServiceAddress, requestURL);
            result = apiResult.Data;
            if (result.code == 200)
            {

            }
            return result;
        }
        #endregion

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

        /// <summary>
        /// 创建推送MessageOption内容的JSON消息体
        /// </summary>
        /// <returns></returns>
        public String CreatePushMessageOption()
        {
            var bodyObject = new { badge = true };
            String body = JsonConvert.SerializeObject(bodyObject);
            return body;
        }

        /// <summary>
        /// 创建Web推送MessageOption内容的JSON消息体
        /// </summary>
        /// <returns></returns>
        public String CreateWebPushMessageOption()
        {
            var bodyObject = new { push = false };
            String body = JsonConvert.SerializeObject(bodyObject);
            return body;
        }

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

        /// <summary>
        /// 创建用户数组
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        private String CreateAccidListBody(List<EmAccoutIdModel> account)
        {
            List<string> accidList = new List<string>();
            if (account != null && account.Any())
            {
                foreach (var item in account)
                {
                    accidList.Add(item.EmAccount);
                }
            }
            var body = JsonConvert.SerializeObject(accidList);
            return body;
        }
        #endregion

        #region 数据持久化
        /// <summary>
        /// 保存推送记录
        /// </summary>
        /// <param name="account"></param>
        /// <param name="empId"></param>
        /// <param name="content"></param>
        /// <param name="title"></param>
        /// <param name="type">推送类型</param>
        /// <param name="pushLogType">记录日志类型</param>
        /// <param name="extras"></param>
        public static void SavePushLog(List<EmAccoutIdModel> accountList, int? empId, string content, string title, SysTemPushTypeEnum pushType, SystemPushLogTypeEnum pushLogType, Dictionary<string, object> extras = null)
        {
            try
            {
                // empId = empId.HasValue ? empId.Value : 0;
                //UserInfo userInfo = UserReidsCache.GetUserLoginInfo(empId.ToString());
                
                //string url = extras == null ? "" : extras["jumpUrl"].ToString();
                //foreach (EmAccoutIdModel item in accountList)
                //{
                //    RB_System_Push_Log spmodel = new RB_System_Push_Log()
                //    {
                //        Content = content,
                //        CreateBy = empId,
                //        CreateTime = DateTime.Now,
                //        IsRead = 0,
                //        IsSys = 1,
                //        Link = url,
                //        Recipient = item.EmployeeId,
                //        RecPlatform = pushLogType,
                //        Title = title,
                //        RB_Branch_id = userInfo != null ? userInfo.RB_Branch_id : 0,
                //        RB_Group_id = userInfo != null ? userInfo.RB_Group_id : 0,
                //        Type = pushType,
                //        ShowShortcut = 1
                //    };
                //    int LId = new RB_System_Push_LogRepository().Insert(spmodel);
                //    List<string> AccountList = new List<string>() { item.EmAccount };
                //    var audience = new { alias = AccountList.ToArray() };
                //    if (extras != null)
                //    {
                //        extras["jumpUrl"] = url + $"&SysLogId={LId}";
                //    }
                //}
            }
            catch (System.Exception ex)
            {
                IM.Util.LogHelper.Write(ex, "SavePushLogIM推送记录日志失败");
            }
        }
        #endregion
    }
}
