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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VT.FW.DB;

namespace Edu.Module.Course
{
    /// <summary>
    /// 滚动开班处理类
    /// </summary>
    public class ScrollClassModule
    {
        /// <summary>
        /// 班级仓储层对象
        /// </summary>
        private readonly RB_ClassRepository classRepository = new RB_ClassRepository();
        /// <summary>
        /// 账户仓储层
        /// </summary>
        private readonly RB_AccountRepository accountRepository = new RB_AccountRepository();
        /// <summary>
        /// 课程仓储层对象
        /// </summary>
        private readonly RB_CourseRepository courseRepository = new RB_CourseRepository();
        /// <summary>
        /// 课程章节
        /// </summary>
        private readonly RB_Course_ChapterRepository course_ChapterRepository = new RB_Course_ChapterRepository();
        /// <summary>
        /// 班次
        /// </summary>
        private readonly RB_Scroll_ShiftRepository scroll_ShiftRepository = new RB_Scroll_ShiftRepository();
        /// <summary>
        /// 排班
        /// </summary>
        private readonly RB_Scroll_PlanRepository scroll_PlanRepository = new RB_Scroll_PlanRepository();
        /// <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_RoomRepository class_RoomRepository = new RB_Class_RoomRepository();
        /// <summary>
        /// 订单关联
        /// </summary>
        private readonly RB_Student_OrderGuestRepository student_OrderGuestRepository = new RB_Student_OrderGuestRepository();
        /// <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();
        /// <summary>
        /// 试听课
        /// </summary>
        private readonly RB_Reserve_ClassRepository reserve_ClassRepository = new RB_Reserve_ClassRepository();
        /// <summary>
        /// 字典
        /// </summary>
        private readonly Rb_dictvalueRepository dictvalueRepository = new Rb_dictvalueRepository();


        #region 班次

        /// <summary>
        /// 获取班次列表
        /// </summary>
        /// <param name="group_Id"></param>
        /// <returns></returns>
        public List<RB_Scroll_Shift_ViewModel> GetScrollShiftList(int group_Id)
        {
            return scroll_ShiftRepository.GetList(new RB_Scroll_Shift_ViewModel() { Group_Id = group_Id });
        }

        /// <summary>
        /// 新增修改
        /// </summary>
        /// <param name="dmodel"></param>
        /// <returns></returns>
        public string SetScrollShift(RB_Scroll_Shift_ViewModel dmodel) {
            if (dmodel.Id > 0)
            {
                Dictionary<string, object> keyValues = new Dictionary<string, object>() {
                    { nameof(RB_Scroll_Shift_ViewModel.Name), dmodel.Name},
                    { nameof(RB_Scroll_Shift_ViewModel.StartTime), dmodel.StartTime},
                    { nameof(RB_Scroll_Shift_ViewModel.EndTime), dmodel.EndTime},
                    { nameof(RB_Scroll_Shift_ViewModel.Color), dmodel.Color},
                    { nameof(RB_Scroll_Shift_ViewModel.UpdateBy), dmodel.UpdateBy},
                    { nameof(RB_Scroll_Shift_ViewModel.UpdateTime), dmodel.UpdateTime},
                };
                List<WhereHelper> wheres = new List<WhereHelper>() {
                    new WhereHelper(){
                         FiledName = nameof(RB_Scroll_Shift_ViewModel.Id),
                          FiledValue = dmodel.Id,
                           OperatorEnum =OperatorEnum.Equal
                    }
                };
                bool flag = scroll_ShiftRepository.Update(keyValues, wheres);
                return flag ? "" : "出错了，请联系管理员";
            }
            else {
                bool flag = scroll_ShiftRepository.Insert(dmodel) > 0;
                return flag ? "" : "出错了，请联系管理员";
            }
        }

        /// <summary>
        /// 删除班次
        /// </summary>
        /// <param name="ShiftId"></param>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public string DelScrollShift(int ShiftId, UserInfo userInfo) {
            Dictionary<string, object> keyValues = new Dictionary<string, object>() {
                { nameof(RB_Scroll_Shift_ViewModel.Status), 1},
                { nameof(RB_Scroll_Shift_ViewModel.UpdateBy), userInfo.Id},
                { nameof(RB_Scroll_Shift_ViewModel.UpdateTime), DateTime.Now},
            };
            List<WhereHelper> wheres = new List<WhereHelper>() {
                new WhereHelper(){
                        FiledName = nameof(RB_Scroll_Shift_ViewModel.Id),
                        FiledValue = ShiftId,
                        OperatorEnum =OperatorEnum.Equal
                }
            };
            bool flag = scroll_ShiftRepository.Update(keyValues, wheres);
            return flag ? "" : "出错了，请联系管理员";
        }
        #endregion

        #region 排班

