
using Edu.Cache.User;
using Edu.Common;
using Edu.Common.Enum.Course;
using Edu.Common.Enum.User;
using Edu.Common.Plugin;
using Edu.Model.CacheModel;
using Edu.Model.Entity.BackClass;
using Edu.Model.Entity.Course;
using Edu.Model.ViewModel.Contract;
using Edu.Model.ViewModel.Course;
using Edu.Model.ViewModel.EduTask;
using Edu.Model.ViewModel.Finance;
using Edu.Model.ViewModel.Grade;
using Edu.Model.ViewModel.Sell;
using Edu.Model.ViewModel.User;
using Edu.Repository.BackClass;
using Edu.Repository.Contract;
using Edu.Repository.Course;
using Edu.Repository.Customer;
using Edu.Repository.EduTask;
using Edu.Repository.Finance;
using Edu.Repository.Flow;
using Edu.Repository.Grade;
using Edu.Repository.Log;
using Edu.Repository.Sell;
using Edu.Repository.User;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VT.FW.DB;

namespace Edu.Module.Course
{
    /// <summary>
    /// 学员单据处理类
    /// </summary>
    public class StudentBillModule
    {
        /// <summary>
        /// 学员退课单据仓储层对象
        /// </summary>
        private readonly RB_Student_BackClassRepository student_BackClassRepository = new RB_Student_BackClassRepository();

        /// <summary>
        /// 旅客表仓储层对象
        /// </summary>
        private readonly RB_Order_GuestRepository order_GuestRepository = new RB_Order_GuestRepository();

        /// <summary>
        /// 订单仓储层对象
        /// </summary>
        private readonly RB_OrderRepository orderRepository = new RB_OrderRepository();

        /// <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_SchoolRepository schoolRepository = new RB_SchoolRepository();

        /// <summary>
        /// 日志
        /// </summary>
        private readonly RB_User_ChangeLogRepository changeLogRepository = new RB_User_ChangeLogRepository();

        /// <summary>
        /// 学员签到仓储层对象
        /// </summary>
        private readonly RB_Class_CheckRepository class_CheckRepository = new RB_Class_CheckRepository();

        /// <summary>
        /// 学员事件记录仓储层
        /// </summary>
        private readonly RB_Student_EventLogRepository student_EventLogRepository = new RB_Student_EventLogRepository();

        /// <summary>
        /// 财务配置
        /// </summary>
        private readonly RB_Finance_ConfigRepository finance_ConfigRepository = new RB_Finance_ConfigRepository();

        /// <summary>
        /// 班级处理类
        /// </summary>
        private readonly ClassModule classModule = new ClassModule();

        /// <summary>
        /// 账号处理类
        /// </summary>
        private readonly User.AccountModule accountModule = new User.AccountModule();

        /// <summary>
        /// 课程优惠信息
        /// </summary>
        private readonly RB_Course_PreferentialRepository course_PreferentialRepository = new RB_Course_PreferentialRepository();

        /// <summary>
        /// 退课协议仓储层对象
        /// </summary>
        private readonly RB_BackClass_ProtocolRepository backClass_ProtocolRepository = new RB_BackClass_ProtocolRepository();

        /// <summary>
        /// 业务单据仓储层对象
        /// </summary>
        private readonly RB_Education_ReceiptRepository education_ReceiptRepository = new RB_Education_ReceiptRepository();

        /// <summary>
        /// 学员协助
        /// </summary>
        private readonly RB_Student_AssistRepository student_AssistRepository = new RB_Student_AssistRepository();
        /// <summary>
        /// 同业
        /// </summary>
        private readonly RB_CustomerRepository customerRepository = new RB_CustomerRepository();
        /// <summary>
        /// 学生仓储层对象
        /// </summary>
        private readonly RB_StudentRepository studentRepository = new RB_StudentRepository();


