using Edu.Common;
using Edu.Common.Enum;
using Edu.Common.Plugin;
using Edu.Model.CacheModel;
using Edu.Model.Entity.Grade;
using Edu.Model.ViewModel.Course;
using Edu.Model.ViewModel.Grade;
using Edu.Model.ViewModel.Scroll;
using Edu.Repository.Course;
using Edu.Repository.Grade;
using Edu.Repository.Reserve;
using Edu.Repository.Scroll;
using Edu.Repository.User;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using VT.FW.DB;

namespace Edu.Module.Course
{
    /// <summary>
    /// 滚动开班处理类
    /// </summary>
    public class ScrollClassCommonModule
    {
        /// <summary>
        /// 班级仓储层对象
        /// </summary>
        private readonly RB_ClassRepository classRepository = new RB_ClassRepository();
        /// <summary>
        /// 课程仓储层对象
        /// </summary>
        private readonly RB_CourseRepository courseRepository = new RB_CourseRepository();
        /// <summary>
        /// 字典
        /// </summary>
        private readonly Rb_dictvalueRepository dictvalueRepository = new Rb_dictvalueRepository();
        /// <summary>
        /// 预约课
        /// </summary>
        private readonly RB_Scroll_AppointmentRepository scroll_AppointmentRepository = new RB_Scroll_AppointmentRepository();
        /// <summary>
        /// 上课时段
        /// </summary>
        private readonly RB_Scroll_CourseTimeRepository scroll_CourseTimeRepository = new RB_Scroll_CourseTimeRepository();
        /// <summary>
        /// 班级计划
        /// </summary>
        private readonly RB_Class_PlanRepository class_PlanRepository = new RB_Class_PlanRepository();
        /// <summary>
        /// 班级
        /// </summary>
        private readonly RB_Class_TimeRepository class_TimeRepository = new RB_Class_TimeRepository();


        #region 滚动开班

        /// <summary>
        /// 创建当月开班数据
        /// </summary>
        public void CreateScrollClass(string courseId,int groupId = 100000)
        {
            string time = DateTime.Now.ToString("yyyy-MM");
            DateTime EndOrderTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM") + "-01 23:59:59").AddMonths(1).AddDays(-1);
            string OpenTime = DateTime.Now.ToString("yyyyMM") + "01";
            int month = DateTime.Now.Month;
            var clist = courseRepository.GetCourseListRepository(new RB_Course_ViewModel() { Group_Id = groupId, IsScrollClass = 1, QCourseIds = courseId });
            //每个课程当月都会生成一个开班数据
            foreach (var item in clist) {
                //验证当月是否已创建班级数据
                if (classRepository.GetClassListRepository(new RB_Class_ViewModel() { Group_Id = groupId, CouseId = item.CourseId, ClassScrollType = 2 }).Any()) {
                    continue;
                }
                #region 生成班级号
                string ClassNo = "GDKB";int ClassLetterNum = 0;
                ////查询最大的字母
                //int CNum = classRepository.GetMaxClassNoPrefix(time + "-01");
                //if (CNum == 0)
                //{
                //    ClassNo += OpenTime + "A";
                //    ClassLetterNum = 1;
                //}
                //else
                //{
                //    string ClassNoLetterStr = Edu.Common.Config.ClassNoLetterStr;
                //    ClassNo += OpenTime + GetClassNo(ClassNoLetterStr, CNum);
                //    ClassLetterNum = CNum + 1;
                //}
                #endregion
                RB_Class cmodel = new RB_Class()
                {
                    ClassId = 0,
                    ClassName = month + "月" + item.CourseName + "班",
                    CouseId = item.CourseId,
                    Teacher_Id = 0,
                    Assist_Id = 0,
                    Group_Id = groupId,
                    School_Id = 0,
                    CreateBy = 0,
                    UpdateBy = 0,
                    Status = 0,
                    ClassPersion = 9999,
                    OpenTime = Convert.ToDateTime(time + "-01"),
                    EndOrderTime = EndOrderTime,
                    OriginalPrice = 0,
                    SellPrice = 0,
                    IsStepPrice = 0,
                    ClassRoomId = 0,
                    IsOpenCommission = 0,
                    CommissionType = 0,
                    CommissionValue = 0,
                    ClassHours = (int)item.ClassHours,
                    ClassStyle = 0,
                    ClassStatus = Common.Enum.Course.ClassStatusEnum.NonOpenClass,
                    InnerRemark = "",
                    OutRemark = "",
                    CompleteProgress = 0,
                    ClassType = 0,
                    DefaultTimeJson = "",
                    DateJson = "",
                    EndClassDate = EndOrderTime,
                    IsDeduction = 0,
                    IsSubscribe = 0,
                    Point = 0,
                    CourseClassType = 0,
                    StudentNumType = 0,
                    ClassHourMinute = 0,
                    ClassNo = ClassNo,
                    ClassLetterNum = ClassLetterNum,
                    ClassScrollType = 2,
                    ScrollMonth = time
                };
                classRepository.Insert(cmodel);
            }

            if (string.IsNullOrEmpty(courseId))
            {
                //清除上个月 没有订单的班级
                classRepository.SetLastMonthNotOrderClassDel(groupId);
            }
        }