        /// <summary>
        /// 获取排班计划
        /// </summary>
        /// <param name="demodel"></param>
        /// <returns></returns>
        public object GetScrollPlanMonthList(RB_Scroll_Plan_ViewModel demodel)
        {
            List<object> RList = new List<object>();
            List<object> RList2 = new List<object>();
            //查询所有的老师
            var teacherList = accountRepository.GetAccountListExtRepository(new Model.ViewModel.User.RB_Account_ViewModel() { Group_Id = demodel.Group_Id, AccountType = Common.Enum.User.AccountTypeEnum.Teacher, IsSelectLevelNor = 1 });
            var list = scroll_PlanRepository.GetList(demodel);
            if (list.Any() || teacherList.Any()) {
                //查询班次
                var shiftList = scroll_ShiftRepository.GetList(new RB_Scroll_Shift_ViewModel() { Group_Id = demodel.Group_Id });
                //查询教室
                string roomIds = string.Join(",", list.Select(x => x.RoomId).Distinct());
                var roomList = class_RoomRepository.GetClassRoomList(new RB_Class_Room_ViewModel() { Group_Id = demodel.Group_Id, QRoomIds = roomIds });

                #region 遍历日期
                List<DateTime> DateList = new List<DateTime>();
                DateTime StartDate = Convert.ToDateTime(demodel.STime);
                DateTime EndDate = Convert.ToDateTime(demodel.ETime);
                while (true) {
                    DateList.Add(StartDate);
                    if (StartDate == EndDate) {
                        break;
                    }
                    StartDate = StartDate.AddDays(1);
                }

                #endregion

                #region 老师
                foreach (var item in teacherList) {
                    List<object> RDateList = new List<object>();
                    foreach (var qitem in DateList) {
                        var planModel = list.Where(x => x.AccountId == item.Id && x.Date == qitem).FirstOrDefault();
                        if (planModel != null)
                        {
                            var roomModel = roomList.Where(x => x.RoomId == planModel.RoomId).FirstOrDefault();
                            var shiftModel = shiftList.Where(x => x.Id == planModel.ShiftId).FirstOrDefault();
                            RDateList.Add(new
                            {
                                Date = qitem.ToString("yyyy-MM-dd"),
                                qitem.Day,
                                PlanId = planModel.Id,
                                planModel.RoomId,
                                planModel.ShiftId,
                                RoomName = roomModel?.RoomName ?? "",
                                RoomSchool = roomModel?.SchoolName ?? "",
                                ShiftName = shiftModel?.Name ?? "",
                                Color = shiftModel?.Color ?? "",
                            });
                        }
                        else {
                            //未设定
                            RDateList.Add(new
                            {
                                Date = qitem.ToString("yyyy-MM-dd"),
                                qitem.Day,
                                PlanId = 0,
                                RoomId = 0,
                                ShiftId = -1,
                                RoomName = "",
                                RoomSchool = "",
                                ShiftName = "",
                                Color = ""
                            });
                        }
                    }
                    RList.Add(new
                    {
                        TeacherId = item.Id,
                        TeacherName = item.AccountName,
                        RDateList
                    });
                }
                #endregion

                #region 班次
                foreach (var item in shiftList) {
                    List<object> RDateList = new List<object>();
                    foreach (var qitem in DateList)
                    {
                        int Num = list.Where(x => x.ShiftId == item.Id && x.Date == qitem).Count();
                        RDateList.Add(new
                        {
                            Date = qitem.ToString("yyyy-MM-dd"),
                            qitem.Day,
                            Number = Num
                        });
                    }
                    RList2.Add(new
                    {
                        ShiftId = item.Id,
                        ShiftName = item.Name,
                        RDateList
                    });
                }
                //增加休息
                List<object> RDateList1 = new List<object>();
                foreach (var qitem in DateList)
                {
                    int Num = list.Where(x => x.ShiftId == 0 && x.Date == qitem).Count();
                    RDateList1.Add(new
                    {
                        Date = qitem.ToString("yyyy-MM-dd"),
                        qitem.Day,
                        Number = Num
                    });
                }
                RList2.Add(new
                {
                    ShiftId = 0,
                    ShiftName = "休息",
                    RDateList1
                });
                #endregion
            }
            return new { 
                TeacherList = RList,
                ShiftList = RList2
            };
        }        

        /// <summary>
        /// 新增修改排班
        /// </summary>
        /// <param name="demodel"></param>
        /// <returns></returns>
        public string SetScrollPlanInfo(RB_Scroll_Plan_ViewModel demodel)
        {
            if (demodel.Id > 0)
            {
                Dictionary<string, object> keyValues = new Dictionary<string, object>() {
                    { nameof(RB_Scroll_Plan_ViewModel.Date), demodel.Date},
                    { nameof(RB_Scroll_Plan_ViewModel.AccountId), demodel.AccountId},
                    { nameof(RB_Scroll_Plan_ViewModel.ShiftId), demodel.ShiftId},
                    { nameof(RB_Scroll_Plan_ViewModel.RoomId), demodel.RoomId},
                    { nameof(RB_Scroll_Plan_ViewModel.UpdateBy), demodel.UpdateBy},
                    { nameof(RB_Scroll_Plan_ViewModel.UpdateTime), demodel.UpdateTime},
                };
                List<WhereHelper> wheres = new List<WhereHelper>() {
                    new WhereHelper(){
                         FiledName = nameof(RB_Scroll_Plan_ViewModel.Id),
                          FiledValue = demodel.Id,
                           OperatorEnum =OperatorEnum.Equal
                    }
                };
                bool flag = scroll_PlanRepository.Update(keyValues, wheres);
                return flag ? "" : "出错了，请联系管理员";
            }
            else {
                bool flag = scroll_PlanRepository.Insert(demodel) > 0;
                return flag ? "" : "出错了，请联系管理员";
            }
        }