        /// <summary>
        /// 计算学员退课金额
        /// </summary>
        /// <param name="BackId"></param>
        /// <returns></returns>
        public object GetBackBillMoneyModule(int BackId)
        {
            var backModel = student_BackClassRepository.GetEntity(BackId);
            var orderModel = orderRepository.GetEntity(backModel.OrderId);
            //班级实体类
            var classModel = classRepository.GetEntity(backModel.ClassId);
            var stuCheckList = class_CheckRepository.GetGuestFinishMinutesRepository(backModel.GuestId.ToString());
            //完成课时数
            var FinishHours = stuCheckList?.Sum(qitem => qitem.FinishClassHours) ?? 0;
            var courseModel = new RB_Course();
            if (orderModel.CourseId > 0)
            {
                courseModel = courseRepository.GetEntity(orderModel.CourseId);
            }
            else
            {
                courseModel = courseRepository.GetEntity(classModel.CouseId);
            }
            //预计退款金额
            decimal backMoney = orderRepository.CalcBackMoneyRepository(orderModel, courseModel, FinishHours,out decimal classHourPrice);
            var obj = new
            {
                orderModel.PreferPrice,
                orderModel.GuestNum,
                courseModel.ClassHours,
                FinishHours,
                classHourPrice,
                backMoney = Math.Round(backMoney, 2)
            };
            return obj;
        }

        /// <summary>
        /// 退课一键制单
        /// </summary>
        /// <param name="backClassId"></param>
        /// <param name="clientId"></param>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public string SetStudentBackFinance(int backClassId, int clientId, UserInfo userInfo)
        {
            int IsPublic = 1;// //公账、私账(默认工作)
            int CurrencyId = 21; //币种(默认人民币)
            int clientType = 10;
            var backModel = student_BackClassRepository.GetEntity(backClassId);
            var BackClassProtocolModel = backClass_ProtocolRepository.GetBackClassProtocolListRepository(new RB_BackClass_Protocol_ViewModel()
            {
                BackId = backClassId
            })?.FirstOrDefault();
            var eduReceipt = education_ReceiptRepository.GetEducationReceiptListRepository(new EducationReceiptQuery()
            {
                ReceiptType = 2,
                RelationId= backClassId
            })?.FirstOrDefault();
            if (backModel == null || backModel.AuditStatus != WFRrocessStatus.AuditThrough) { return "退课流程未审核通过"; }
            if (backModel.FinanceId > 0) { return "已制单，无法再次生成财务单据"; }
            var guestModel = order_GuestRepository.GetEntity(backModel.GuestId);
            if (guestModel == null || guestModel.GuestState != GuestStateEnum.DropOut) { return "客人名单状态不正确"; }
            var fcmodel = finance_ConfigRepository.GetList(new RB_Finance_Config_ViewModel() { Group_Id = userInfo.Group_Id, Type = FinanceConfigTypeEnum.DropCourse }).FirstOrDefault();
            if (fcmodel == null) { return "未配置制单流程"; }

            string msg = "";
            #region 新增财务单据
            var detailList = new List<object>
            {
                new
                {
                    fcmodel.CostTypeId,
                    Number = 1,
                    OriginalMoney = backModel.RealityBackMoney,
                    UnitPrice = backModel.RealityBackMoney,
                    Remark = "学员【"+guestModel.GuestName+"】退课"
                }
            };
            var classModel = classRepository.GetEntity(backModel.ClassId);
            string Remark = backModel.ApplyReason+ "【" + (classModel?.ClassName ?? "") + "】下,订单" + backModel.OrderId + " 客人退课";
            var financeObj = new
            {
                OtherType = 28,
                ReFinanceId = eduReceipt?.Id ?? 0,
                ReFinanceId2 = BackClassProtocolModel?.Id ?? 0,
                IsPublic,
                ClientType = clientType,
                ClientID = clientId,
                CurrencyId,
                WBMoney = backModel.RealityBackMoney,
                PayDate = DateTime.Now.ToString("yyyy-MM-dd"),
                TemplateId = fcmodel.TempleteId,
                OrderSource = 17,
                OrderID = backModel.OrderId,
                TCIDList = new List<int>() { backModel.ClassId },
                Remark,
                detailList,
                CreateBy = userInfo.Id,
                RB_Branch_Id = classModel.School_Id,
                RB_Depart_Id = userInfo.DeptId,
                RB_Group_Id = userInfo.Group_Id,
                RB_CreateByName = userInfo.AccountName,
                RB_DepartName = userInfo.DeptName,
                RB_BranchName = schoolRepository.GetEntity(classModel.School_Id)?.SName ?? "",
                RB_GroupName = userInfo.GroupName,
                FinanceType = 2
            };
            string sign = EncryptionHelper.AesEncrypt(JsonHelper.Serialize(financeObj), Config.ReadConfigKey("FinanceKey"));
            var resultInfo = new
            {
                msg = sign
            };
            string apiResult = HttpHelper.HttpPost(Config.ReadConfigKey("PaymentFinanceApi"), JsonHelper.Serialize(resultInfo), "");
            JObject parmsJob = JObject.Parse(apiResult);
            string resultCode = parmsJob.GetStringValue("resultCode");
            int frid = parmsJob.GetInt("data", 0);

            if (resultCode == "1" && frid > 0)
            {
                Dictionary<string, object> keyValues = new Dictionary<string, object>() {
                    { nameof(RB_Student_BackClass.FinanceId),frid}
                };
                bool flag = student_BackClassRepository.Update(keyValues, new WhereHelper(nameof(RB_Student_BackClass.BackId), backModel.BackId));
                if (flag)
                {
                    //记录日志
                    changeLogRepository.Insert(new Model.Entity.Log.RB_User_ChangeLog()
                    {
                        Id = 0,
                        Type = 1,
                        CreateBy = userInfo.Id,
                        CreateTime = DateTime.Now,
                        Group_Id = userInfo.Group_Id,
                        LogContent = "生成学员退课财务单据【" + backModel.BackId + "】",
                        School_Id = userInfo.School_Id,
                        SourceId = 0
                    });
                }
            }
            else
            {
                string message = parmsJob.GetStringValue("message");
                LogHelper.Write("SetStudentBackFinance:" + message);
                msg += backModel.BackId + "创建财务单据失败;";
            }
            #endregion
            return msg;
        }