        /// <summary>
        /// 获取班号
        /// </summary>
        /// <param name="classNoLetterStr"></param>
        /// <param name="cNum"></param>
        /// <returns></returns>
        private string GetClassNo(string classNoLetterStr, int cNum)
        {
            string classNo = "";
            int i = (cNum + 1) / 52;
            if (i > 0)
            {
                for (var l = 0; l < i; l++)
                {
                    classNo += "z";
                }
            }
            int y = (cNum + 1) % 52;
            if (y > 0)
            {
                classNo += classNoLetterStr.Substring(y - 1, 1);
            }
            return classNo;
        }

        #endregion

        #region 预约课程

        /// <summary>
        /// 预约课程
        /// </summary>
        public bool CreateScrollAppointment(int groupId = 100000) {
            //提前时间
            string Scroll_Time = dictvalueRepository.GetList(new Model.ViewModel.User.RB_Dictvalue_Extend() { RB_Group_id = groupId, DictKey = "Scroll_Time" }).FirstOrDefault()?.Content ?? "00:00";

            //按照设置的时间来判定
            if (DateTime.Now.Hour == Convert.ToDateTime("2022-01-25 " + Scroll_Time).Hour)
            {
                //提前几天
                int AdvanceDay = Convert.ToInt32(dictvalueRepository.GetList(new Model.ViewModel.User.RB_Dictvalue_Extend() { RB_Group_id = groupId, DictKey = "Scroll_AdvanceDay" }).FirstOrDefault()?.Content ?? "1");
                //看提前几天  这个日期之前的（包含此日期） 都算
                string SelectDate = DateTime.Now.AddDays(DateTime.Now.Hour == 0 ? AdvanceDay - 1 : AdvanceDay).ToString("yyyy-MM-dd");
                var AppointList = scroll_AppointmentRepository.GetAppointList(new RB_Scroll_Appointment_ViewModel() { Group_Id = groupId, State= Common.Enum.Course.CourseAppointStateEnum.WaitSure, EntTime = SelectDate });

                if (AppointList.Any())
                {
                    //获取上课时段
                    string ctIds = string.Join(",", AppointList.Select(x => x.CourseTimeId).Distinct());
                    var CTList = scroll_CourseTimeRepository.GetList(new RB_Scroll_CourseTime_ViewModel() { Group_Id = groupId, CourseTimeIds = ctIds });
                    foreach (var item in CTList)
                    {
                        item.TimeList = new List<CourseTimeModel>();
                        if (!string.IsNullOrEmpty(item.Content))
                        {
                            item.TimeList = JsonHelper.DeserializeObject<List<CourseTimeModel>>(item.Content);
                        }
                    }

                    #region 获取token 推送订阅消息

                    string Appid = Config.JiaXiaoHeAppId;
                    var Secret = Config.JiaXiaoHeAppSecret;
                    string token = WeChatHelper.GetAccessToken(Appid, Secret);
                    if (string.IsNullOrEmpty(token))
                    {
                        return false;
                    }

                    #endregion

                    //以老师为单位 遍历
                    AppointList.GroupBy(x => new { x.Date, x.AccountId, x.WorkUserId,x.TeacherId, x.TeacherName, x.CourseId, x.CourseName, x.ChapterNo, x.ShiftSort, x.CourseTimeId, x.RoomId, x.RoomName, x.RoomSchoolName, x.ScrollMinNum }).ToList().ForEach(item =>
                    {
                        var ctModel = CTList.Where(x => x.Id == item.Key.CourseTimeId).FirstOrDefault();
                        var CourseTimeList = ctModel.TimeList.Where(x => ("," + item.Key.ShiftSort + ",").Contains("," + x.Sort + ",")).ToList();
                        string CourseTime = CourseTimeList.Min(x => x.StartTime) + "~" + CourseTimeList.Max(x => x.EndTime);
                        string StartTime = item.Key.Date.ToString("yyyy-MM-dd") + " " + CourseTimeList.Min(x => x.StartTime);
                        //开始验证学生的数量是否达标
                        if (item.Count() < item.Key.ScrollMinNum)
                        {
                            //人数未达标 取消课程
                            foreach (var qitem in item)
                            {
                                Dictionary<string, object> keyValues = new Dictionary<string, object>() {
                                    { nameof(RB_Scroll_Appointment_ViewModel.State), Common.Enum.Course.CourseAppointStateEnum.Cancel}
                                };
                                List<WhereHelper> wheres = new List<WhereHelper>() {
                                    new WhereHelper(){
                                         FiledName = nameof(RB_Scroll_Appointment_ViewModel.Id),
                                          FiledValue = qitem.Id,
                                           OperatorEnum =OperatorEnum.Equal
                                    }
                                };
                                bool flag = scroll_AppointmentRepository.Update(keyValues, wheres);
                                if (flag)
                                {
                                    //给学生推送 取消课程的订阅消息
                                    SendAppointmentCancelMsg(token, qitem.StuOpenId, qitem, StartTime);
                                }
                            }

                            //给老师推送取消课程 信息
                            if (!string.IsNullOrEmpty(item.Key.WorkUserId))
                            {
                                var recipientPath = HttpUtility.UrlEncode($"/teacher/myPrepareLessons?d=");//地址需要后台功能做了之后吧
                                var content = $@"<font color='info'>课程取消通知</font>\n>**概要信息** \n>
上课日期：<font color='warning'>{item.Key.Date.ToString("yyyy-MM-dd")}</font>\n>
上课时段：<font color='warning'>{CourseTime}</font>\n>
取消原因：<font color='comment'>预约人数未达到最低成班人数 {item.Key.ScrollMinNum}人</font>\n>
请 点 击：[查看详情]({Config.ErpUrl}/autologin?loginId={item.Key.AccountId}&target={recipientPath})";
                                PushWorkChatHelper.PushToWorkChat(content, "LiuDong", "课程取消通知");
                            }
                        }
                        else
                        {
                            #region 写入class_plan 计划表

                            //先查询计划是否已存在

                            int planId = class_PlanRepository.Insert(new RB_Class_Plan()
                            {
                                ClassPlanId = 0,
                                ClassId = 0,
                                ClassDate = item.Key.Date,
                                Status = 0,
                                ClassRoomId = item.Key.RoomId,
                                Group_Id = groupId,
                                School_Id = -1,// 暂时 应该要赋值  订单上的预约校区
                                TeacherId = item.Key.TeacherId,
                                BeiKeStatus = 0,
                                FanKuiStatus = 0,
                                ParentFanKuiStatus = 0,
                                RepeatPlanIds = "",
                                PlanType = 2,
                                CourseId = item.Key.CourseId
                            });
                            if (planId > 0)
                            {
                                //写入时间
                                foreach (var citem in CourseTimeList)
                                {
                                    class_TimeRepository.Insert(new RB_Class_Time()
                                    {
                                        ClassTimeId = 0,
                                        ClassId = 0,
                                        ClassPlanId = planId,
                                        StartTime = citem.StartTime,
                                        EndTime = citem.EndTime,
                                        Group_Id = groupId,
                                        School_Id = 0,//暂时 应该要赋值  订单上的预约校区
                                        ClassStatus = 0,
                                        SuiPai = "",
                                        VideoUrl = "",
                                        TimeHour = citem.ClassHours
                                    });
                                }

                                //人数达标  写入计划课程
                                foreach (var qitem in item)
                                {
                                    Dictionary<string, object> keyValues = new Dictionary<string, object>() {
                                        { nameof(RB_Scroll_Appointment_ViewModel.State), Common.Enum.Course.CourseAppointStateEnum.WaitCourse},
                                        { nameof(RB_Scroll_Appointment_ViewModel.ClassPlanId), planId}
                                    };
                                    List<WhereHelper> wheres = new List<WhereHelper>() {
                                        new WhereHelper(){
                                                FiledName = nameof(RB_Scroll_Appointment_ViewModel.Id),
                                                FiledValue = qitem.Id,
                                                OperatorEnum =OperatorEnum.Equal
                                        }
                                    };
                                    bool flag = scroll_AppointmentRepository.Update(keyValues, wheres);
                                    if (flag)
                                    {
                                        //给学生推送 预约课程的订阅消息
                                        SendAppointmentSusscessMsg(token, qitem.StuOpenId, qitem, StartTime);
                                    }
                                }
                            }
                            #endregion
                            

                            //给老师推送课程 信息
                            if (!string.IsNullOrEmpty(item.Key.WorkUserId))
                            {
                                var recipientPath = HttpUtility.UrlEncode($"/teacher/myPrepareLessons?d=");//地址需要后台功能做了之后吧
                                var content = $@"<font color='info'>课程预约成功通知</font>\n>**概要信息** \n>
上课日期：<font color='warning'>{item.Key.Date.ToString("yyyy-MM-dd")}</font>\n>
上课时段：<font color='warning'>{CourseTime}</font>\n>
上课课程：<font color='warning'>{item.Key.CourseName}(第{item.Key.ChapterNo}次课)</font>\n>
上课教室：<font color='warning'>{item.Key.RoomName}({item.Key.RoomSchoolName})</font>\n>
上课人数：<font color='comment'>{item.Count()}人</font>\n>
请 点 击：[查看详情]({Config.ErpUrl}/autologin?loginId={item.Key.AccountId}&target={recipientPath})";
                                PushWorkChatHelper.PushToWorkChat(content, "LiuDong", "课程预约成功通知");
                            }
                        }

                    });
                }
            }
            return true;
        }