        #endregion

        #region 上课时段

        /// <summary>
        /// 获取上课时段列表
        /// </summary>
        /// <param name="group_Id"></param>
        /// <returns></returns>
        public List<RB_Scroll_CourseTime_ViewModel> GetScrollCourseTimeList(int group_Id)
        {
            var list = scroll_CourseTimeRepository.GetList(new RB_Scroll_CourseTime_ViewModel() { Group_Id = group_Id });
            foreach (var item in list) {
                item.TimeList = new List<CourseTimeModel>();
                if (!string.IsNullOrEmpty(item.Content))
                {
                    item.TimeList = JsonHelper.DeserializeObject<List<CourseTimeModel>>(item.Content);
                }
            }
            return list;
        }

        /// <summary>
        /// 新增修改
        /// </summary>
        /// <param name="dmodel"></param>
        /// <returns></returns>
        public string SetScrollCourseTime(RB_Scroll_CourseTime_ViewModel dmodel)
        {
            if (dmodel.Id > 0)
            {
                Dictionary<string, object> keyValues = new Dictionary<string, object>() {
                    { nameof(RB_Scroll_CourseTime_ViewModel.Name), dmodel.Name},
                    { nameof(RB_Scroll_CourseTime_ViewModel.Content), dmodel.Content},
                    { nameof(RB_Scroll_CourseTime_ViewModel.UpdateBy), dmodel.UpdateBy},
                    { nameof(RB_Scroll_CourseTime_ViewModel.UpdateTime), dmodel.UpdateTime},
                };
                List<WhereHelper> wheres = new List<WhereHelper>() {
                    new WhereHelper(){
                         FiledName = nameof(RB_Scroll_CourseTime_ViewModel.Id),
                          FiledValue = dmodel.Id,
                           OperatorEnum =OperatorEnum.Equal
                    }
                };
                bool flag = scroll_CourseTimeRepository.Update(keyValues, wheres);
                return flag ? "" : "出错了，请联系管理员";
            }
            else
            {
                bool flag = scroll_CourseTimeRepository.Insert(dmodel) > 0;
                return flag ? "" : "出错了，请联系管理员";
            }
        }

        /// <summary>
        /// 删除上课时段
        /// </summary>
        /// <param name="CourseTimeId"></param>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public string DelScrollCourseTime(int CourseTimeId, UserInfo userInfo)
        {
            Dictionary<string, object> keyValues = new Dictionary<string, object>() {
                { nameof(RB_Scroll_CourseTime_ViewModel.Status), 1},
                { nameof(RB_Scroll_CourseTime_ViewModel.UpdateBy), userInfo.Id},
                { nameof(RB_Scroll_CourseTime_ViewModel.UpdateTime), DateTime.Now},
            };
            List<WhereHelper> wheres = new List<WhereHelper>() {
                new WhereHelper(){
                        FiledName = nameof(RB_Scroll_CourseTime_ViewModel.Id),
                        FiledValue = CourseTimeId,
                        OperatorEnum =OperatorEnum.Equal
                }
            };
            bool flag = scroll_CourseTimeRepository.Update(keyValues, wheres);
            return flag ? "" : "出错了，请联系管理员";
        }

        #endregion


        #region 预约课程

        /// <summary>
        /// 获取预约分页列表
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="count"></param>
        /// <param name="demodel"></param>
        /// <returns></returns>
        public List<RB_Scroll_Appointment_ViewModel> GetAppointPageList(int pageIndex, int pageSize, out long count, RB_Scroll_Appointment_ViewModel demodel)
        {
            var list = scroll_AppointmentRepository.GetAppointPageList(pageIndex, pageSize, out count, demodel);
            if (list.Any()) {
                //获取上课时段
                string CourseTimeIds = string.Join(",", list.Select(x => x.CourseTimeId).Distinct());
                var ctlist = scroll_CourseTimeRepository.GetList(new RB_Scroll_CourseTime_ViewModel() { Group_Id = demodel.Group_Id, CourseTimeIds = CourseTimeIds });
                foreach (var item in ctlist)
                {
                    item.TimeList = new List<CourseTimeModel>();
                    if (!string.IsNullOrEmpty(item.Content))
                    {
                        item.TimeList = JsonHelper.DeserializeObject<List<CourseTimeModel>>(item.Content);
                    }
                }

                foreach (var item in list)
                {
                    var ctModel = ctlist.Where(x => x.Id == item.CourseTimeId).FirstOrDefault();
                    item.CourseTimeList = ctModel.TimeList.Where(x => ("," + item.ShiftSort + ",").Contains("," + x.Sort + ",")).ToList();
                }
            }
            return list;
        }