        /// <summary>
        /// 获取续费课程列表
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="rowsCount"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        public List<object> GetRenewClassModule(int pageIndex, int pageSize, out long rowsCount, RB_Class_ViewModel query)
        {
            List<object> list = new List<object>();
            var classList = classModule.GetClassPageListModule(pageIndex, pageSize, out rowsCount, query, isGetStepPrice: true);
            List<RB_Course_Preferential_Extend> coursePriceList = new List<RB_Course_Preferential_Extend>();
            if (classList != null && classList.Count > 0)
            {
                string courseIds = string.Join(",", classList.Select(qitem => qitem.CouseId));
                coursePriceList = course_PreferentialRepository.GetCoursePreferentialListRepostory(new RB_Course_Preferential_Extend()
                {
                    QCourseIds = courseIds
                });
            }
            foreach (var item in classList)
            {
                decimal SellPrice = item.SellPrice;
                decimal OriginalPrice = item.SellPrice;
                var obj = new
                {
                    item.ClassId,
                    item.ClassName,
                    item.CouseId,
                    item.CourseName,
                    item.ClassHours,
                    item.TeacherName,
                    item.RoomName,
                    OpenTime = Common.ConvertHelper.FormatDate(item.OpenTime),
                    NewOriginalPrice = item.OriginalPrice,
                    NewSellPrice = item.SellPrice,
                    OriginalPrice,
                    SellPrice,
                    item.ClassPersion,
                    item.OrderStudentCount,
                    item.ClassStepPriceList,
                    item.InnerRemark
                };
                list.Add(obj);
            }
            return list;
        }

