using APT.Infrastructure.Core;
using APT.BaseData.Domain.ApiModel;
using APT.BaseData.Domain.Entities.FM;
using APT.BaseData.Domain.IServices.FM;
using APT.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Immutable;
using APT.BaseData.Domain.Entities;
using APT.BaseData.Domain.Enums;
using APT.Infrastructure.Api;
using APT.MS.Domain.Entities.PF;
using APT.BaseData.Domain.Dtos;
using Castle.Core.Internal;
using APT.MS.Domain.Entities.SC;
using TencentCloud.Sms.V20210111.Models;

namespace APT.BaseData.Services.Services.FM
{
    public partial class FMNoticeService : CommonService, IFMNoticeService
    {

        public FMNoticeService(IRepository repository) : base(repository)
        {
        }

        /// <summary>
        /// 发送短信
        /// </summary>
        /// <param name="noticeType">现在只支持会议</param>
        /// <param name="DATA_ID"></param>
        public void SendMsg(NOTICETYPE noticeType, Guid? DATA_ID, Guid? KEY = null, T_FM_SYNC_TASK task = null)
        {
            var mtConfig = GetEntity<T_SC_MT_CONFIG>(e => e.IS_SENDMSG);
            if (mtConfig == null)
            {
                return;
            }

            Expression<Func<T_FM_NOTICE, bool>> expression = e => e.NOTICE_STATUS == FMNoticeStatus.等待发送;
            //if (noticeType != null && noticeType.HasValue)
            //{
            //    expression = expression.And(e => e.NOTICETYPE == noticeType.Value);
            //}
            expression = expression.And(e => e.NOTICETYPE == noticeType);
            if (DATA_ID != null && DATA_ID.HasValue)
            {
                expression = expression.And(e => e.DATA_ID == DATA_ID.Value);
            }
            if (KEY != null && KEY.HasValue)
            {
                expression = expression.And(e => e.KEY == KEY.Value);
            }

            var listNoticeSend = GetEntities(expression);//&&e.NOTICETYPE==NOTICETYPE.Meeting 以后放开此限制
            if (listNoticeSend == null || !listNoticeSend.Any())
                return;
            //数据完善
            //    如果没有手机号码 修改为发送失败  
            //短信发送
            //    发送次数 ++
            //    发送成功修改状态
            //    如果发送失败 判断次数  如果第三次（最后一次） 修改为 发送失败 记录失败原因

            #region      判断 手机号码 补齐  公用

            var noTEL = listNoticeSend.Where(e => e.TEL == null || e.TEL.Length < 1);
            T_FM_USER FMCheck = null;
            if (noTEL != null && noTEL.Any())
            {
                var listUserID = noTEL.Where(e => e.USER_ID.HasValue).Select(e => e.USER_ID);
                if (listUserID != null && listUserID.Any())
                {
                    var users = GetEntities<T_FM_USER>(e => listUserID.Contains(e.ID));
                    foreach (var item in listNoticeSend)
                    {
                        if (string.IsNullOrEmpty(item.TEL))
                        {
                            FMCheck = users.FirstOrDefault(e => e.ID == item.USER_ID);
                            if (FMCheck == null)
                            {
                                item.ERRORMSG = "获取人员信息失败";
                                item.NOTICE_STATUS = FMNoticeStatus.发送失败;
                            }
                            else if (string.IsNullOrEmpty(FMCheck.PHONE))
                            {
                                item.ERRORMSG = "缺少手机号码";
                                item.NOTICE_STATUS = FMNoticeStatus.发送失败;
                            }
                            else if (FMCheck.ENABLE_STATUS == 1)
                            {
                                item.ERRORMSG = "该用户已停用";
                                item.NOTICE_STATUS = FMNoticeStatus.发送失败;
                            }
                            else
                            {
                                item.TEL = FMCheck.PHONE;
                            }
                        }
                    }
                }
            }

            #endregion

            #region 结束时间小于当前时间, 就不发送了 
            DateTime dtNow = DateTime.Now;
            foreach (var item in listNoticeSend)
            {
                if (item.ENDDT.HasValue && item.ENDDT < dtNow)
                {
                    item.ERRORMSG = "结束时间小于当前时间不发送";
                    item.NOTICE_STATUS = FMNoticeStatus.发送失败;
                }
            }
            #endregion


            #region 验证手机号码
            foreach (var item in listNoticeSend)
            {
                if (item.NOTICE_STATUS == FMNoticeStatus.等待发送 && item.TEL.Length < 11)
                {
                    item.ERRORMSG = "手机号码错误";
                    item.NOTICE_STATUS = FMNoticeStatus.发送失败;
                }
            }
            #endregion


            #region     短信发送
            List<string> listPhone = new List<string>();
            List<string> listTemplateParams = new List<string>();

            //var listDataID = listNoticeSend.Select(e => e.DATA_ID).Distinct();
            var lisKEY = listNoticeSend.Select(e => e.KEY).Distinct();

            TencentSendSMS tencentSendSMS = new TencentSendSMS();
            string[] phoneNumbers = null;
            List<string> templates = null;
            string TEMPLATE_ID = string.Empty;//短信模板

            bool isSend = false;//是否发送成功
            foreach (var item in lisKEY)
            {
                var listTemp = listNoticeSend.Where(e => e.KEY == item && e.NOTICE_STATUS == FMNoticeStatus.等待发送);
                phoneNumbers = listTemp.Select(e => e.TEL).ToArray();
                switch (noticeType)
                {
                    case NOTICETYPE.Meeting:
                        //2个参数
                        foreach (var itemS in listTemp)
                        {
                            if (templates == null)
                            {
                                templates = new List<string>();
                                TEMPLATE_ID = itemS.TEMPLATE_ID;
                                templates.Add(itemS.TITLE);
                                templates.Add(itemS.ENDDT.Value.ToString("yyyy-MM-dd HH:mm"));
                                break;
                            }
                        }
                        break;
                    case NOTICETYPE.MeetingJD:
                        //2个参数
                        foreach (var itemS in listTemp)
                        {
                            if (templates == null)
                            {
                                templates = new List<string>();

                                TEMPLATE_ID = itemS.TEMPLATE_ID;
                                templates.AddRange(GetSplit(itemS.TITLE.Split('[')[0]));
                                templates.Add(itemS.ENDDT.Value.Year.ToString());
                                templates.Add(itemS.ENDDT.Value.Month.ToString("00"));
                                templates.Add(itemS.ENDDT.Value.Day.ToString("00"));
                                templates.Add(itemS.ENDDT.Value.Hour.ToString("00"));
                                templates.Add(itemS.ENDDT.Value.Minute.ToString("00"));
                                templates.Add(itemS.ENDDT.Value.Second.ToString("00"));
                                break;
                            }
                        }
                        break;
                    default:
                        break;
                }

                if (string.IsNullOrEmpty(TEMPLATE_ID) || phoneNumbers.Length < 1 || !templates.Any())
                {
                    continue;
                }

                try
                {
                    SendSmsResponse result = null;
                    if (noticeType == NOTICETYPE.Meeting)
                    {
                        result = tencentSendSMS.sendSMS(TEMPLATE_ID, phoneNumbers, templates.ToArray());
                    }
                    else if (noticeType == NOTICETYPE.MeetingJD)
                    {
                        //result = tencentSendSMS.sendSMSDCJD(TEMPLATE_ID, phoneNumbers, templates.ToArray());
                    }
                    if (result != null)
                    {
                        foreach (var itemResult in result.SendStatusSet)
                        {
                            foreach (var itemRN in listNoticeSend)
                            {
                                if (itemRN.KEY == item && itemRN.NOTICE_STATUS == FMNoticeStatus.等待发送 && itemResult.PhoneNumber.EndsWith(itemRN.TEL))
                                {
                                    itemRN.TRYCOUNT++;
                                    if (itemResult.Code == "Ok")
                                    {
                                        isSend = true;
                                        itemRN.NOTICE_STATUS = FMNoticeStatus.发送成功;
                                    }
                                    else if (itemRN.TRYCOUNT == 3)
                                    {
                                        //3次发送失败 记录信息
                                        itemRN.NOTICE_STATUS = FMNoticeStatus.发送失败;
                                        itemRN.ERRORMSG = itemResult.Message;
                                        if (itemRN.ERRORMSG != null && itemRN.ERRORMSG.Length > 100)
                                        {
                                            itemRN.ERRORMSG = itemRN.ERRORMSG.Substring(0, 95);
                                        }
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
                catch
                {
                    //发送信息报错 例：腾讯云 服务器挂了
                }
            }

            #endregion

            #region    信息保存
            if (isSend)
            {
                UnifiedCommit(() =>
                {
                    BantchSaveEntityNoCommit(listNoticeSend);//BantchUpdateEntityNoCommit(listNoticeSend); 得升级 不然报错
                    if (task != null)
                    {
                        UpdateEntityNoCommit(task);
                    }
                });
            }
            else
            {
                var listChange = listNoticeSend.Where(e => e.NOTICE_STATUS == FMNoticeStatus.发送失败);
                if (listChange != null && listChange.Any())
                {
                    foreach (var item in listChange)
                    {
                        item.TRYCOUNT++;
                    }
                    BantchSaveEntityNoCommit(listChange); //BantchUpdateEntityNoCommit(listChange);
                    if (task != null)
                    {
                        UpdateEntityNoCommit(task);
                    }
                }
            }

            #endregion
        }

        /// <summary>
        /// 获取会议模板ID
        /// </summary>
        /// <param name="ORG_ID"></param>
        /// <returns></returns>
        public string GetTEMPLATE_ID(Guid ORG_ID)
        {
            if (ORG_ID == new Guid("B043B28B-BBC3-C452-6052-4FBA1457ABFA"))
            {
                return NOTICETYPE.Meeting.GetDescription();
            }
            else if (ORG_ID == new Guid("8B3C41AA-51B1-7CE9-1879-248A038C1B5C"))
            {
                return NOTICETYPE.MeetingJD.GetDescription();
            }

            return "";
        }

        /// <summary>
        /// 文本分块(发送信息时用)
        /// </summary>
        /// <param name="title"></param>
        /// <param name="piece"></param>
        /// <param name="splitMax"></param>
        /// <returns></returns>
        private List<string> GetSplit(string title, int piece = 3, int splitMax = 6)
        {
            int titleLength = title.Length;
            List<string> listResult = new List<string>();
            if (titleLength == piece)
            {
                //每个字一份
                for (int i = 0; i < piece; i++)
                {
                    listResult.Add(title.Substring(i, 1));
                }

            }
            else if (titleLength >= splitMax * piece)
            {
                //按最长给 多的也不给
                for (int i = 0; i < piece; i++)
                {
                    listResult.Add(title.Substring(i * splitMax, splitMax));
                }
            }
            else
            {
                int remain = titleLength % piece;
                int Per = titleLength / piece;

                //分割长度
                List<int> listLength = new List<int>();
                if (remain == 0)
                {
                    for (int i = 0; i < piece; i++)
                        listLength.Add(Per);
                }
                else
                {
                    for (int i = 0; i < piece; i++)
                    {
                        remain--;
                        if (remain < 0)
                            listLength.Add(Per);
                        else
                            listLength.Add(Per + 1);
                    }
                }

                for (int i = 0; i < piece; i++)
                {
                    listResult.Add(title.Substring(0, listLength[i]));
                    title = title.Substring(listLength[i]);
                }
            }
            return listResult;

        }
    }
}