        #endregion

        #region 小程序
        /// <summary>
        /// 获取预约基本信息
        /// </summary>
        /// <param name="userInfo"></param>
        /// <param name="rmsg"></param>
        /// <returns></returns>
        public object GetScrollAppointmentBaseInfo(AppletStudentInfo userInfo, out string rmsg) {
            rmsg = "";
            #region 学生的课程
            //获取正在上课的课程
            var learnModel = student_OrderGuestRepository.GetStudentLearningCourse(userInfo.AccountId, userInfo.Group_Id);
            if (learnModel == null) { rmsg = "未查询有正在学习的课程，无法约课"; return ""; }
            if (learnModel.ClassScrollType != 2) { rmsg = "不是预约学员，无法查看"; return ""; }
            //获取课程信息
            var courseModel = courseRepository.GetEntity(learnModel.CourseId);
            if (courseModel.CourseTimeId <= 0) { rmsg = "课程未关联上课时段"; return ""; }
            //查询课程使用的上课时段
            var ctModel = scroll_CourseTimeRepository.GetEntity<RB_Scroll_CourseTime_ViewModel>(courseModel.CourseTimeId);
            if (!string.IsNullOrEmpty(ctModel.Content))
            {
                ctModel.TimeList = JsonHelper.DeserializeObject<List<CourseTimeModel>>(ctModel.Content);
            }
            else { rmsg = "上课时段未配置"; return ""; }
            //获取课程的章节数量
            int MaxChapterNum = courseRepository.GetMaxChapterNum(learnModel.CourseId, userInfo.Group_Id);
            if (learnModel.CourseChapterNo >= MaxChapterNum) { rmsg = "课程已上完，无法继续约课"; return ""; }
            #endregion

            //查询已预约了几次课程
            var myAppointModel = scroll_AppointmentRepository.GetMyAppointmentNum(userInfo.AccountId, userInfo.Group_Id);
            string AppointDate = "";//最后预约的时间  再次预约只能预约之后的日期
            int AppointNum = 0;//已预约次数
            if (myAppointModel != null)
            {
                AppointDate = myAppointModel.Date.ToString("yyyy-MM-dd");
                AppointNum = myAppointModel.ScrollMinNum;
            }

            //获取提前天数 + 可预约时间   (这个应该走中心 或者 首页接口反) 具体看预约的入口在哪里  根据这个时间 准确抓取首次加载的日期
            int AdvanceDay = Convert.ToInt32(dictvalueRepository.GetList(new Model.ViewModel.User.RB_Dictvalue_Extend() { RB_Group_id = userInfo.Group_Id, DictKey = "Scroll_AdvanceDay" }).FirstOrDefault()?.Content ?? "1");
            string ScrollETime = dictvalueRepository.GetList(new Model.ViewModel.User.RB_Dictvalue_Extend() { RB_Group_id = userInfo.Group_Id, DictKey = "Scroll_Time" }).FirstOrDefault()?.Content ?? "";
            //预约范围
            int AppointDay = Convert.ToInt32(dictvalueRepository.GetList(new Model.ViewModel.User.RB_Dictvalue_Extend() { RB_Group_id = userInfo.Group_Id, DictKey = "Scroll_AppointDay" }).FirstOrDefault()?.Content ?? "7");

            double NextAppointMinutes = 0;
            if (MaxChapterNum > learnModel.CourseChapterNo + AppointNum) {
                //查询下一次课的耗时分钟数  前端需要根据这个分钟数 
                var chapterModel = course_ChapterRepository.GetChapterListRepository(new RB_Course_Chapter_ViewModel() { Group_Id = userInfo.Group_Id, CourseId = learnModel.CourseId, ChapterNo = (learnModel.CourseChapterNo + AppointNum + 1).ToString() }).FirstOrDefault();
                NextAppointMinutes = chapterModel?.StudyMinutes ?? 0;
            }

            #region 获取订阅模板
            // 预约成功  +  取消
            List<string> TempleteList = new List<string>()
            {
                "oAkcEBjei5seEiDBJVZyjJj2MsHHfYPikNkn-kdVEK0",
                "_iqA9KHffrLRNg_yRQqk7uLQNzJsQIGF7ykXLsFXhlw"
            };
            #endregion

            return new
            {
                AccountId = userInfo.Id,
                StuId = userInfo.AccountId,
                NextSKChapterNo = learnModel.CourseChapterNo + 1,
                AppointDate,
                AppointNum,
                NextAppointChapterNo = learnModel.CourseChapterNo + 1 + AppointNum,
                IsNextAppoint = MaxChapterNum > learnModel.CourseChapterNo + AppointNum,
                NextAppointMinutes,
                MaxChapterNum,
                AdvanceDay,
                ScrollETime,
                AppointDay,
                learnModel.CourseId,
                TempleteList
            };
        }