        #region 出勤管理
        /// <summary>
        /// 获取学生的当日出勤情况
        /// </summary>
        /// <param name="demodel"></param>
        /// <returns></returns>
        public object GetStudentAttendanceDayStatistics(RB_Class_Check_ViewModel demodel)
        {
            //获取当日签到数据
            var list = class_CheckRepository.GetStudentAttendanceDayStatistics(demodel);
            //根据班级 课次分组
            var RList = list.GroupBy(x => new { x.ClassId, x.ClassName, x.ClassNo, x.CouseId, x.CourseName, x.ClassRoomId, x.RoomName, x.School_Id, x.TeacherId, x.TeacherName, x.ClassDate, x.TimeBucket }).OrderBy(x => x.Key.ClassId).ThenBy(x => x.Key.TimeBucket).Select(x => new
            {
                x.Key.ClassId,
                x.Key.ClassName,
                x.Key.ClassNo,
                x.Key.CouseId,
                x.Key.CourseName,
                x.Key.ClassRoomId,
                x.Key.RoomName,
                x.Key.School_Id,
                x.Key.TeacherId,
                x.Key.TeacherName,
                ClassDate = x.Key.ClassDate.ToString("yyyy-MM-dd"),
                x.Key.TimeBucket,
                GuestList = x.Select(z => new
                {
                    z.OrderGuestId,
                    z.GuestName,
                    z.CurrentDeductionHours,
                    z.StudyNum,
                    z.CheckStatus,
                    z.ClassTimeId
                })
            });
            return RList;
        }

        /// <summary>
        /// 获取学生的当日出勤情况  Excel
        /// </summary>
        /// <param name="demodel"></param>
        /// <returns></returns>
        public List<ExcelDataSource> GetStudentAttendanceDayStatisticsToExcel(RB_Class_Check_ViewModel demodel)
        {
            List<ExcelDataSource> RDate = new List<ExcelDataSource>();
            //获取当日签到数据
            var list = class_CheckRepository.GetStudentAttendanceDayStatistics(demodel);
            //根据班级 课次分组
            var glist = list.GroupBy(x => new { x.ClassId, x.ClassName, x.ClassNo, x.CouseId, x.CourseName, x.ClassRoomId, x.RoomName, x.School_Id, x.TeacherId, x.TeacherName, x.ClassDate, x.TimeBucket }).OrderBy(x => x.Key.ClassId).ThenBy(x => x.Key.TimeBucket);
            foreach (var qitem in glist)
            {
                int Count = qitem.Count();
                int Num = 1;
                foreach (var item in qitem)
                {
                    string CheckStatusName = "";
                    switch (item.CheckStatus)
                    {
                        case 0:
                            CheckStatusName = "正常"; break;
                        case 1:
                            CheckStatusName = "缺席"; break;
                        case 2:
                            CheckStatusName = "请假"; break;
                    }
                    if (Num == 1)
                    {
                        ExcelDataSource datarow = new ExcelDataSource(30)
                        {
                            ExcelRows = new List<ExcelColumn>()
                            {
                                new ExcelColumn(value: qitem.Key.ClassNo){ Rowspan = Count },
                                new ExcelColumn(value: qitem.Key.ClassName){ Rowspan = Count },
                                new ExcelColumn(value: qitem.Key.CourseName){ Rowspan = Count},
                                new ExcelColumn(value: qitem.Key.TeacherName){ Rowspan = Count},
                                new ExcelColumn(value: qitem.Key.ClassDate.ToString("yyyy-MM-dd")){ Rowspan = Count },
                                new ExcelColumn(value: qitem.Key.TimeBucket){ Rowspan = Count},
                                new ExcelColumn(value: item.GuestName){ },
                                new ExcelColumn(value: item.CurrentDeductionHours.ToString()){ },
                                new ExcelColumn(value: CheckStatusName){ },
                            }
                        };
                        RDate.Add(datarow);
                    }
                    else
                    {
                        ExcelDataSource datarow = new ExcelDataSource(30)
                        {
                            ExcelRows = new List<ExcelColumn>()
                            {
                                new ExcelColumn(value: ""){ },
                                new ExcelColumn(value: ""){ },
                                new ExcelColumn(value: ""){ },
                                new ExcelColumn(value: ""){ },
                                new ExcelColumn(value: ""){ },
                                new ExcelColumn(value: ""){ },
                                new ExcelColumn(value: item.GuestName){ },
                                new ExcelColumn(value: item.CurrentDeductionHours.ToString()){ },
                                new ExcelColumn(value: CheckStatusName){ },
                            }
                        };
                        RDate.Add(datarow);
                    }
                    Num++;
                }
            }

            return RDate;
        }