        /// <summary>
        /// 发送订阅消息
        /// </summary>
        /// <param name="token"></param>
        /// <param name="OpenId"></param>
        /// <param name="demodel"></param>
        /// <param name="StartTime"></param>
        /// <returns></returns>
        public bool SendAppointmentSusscessMsg(string token, string OpenId, RB_Scroll_Appointment_ViewModel demodel, string StartTime)
        {
            string wenXinResult = string.Empty;
            if (!string.IsNullOrWhiteSpace(token))
            {
                string Url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token;
                var postdata = new
                {
                    touser = OpenId,
                    template_id = "oAkcEBjei5seEiDBJVZyjJj2MsHHfYPikNkn-kdVEK0",
                    page = "pages/index/index",
                    data = new
                    {
                        thing1 = new
                        {
                            value = demodel.CourseName+ "(第"+ demodel.ChapterNo+"次课)"//课程名称
                        },
                        name3 = new
                        {
                            value = demodel.TeacherName//上课老师
                        },
                        time8 = new
                        {
                            value = StartTime//预约时间
                        },
                        thing10 = new
                        {
                            value = demodel.RoomName+ " ("+ demodel.RoomSchoolName + ")"//上课地点
                        },
                        thing5 = new
                        {
                            value = "约课成功，请准时上课哟~" //温馨提醒
                        }
                    }
                };

                wenXinResult = HttpHelper.HttpPost(Url, JsonHelper.Serialize(postdata), "");
                LogHelper.WriteInfo("SendAppointmentSusscessMsg 预约成功发送订阅消息:" + wenXinResult);
                JObject jo = (JObject)JsonConvert.DeserializeObject(wenXinResult);
                int errcode = Convert.ToInt32(jo["errcode"].ToString());
                if (errcode == 0)
                {
                    //成功
                    return true;
                }
                else
                {
                    LogHelper.Write(string.Format("SendAppointmentSusscessMsg:wenXinResult:{0}", wenXinResult));
                }
            }
            return false;
        }