        /// <summary>
        /// 获取可预约老师的列表
        /// </summary>
        /// <param name="userInfo"></param>
        /// <param name="Date"></param>
        /// <param name="rmsg"></param>
        /// <returns></returns>
        public object GetScrollAppointmentTeacherList(AppletStudentInfo userInfo, string Date, int SchoolId, out string rmsg)
        {
            rmsg = "";
            #region 学生的课程
            //获取正在上课的课程
            var learnModel = student_OrderGuestRepository.GetStudentLearningCourse(userInfo.AccountId, userInfo.Group_Id);
            if (learnModel == null) { rmsg = "未查询有正在学习的课程，无法约课";return ""; }
            if (learnModel.ClassScrollType != 2) { rmsg = "不是预约学员，无法查看"; return ""; }
            //获取课程信息
            var courseModel = courseRepository.GetEntity(learnModel.CourseId);
            if (courseModel.CourseTimeId <= 0) { rmsg = "课程未关联上课时段"; return ""; }
            //查询课程使用的上课时段
            var ctModel = scroll_CourseTimeRepository.GetEntity<RB_Scroll_CourseTime_ViewModel>(courseModel.CourseTimeId);
            if (!string.IsNullOrEmpty(ctModel.Content))
            {
                ctModel.TimeList = JsonHelper.DeserializeObject<List<CourseTimeModel>>(ctModel.Content);
            }
            else { rmsg = "上课时段未配置"; return ""; }
            //获取课程的章节数量
            int MaxChapterNum = courseRepository.GetMaxChapterNum(learnModel.CourseId, userInfo.Group_Id);
            if (learnModel.CourseChapterNo >= MaxChapterNum) { rmsg = "课程已上完，无法继续约课"; return ""; }

            //查询已预约了几次课程
            var myAppointModel = scroll_AppointmentRepository.GetMyAppointmentNum(userInfo.AccountId, userInfo.Group_Id);
            string AppointDate = "";//最后预约的时间  再次预约只能预约之后的日期
            int AppointNum = 0;//已预约次数
            if (myAppointModel != null)
            {
                AppointDate = myAppointModel.Date.ToString("yyyy-MM-dd");
                AppointNum = myAppointModel.ScrollMinNum;
            }
            #endregion

            #region 组装数据
            //查询班次
            var shiftList = scroll_ShiftRepository.GetList(new RB_Scroll_Shift_ViewModel() { Group_Id = userInfo.Group_Id });
            //查询当天可上课的老师
            var planList = scroll_PlanRepository.GetTeacherPlanForDay(Date, SchoolId, userInfo.Group_Id);
            //再查询这些老师  正常排课 + 试听课安排  需要排除这些课程
            var pcList = class_PlanRepository.GetClassPlanModelRepository(new RB_Class_Plan_ViewModel() { Group_Id = userInfo.Group_Id, QClassDateStr = Date });
            if (pcList.Any()) {
                //查询计划的时间段
                string planids = string.Join(",", pcList.Select(x => x.ClassPlanId));
                var ctList = class_TimeRepository.GetClassTimeListRepository(new RB_Class_Time_ViewModel() { Group_Id = userInfo.Group_Id, QClassPlanIds = planids });
                foreach (var item in pcList) {
                    item.PlanTimeList = ctList.Where(x => x.ClassPlanId == item.ClassPlanId).ToList();
                }
            }
            var rcList = reserve_ClassRepository.GetReserveClassListRepository(new Model.ViewModel.Reserve.RB_Reserve_Class_Extend() { Group_Id = userInfo.Group_Id, StartClassDate = Date, EndClassDate = Date });

            //再查询当日已预约情况
            var appointList = scroll_AppointmentRepository.GetList(new RB_Scroll_Appointment_ViewModel() { Group_Id = userInfo.Group_Id, StartTime = Date, EntTime = Date });