        #endregion



        #region 学员名单
        /// <summary>
        /// 获取学员名单分页列表
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="rowsCount"></param>
        /// <param name="demodel"></param>
        /// <param name="orderIds"></param>
        /// <returns></returns>
        public List<RB_Order_Guest_Extend> GetAllStudentPage(int pageIndex, int pageSize, out long rowsCount, RB_Order_Guest_Extend demodel)
        {
            var orderstudentList = order_GuestRepository.GetAllStudentPage(pageIndex, pageSize, out rowsCount, demodel);
            if (orderstudentList.Any()) 
            {
                //课程顾问  协助老师   负责人； 客户来源   来源关联人
                string stuIds = string.Join(",", orderstudentList.Select(x => x.StuId).Distinct().ToList());
                //协助人员列表
                var assistList = student_AssistRepository.GetStudentAssistListRepository(new Model.ViewModel.Customer.RB_Student_Assist_Extend()
                {
                    QStuIds = stuIds
                });
                //内部介绍人
                List<int> empIdList = Common.ConvertHelper.StringToList(string.Join(",", orderstudentList.Where(qitem => qitem.CreateType == StuCreateTypeEnum.InternalIntroduction).Select(qitem => qitem.StuSourceId)));
                List<int> aIds = Common.ConvertHelper.StringToList(string.Join(",", assistList.Select(qitem => qitem.AssistId)));
                List<RB_Account_ViewModel> accountList = new List<RB_Account_ViewModel>();
                if (aIds != null && aIds.Count > 0)
                {
                    empIdList.AddRange(aIds);
                }
                if (empIdList != null && empIdList.Count > 0)
                {
                    accountList = accountModule.GetAccountListExtModule(new RB_Account_ViewModel() { QIds = string.Join(",", empIdList) });
                }
                
                //同业录入列表
                List<Model.ViewModel.Customer.RB_Customer_Extend> customerList = new List<Model.ViewModel.Customer.RB_Customer_Extend>();
                List<int> customerIdList = Common.ConvertHelper.StringToList(string.Join(",", orderstudentList.Where(qitem => qitem.CreateType == StuCreateTypeEnum.CustomerInput).Select(qitem => qitem.StuSourceId)));
                if (customerIdList != null && customerIdList.Count > 0)
                {
                    customerList = customerRepository.GetCustomerListRepository(new Model.ViewModel.Customer.RB_Customer_Extend()
                    {
                        CustomerIds = string.Join(",", customerIdList)
                    });
                }
                List<RB_Student_ViewModel> transStudentList = new List<RB_Student_ViewModel>();
                //转介人列表
                List<int> transIdList = Common.ConvertHelper.StringToList(string.Join(",", orderstudentList.Where(qitem => qitem.CreateType == StuCreateTypeEnum.TransIntroduction).Select(qitem => qitem.StuSourceId)));
                if (transIdList != null && transIdList.Count > 0)
                {
                    transStudentList = studentRepository.GetStudentListRepository(new RB_Student_ViewModel()
                    {
                        StuIds = string.Join(",", transIdList)
                    });
                }

                
                foreach (var item in orderstudentList)
                {
                    var tempAssistList = assistList?.Where(qitem => qitem.StuId == item.StuId)?.ToList();
                    foreach (var sItem in tempAssistList)
                    {
                        sItem.AssistName = accountList?.FirstOrDefault(qitem => qitem.Id == sItem.AssistId)?.AccountName ?? "";
                    }
                    item.AssistList = tempAssistList;
                    if (item.CreateType == StuCreateTypeEnum.InternalIntroduction)
                    {
                        item.StuSourceIdName = accountList?.FirstOrDefault(qitem => qitem.Id == item.StuSourceId)?.AccountName ?? "";
                    }
                    else if (item.CreateType == StuCreateTypeEnum.CustomerInput)
                    {
                        var tempCustomer = customerList?.FirstOrDefault(qitem => qitem.CustomerId == item.StuSourceId);
                        item.StuSourceIdName = tempCustomer?.CustomerName ?? "";
                        if (tempCustomer != null)
                        {
                            if (tempCustomer.CustomerType == Common.Enum.Customer.CatetoryTypeEnum.Other)
                            {
                                item.EnterpriseName = tempCustomer?.EnterpriseName ?? "";
                            }
                            else
                            {
                                item.EnterpriseName = tempCustomer?.CategoryName ?? "";
                            }
                        }
                        else
                        {
                            item.EnterpriseName = "";
                        }
                        
                    }
                    else if (item.CreateType == StuCreateTypeEnum.TransIntroduction)
                    {
                        item.StuSourceIdName = transStudentList?.FirstOrDefault(qitem => qitem.StuId == item.StuSourceId)?.StuName ?? "";
                    }
                }
            }
            return orderstudentList;
        }