        /// <summary>
        /// 发送订阅消息
        /// </summary>
        /// <param name="token"></param>
        /// <param name="OpenId"></param>
        /// <param name="demodel"></param>
        /// <param name="StartTime"></param>
        /// <returns></returns>
        public bool SendAppointmentCancelMsg(string token, string OpenId, RB_Scroll_Appointment_ViewModel demodel, string StartTime)
        {
            string wenXinResult = string.Empty;
            if (!string.IsNullOrWhiteSpace(token))
            {
                string Url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token;
                var postdata = new
                {
                    touser = OpenId,
                    template_id = "_iqA9KHffrLRNg_yRQqk7uLQNzJsQIGF7ykXLsFXhlw",
                    page = "pages/index/index",
                    data = new
                    {
                        thing1 = new
                        {
                            value = demodel.CourseName + "(第" + demodel.ChapterNo + "次课)"//课程名称
                        },
                        thing3 = new
                        {
                            value = demodel.TeacherName//上课老师
                        },
                        time2 = new
                        {
                            value = StartTime//预约时间
                        },
                        thing4 = new
                        {
                            value = demodel.RoomName + " (" + demodel.RoomSchoolName + ")"//上课地点
                        },
                        thing7 = new
                        {
                            value = "预约人数未达到最低成班人数" //取消原因
                        }
                    }
                };

                wenXinResult = HttpHelper.HttpPost(Url, JsonHelper.Serialize(postdata), "");
                LogHelper.WriteInfo("SendAppointmentCancelMsg 预约取消发送订阅消息:" + wenXinResult);
                JObject jo = (JObject)JsonConvert.DeserializeObject(wenXinResult);
                int errcode = Convert.ToInt32(jo["errcode"].ToString());
                if (errcode == 0)
                {
                    //成功
                    return true;
                }
                else
                {
                    LogHelper.Write(string.Format("SendAppointmentCancelMsg:wenXinResult:{0}", wenXinResult));
                }
            }
            return false;
        }
        #endregion
    }
}