            List<object> RList = new List<object>();
            //开始遍历老师了
            foreach (var item in planList) {
                //查询班次
                var shiftModel = shiftList.Where(x => x.Id == item.ShiftId).FirstOrDefault();
                item.CourseTimeList = ctModel.TimeList.Where(x => Convert.ToDateTime("2020-01-01 " + x.StartTime) >= Convert.ToDateTime("2020-01-01 " + shiftModel.StartTime) && Convert.ToDateTime("2020-01-01 " + x.EndTime) <= Convert.ToDateTime("2020-01-01 " + shiftModel.EndTime)).RefMapperToList<CourseTimeExtend>();

                //查询该时段内  是否已有正常排课
                var pc2List = pcList.Where(x => x.TeacherId == item.TeacherId).ToList();
                foreach (var qitem in pc2List) {
                    foreach (var citem in qitem.PlanTimeList) {
                        DateTime CSDate = Convert.ToDateTime("2022-01-01 " + citem.StartTime);
                        DateTime CEDate = Convert.ToDateTime("2022-01-01 " + citem.EndTime);
                        //开始验证重复数据
                        var HList = item.CourseTimeList.Where(x => (x.SDate <= CSDate && CSDate <= x.EDate) || (x.SDate <= CEDate && CEDate <= x.EDate)).ToList();
                        foreach (var hitem in HList) {
                            hitem.State = 2;//已有排课  不可预约
                        }
                    }
                }
                //查询该时段内  是否已有正常试听
                var rc2List = rcList.Where(x => x.TeacherId == item.TeacherId).ToList();
                foreach (var qitem in rc2List) {
                    DateTime CSDate = Convert.ToDateTime("2022-01-01 " + qitem.ClassTime);
                    DateTime CEDate = Convert.ToDateTime("2022-01-01 " + qitem.EndTime);
                    //开始验证重复数据
                    var HList = item.CourseTimeList.Where(x => (x.SDate <= CSDate && CSDate <= x.EDate) || (x.SDate <= CEDate && CEDate <= x.EDate)).ToList();
                    foreach (var hitem in HList)
                    {
                        hitem.State = 2;//已有排课  不可预约
                    }
                }

                //查询已预约情况
                var aList = appointList.Where(x => x.TeacherId == item.TeacherId).ToList();
                aList.GroupBy(x => new { x.CourseId, x.ChapterNo, x.ShiftSort }).ToList().ForEach(x =>
                {
                    var firstModel = x.FirstOrDefault();
                    List<int> SortList = JsonHelper.DeserializeObject<List<int>>("[" + x.Key.ShiftSort + "]");
                    item.CourseTimeList.Where(y => SortList.Contains(y.Sort)).ToList().ForEach(z => {
                        z.MinPeopleNum = firstModel.ScrollMinNum;
                        z.MaxPeopleNum = firstModel.ScrollMaxNum;
                        z.State = 3;//已预约了
                        if (x.Where(x => x.StuId == userInfo.AccountId).Any()) {
                            z.State = 4;//我预约的
                        }
                        z.CourseId = x.Key.CourseId;
                        z.CourseName = firstModel.CourseName;
                        z.CourseChapterNo = x.Key.ChapterNo;
                        z.PeopleNum = x.Count();
                        z.SortIdentify = x.Key.ShiftSort;
                        z.Description = string.Join(",", x.Select(q => q.StuName));
                        if (z.State == 3) {
                            if (learnModel.CourseId != z.CourseId) {
                                //课程不一致 无法预约
                                z.State = 2;
                            }
                            if (z.CourseChapterNo != learnModel.CourseChapterNo + 1 + AppointNum) {
                                //章节不一致 无法预约
                                z.State = 2;
                            }
                            if (z.MaxPeopleNum <= z.PeopleNum) {
                                //人数已报满 无法预约
                                z.State = 2;
                            }
                        }
                    });
                });

                item.CourseTimeList = item.CourseTimeList.Where(x => x.State != 2).ToList();//排除不可预约的
                RList.Add(new
                {
                    item.AccountId,
                    item.TeacherId,
                    item.TeacherHead,
                    item.TeacherName,
                    item.TeacherIntro,
                    item.RoomId,
                    item.RoomName,
                    item.SchoolName,
                    item.CourseTimeList,
                    shiftModel.StartTime,
                    shiftModel.EndTime
                });
            }
            #endregion

            return RList;
        }