        /// <summary>
        /// 获取签到状态记录
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="rowsCount"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        public List<RB_Class_Check_ViewModel> GetClassCheckPageList(int pageIndex, int pageSize, out long rowsCount, RB_Class_Check_ViewModel query)
        {
            return class_CheckRepository.GetClassCheckPageList(pageIndex, pageSize, out rowsCount, query);
        }

        /// <summary>
        /// 获取学员事件记录分页列表
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="rowsCount"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        public List<RB_Student_EventLog_ViewModel> GetStudentEventLogPageList(int pageIndex, int pageSize, out long rowsCount, RB_Student_EventLog_ViewModel query)
        {
            return student_EventLogRepository.GetStudentEventLogPageList(pageIndex, pageSize, out rowsCount, query);
        }

        /// <summary>
        ///删除学员事件
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool DelStudentEventLog(int Id, int UpdateBy)
        {
            Dictionary<string, object> fileds = new Dictionary<string, object>()
            {
                { nameof(RB_Student_EventLog_ViewModel.Status),1},
                { nameof(RB_Student_EventLog_ViewModel.UpdateBy),UpdateBy},
                { nameof(RB_Student_EventLog_ViewModel.UpdateTime),System.DateTime.Now},
            };
            return student_EventLogRepository.Update(fileds, new WhereHelper(nameof(RB_Student_EventLog_ViewModel.Id), Id));
        }

        /// <summary>
        /// 新增/修改学员事件
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool SetStudentEventLog(RB_Student_EventLog_ViewModel model)
        {
            bool flag = false;
            if (model.Id == 0)
            {
                flag = student_EventLogRepository.Insert(model) > 0;
            }
            else
            {
                Dictionary<string, object> fileds = new Dictionary<string, object>()
                {
                   { nameof(RB_Student_EventLog_ViewModel.EventContent),model.EventContent},
                   { nameof(RB_Student_EventLog_ViewModel.EventType),model.EventType},
                   { nameof(RB_Student_EventLog_ViewModel.Title),model.Title},
                   { nameof(RB_Student_EventLog_ViewModel.EventPic),model.EventPic},
                };
                flag = student_EventLogRepository.Update(fileds, new WhereHelper(nameof(RB_Student_EventLog_ViewModel.Id), model.Id));
            }
            return flag;
        }
        #endregion
    }
}