        /// <summary>
        /// 预约
        /// </summary>
        /// <param name="demodel"></param>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public string SetScrollAppointment(RB_Scroll_Appointment_ViewModel demodel, AppletStudentInfo userInfo)
        {
            #region 初步验证
            int AppointDay = Convert.ToInt32(dictvalueRepository.GetList(new Model.ViewModel.User.RB_Dictvalue_Extend() { RB_Group_id = userInfo.Group_Id, DictKey = "Scroll_AppointDay" }).FirstOrDefault()?.Content ?? "7");
            //只能约最近7天的 (包含今日)
            if (demodel.Date > DateTime.Now.AddDays(AppointDay - 1)) { return "只能预约最近" + AppointDay + "天课程"; }
            //提前天数
            int AdvanceDay = Convert.ToInt32(dictvalueRepository.GetList(new Model.ViewModel.User.RB_Dictvalue_Extend() { RB_Group_id = userInfo.Group_Id, DictKey = "Scroll_AdvanceDay" }).FirstOrDefault()?.Content ?? "1");
            if (demodel.Date < Convert.ToDateTime(DateTime.Now.AddDays(AdvanceDay).ToString("yyyy-MM-dd"))) { return "需要提前" + AdvanceDay + "天约课"; }
            if (AdvanceDay == 1)
            {
                //可预约的时间 (提前1天时启用)
                string ScrollETime = dictvalueRepository.GetList(new Model.ViewModel.User.RB_Dictvalue_Extend() { RB_Group_id = userInfo.Group_Id, DictKey = "Scroll_Time" }).FirstOrDefault()?.Content ?? "";
                if (DateTime.Now > Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd") + " " + ScrollETime)) { return "需要在当日" + ScrollETime + "之前约课"; }
            }
            //我已预约的
            var myAppointModel = scroll_AppointmentRepository.GetMyAppointmentNum(userInfo.AccountId, userInfo.Group_Id);
            int AppointNum = 0;//已预约次数
            if (myAppointModel != null) {
                if (demodel.Date <= myAppointModel.Date) { return "需预约" + myAppointModel.Date.ToString("yyyy-MM-dd") + "之后的日期"; }
                AppointNum = myAppointModel.ScrollMinNum;
            }
            #endregion

            #region 学生的课程
            //获取正在上课的课程
            var learnModel = student_OrderGuestRepository.GetStudentLearningCourse(userInfo.AccountId, userInfo.Group_Id);
            if (learnModel == null) { return "未查询有正在学习的课程，无法约课"; }
            if (learnModel.ClassScrollType != 2) { return "不是预约学员，无法查看"; }
            if (demodel.CourseId != learnModel.CourseId) { return "正在学习的课程不正确"; }
            if (learnModel.CourseChapterNo + AppointNum + 1 != demodel.ChapterNo) { return "预约第几次课有误，请刷新后再试"; }
            //获取课程信息
            var courseModel = courseRepository.GetEntity(learnModel.CourseId);
            if (courseModel.CourseTimeId <= 0) { return "课程未关联上课时段"; }
            //查询课程使用的上课时段
            var ctModel = scroll_CourseTimeRepository.GetEntity<RB_Scroll_CourseTime_ViewModel>(courseModel.CourseTimeId);
            if (!string.IsNullOrEmpty(ctModel.Content))
            {
                ctModel.TimeList = JsonHelper.DeserializeObject<List<CourseTimeModel>>(ctModel.Content);
            }
            else { return "上课时段未配置"; }
            //获取课程的章节数量
            int MaxChapterNum = courseRepository.GetMaxChapterNum(learnModel.CourseId, userInfo.Group_Id);
            if (learnModel.CourseChapterNo + AppointNum + 1 > MaxChapterNum) { return "课程已上完，无法继续约课"; }
            #endregion

            #region 组装排班
            string Date = demodel.Date.ToString("yyyy-MM-dd");
            //验证当日老师的数据
            var planList = scroll_PlanRepository.GetList(new RB_Scroll_Plan_ViewModel() { Group_Id = userInfo.Group_Id, AccountId = demodel.AccountId, STime = Date, ETime = Date });
            if (!planList.Any()) { return "老师当日未查询到可预约课，请刷新后再试"; }

            //开始验证 此时段数据是否可以预约
            var pcList = class_PlanRepository.GetClassPlanModelRepository(new RB_Class_Plan_ViewModel() { Group_Id = userInfo.Group_Id, QClassDateStr = Date, TeacherId = demodel.TeacherId });
            if (pcList.Any())
            {
                //查询计划的时间段
                string planids = string.Join(",", pcList.Select(x => x.ClassPlanId));
                var ctList = class_TimeRepository.GetClassTimeListRepository(new RB_Class_Time_ViewModel() { Group_Id = userInfo.Group_Id, QClassPlanIds = planids });
                foreach (var item in pcList)
                {
                    item.PlanTimeList = ctList.Where(x => x.ClassPlanId == item.ClassPlanId).ToList();
                }
            }
            var rcList = reserve_ClassRepository.GetReserveClassListRepository(new Model.ViewModel.Reserve.RB_Reserve_Class_Extend() { Group_Id = userInfo.Group_Id, StartClassDate = Date, EndClassDate = Date, TeacherId = demodel.TeacherId });

            //再查询当日已预约情况
            var appointList = scroll_AppointmentRepository.GetList(new RB_Scroll_Appointment_ViewModel() { Group_Id = userInfo.Group_Id, StartTime = Date, EntTime = Date });
            if (appointList.Where(x => x.StuId == userInfo.AccountId).Any()) { return "当日已有预约，无法继续预约"; }

            //开始遍历老师了
            foreach (var item in planList)
            {
                //查询班次
                var shiftModel = scroll_ShiftRepository.GetList(new RB_Scroll_Shift_ViewModel() { Group_Id = userInfo.Group_Id, Id = item.ShiftId }).FirstOrDefault();
                //上课时段
                item.CourseTimeList = ctModel.TimeList.Where(x => Convert.ToDateTime("2020-01-01 " + x.StartTime) >= Convert.ToDateTime("2020-01-01 " + shiftModel.StartTime) && Convert.ToDateTime("2020-01-01 " + x.EndTime) <= Convert.ToDateTime("2020-01-01 " + shiftModel.EndTime)).RefMapperToList<CourseTimeExtend>();

                //查询该时段内  是否已有正常排课
                var pc2List = pcList.Where(x => x.TeacherId == item.TeacherId).ToList();
                foreach (var qitem in pc2List)
                {
                    foreach (var citem in qitem.PlanTimeList)
                    {
                        DateTime CSDate = Convert.ToDateTime("2022-01-01 " + citem.StartTime);
                        DateTime CEDate = Convert.ToDateTime("2022-01-01 " + citem.EndTime);
                        //开始验证重复数据
                        var HList = item.CourseTimeList.Where(x => (x.SDate <= CSDate && CSDate <= x.EDate) || (x.SDate <= CEDate && CEDate <= x.EDate)).ToList();
                        foreach (var hitem in HList)
                        {
                            hitem.State = 2;//已有排课  不可预约
                        }
                    }
                }
                //查询该时段内  是否已有正常试听
                var rc2List = rcList.Where(x => x.TeacherId == item.TeacherId).ToList();
                foreach (var qitem in rc2List)
                {
                    DateTime CSDate = Convert.ToDateTime("2022-01-01 " + qitem.ClassTime);
                    DateTime CEDate = Convert.ToDateTime("2022-01-01 " + qitem.EndTime);
                    //开始验证重复数据
                    var HList = item.CourseTimeList.Where(x => (x.SDate <= CSDate && CSDate <= x.EDate) || (x.SDate <= CEDate && CEDate <= x.EDate)).ToList();
                    foreach (var hitem in HList)
                    {
                        hitem.State = 2;//已有排课  不可预约
                    }
                }

                //查询已预约情况
                var aList = appointList.Where(x => x.TeacherId == item.TeacherId).ToList();
                aList.GroupBy(x => new { x.CourseId, x.ChapterNo, x.ShiftSort }).ToList().ForEach(x =>
                {
                    var firstModel = x.FirstOrDefault();
                    List<int> SortList = JsonHelper.DeserializeObject<List<int>>("[" + x.Key.ShiftSort + "]");
                    item.CourseTimeList.Where(y => SortList.Contains(y.Sort)).ToList().ForEach(z => {
                        z.MinPeopleNum = firstModel.ScrollMinNum;
                        z.MaxPeopleNum = firstModel.ScrollMaxNum;
                        z.State = 3;//已预约了
                        if (x.Where(x => x.StuId == userInfo.AccountId).Any())
                        {
                            z.State = 4;//我预约的
                        }
                        z.CourseId = x.Key.CourseId;
                        z.CourseName = firstModel.CourseName;
                        z.CourseChapterNo = x.Key.ChapterNo;
                        z.PeopleNum = x.Count();
                    });
                });
            }
            #endregion

            #region 开始预约
            double NextAppointMinutes = 0;
            if (MaxChapterNum > learnModel.CourseChapterNo + AppointNum)
            {
                //查询下一次课的耗时分钟数  前端需要根据这个分钟数 
                var chapterModel = course_ChapterRepository.GetChapterListRepository(new RB_Course_Chapter_ViewModel() { Group_Id = userInfo.Group_Id, CourseId = learnModel.CourseId, ChapterNo = (learnModel.CourseChapterNo + AppointNum + 1).ToString() }).FirstOrDefault();
                NextAppointMinutes = chapterModel?.StudyMinutes ?? 0;
            }

            var planModel = planList.FirstOrDefault();
            var timeList = planModel.CourseTimeList.Where(x => ("," + demodel.ShiftSort + ",").Contains("," + x.Sort + ",")).ToList();
            if (timeList.Sum(x => x.Minutes) != NextAppointMinutes) { return "预约时长不正确"; }
            if (timeList.Where(x => x.State == 2).Any()) { return "当日有时段不可预约"; }
            foreach (var item in timeList.Where(x => x.State == 3))
            {
                if (demodel.CourseId != item.CourseId) { return "预约课程不一致"; }
                if (demodel.ChapterNo != item.CourseChapterNo) { return "预约课程章节不一致"; }
                if (item.PeopleNum + 1 > item.MaxPeopleNum) { return "该时段已预约满，请预约其他时段"; }
            }

            demodel.CourseEndTime = Convert.ToDateTime(Date + " " + timeList.Max(x => x.EndTime));//上完课的时间
            demodel.RoomId = planModel.RoomId;//上课教室

            //验证都OK了  插入预约数据
            bool flag = scroll_AppointmentRepository.Insert(demodel) > 0;
            return flag ? "" : "出错了，请联系管理员";
            #endregion
        }

        /// <summary>
        /// 取消预约
        /// </summary>
        /// <param name="appointId"></param>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public string CancelAppointment(int appointId, AppletStudentInfo userInfo)
        {
            var appontModel = scroll_AppointmentRepository.GetEntity(appointId);
            if (appontModel == null || appontModel.StuId != userInfo.AccountId) { return "预约不存在"; }
            if (appontModel.State != Common.Enum.Course.CourseAppointStateEnum.WaitSure) { return "状态不正确，无法取消"; }
            Dictionary<string, object> keyValues = new Dictionary<string, object>() {
                { nameof(RB_Scroll_Appointment_ViewModel.State), Common.Enum.Course.CourseAppointStateEnum.Cancel},
                { nameof(RB_Scroll_Appointment_ViewModel.UpdateTime), DateTime.Now},
            };
            List<WhereHelper> wheres = new List<WhereHelper>() {
                new WhereHelper(){
                     FiledName = nameof(RB_Scroll_Appointment_ViewModel.Id),
                      FiledValue = appointId,
                       OperatorEnum =OperatorEnum.Equal
                }
            };
            bool flag = scroll_AppointmentRepository.Update(keyValues, wheres);
            return flag ? "" : "出错了，请联系管理员";
        }
        #endregion
    }
}
