using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EMIS.DataLogic.MinorManage.MinorClass;
using Bowin.Common.Linq.Entity;
using EMIS.ViewModel.MinorManage.MinorClass;
using EMIS.ViewModel;
using System.Linq.Expressions;
using EMIS.Entities;
using Bowin.Common.Linq;
using EMIS.DataLogic.MinorManage.MinorApply;
using EMIS.CommonLogic.MinorManage.MinorApply;
using EMIS.ViewModel.MinorManage.MinorApply;
using EMIS.ViewModel.Students;
using EMIS.DataLogic.MinorManage.MinorPlanManage;
using EMIS.ViewModel.CacheManage;

namespace EMIS.CommonLogic.MinorManage.MinorClass
{
    public class MinorClassServices : BaseServices, IMinorClassServices
    {
        public MinorClassDAL minorClassDAL { get; set; }
        public MinorApplyDAL minorApplyDAL { get; set; }
        public IMinorApplyServices minorApplyServices { get; set; }
        public MinorSpecialtyDAL minorSpecialtyDAL { get; set; }

        /// <summary>
        /// 获取辅修班级信息
        /// </summary>
        /// <param name="configuretView"></param>
        /// <param name="collegeID"></param>
        /// <param name="yearID"></param>
        /// <param name="standardID"></param>
        /// <param name="approvalStatus"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IGridResultSet<MinorClassView> GetMinorClassViewGrid(ConfiguretView configuretView, Guid? collegeID, int? yearID, int? standardID, int? classminorStatus, int pageIndex, int pageSize)
        {
            Expression<Func<CF_Classminor, bool>> exp = (x => true);
            Expression<Func<CF_Grademinor, bool>> expgm = (x => true);
            if (collegeID.HasValue)
            {
                expgm = expgm.And(x => x.CollegeID == collegeID);
            }
            if (yearID.HasValue)
            {
                expgm = expgm.And(x => x.YearID == yearID);
            }
            if (standardID.HasValue)
            {
                expgm = expgm.And(x => x.StandardID == standardID);
            }
            if (classminorStatus.HasValue)
            {
                exp = exp.And(x => x.RecordStatus == classminorStatus);
            }

            var query = minorClassDAL.GetMinorClassViewQueryable(exp, expgm);

            //查询条件
            if (!string.IsNullOrEmpty(configuretView.ConditionValue))
            {
                query = query.DynamicWhere(configuretView.Attribute, configuretView.Condition, configuretView.ConditionValue.Trim());
            }

            var result = this.GetQueryByDataRangeByCollege(query).OrderByDescending(x => x.SchoolyearCode).ThenByDescending(x => x.GradeYearID).ThenBy(x => x.StandardID).ToGridResultSet<MinorClassView>(pageIndex, pageSize);

            return result;
        }

        /// <summary>
        /// 获取辅修班级信息(Excel)
        /// </summary>
        /// <param name="configuretView"></param>
        /// <param name="collegeID"></param>
        /// <param name="yearID"></param>
        /// <param name="standardID"></param>
        /// <param name="approvalStatus"></param>
        /// <param name="idList"></param>
        /// <returns></returns>
        public List<MinorClassView> GetMinorClassViewList(ConfiguretView configuretView, Guid? collegeID, int? yearID, int? standardID, int? classminorStatus, List<Guid?> idList)
        {
            Expression<Func<CF_Classminor, bool>> exp = (x => true);
            Expression<Func<CF_Grademinor, bool>> expgm = (x => true);
            if (collegeID.HasValue)
            {
                expgm = expgm.And(x => x.CollegeID == collegeID);
            }
            if (yearID.HasValue)
            {
                expgm = expgm.And(x => x.YearID == yearID);
            }
            if (standardID.HasValue)
            {
                expgm = expgm.And(x => x.StandardID == standardID);
            }
            if (classminorStatus.HasValue)
            {
                exp = exp.And(x => x.RecordStatus == classminorStatus);
            }
            if (idList.Count > 0 && idList != null)
            {
                exp = exp.And(x => idList.Contains(x.ClassminorID));
            }
            var query = minorClassDAL.GetMinorClassViewQueryable(exp, expgm);

            //查询条件
            if (!string.IsNullOrEmpty(configuretView.ConditionValue))
            {
                query = query.DynamicWhere(configuretView.Attribute, configuretView.Condition, configuretView.ConditionValue.Trim());
            }

            var result = this.GetQueryByDataRangeByCollege(query).OrderByDescending(x => x.SchoolyearCode).ThenByDescending(x => x.GradeYearID).ThenBy(x => x.StandardID).ToList();

            return result;
        }



        public void GenerateMinorClass()
        {
            try
            {
                Expression<Func<EM_StudentMinorRegist, bool>> exp = x => true;
                Expression<Func<CF_Classmajor, bool>> expcla = x => true;
                Expression<Func<CF_College, bool>> expcol = x => true;

                List<CF_Classminor> addClassminorList = new List<CF_Classminor>();
                List<CF_Classminor> updateClassminorList = new List<CF_Classminor>();
                var endStatusID = minorApplyServices.GetCorrectEndStatus();

                exp = exp.And(x => x.RecordStatus == endStatusID);
                var minorStudentList = minorApplyDAL.GetMinorApplyViewQueryable(exp, expcla, expcol);

                var dbClassList = minorClassDAL.GetMinorClassViewQueryable(x => true, x => true).ToList();

                //Expression<Func<CF_ClassminorStudent, bool>> stuexp = x => true;
                //var dbstudent = minorClassDAL.GetStudentsQueryable(stuexp);
                var gradeMinorList = minorSpecialtyDAL.GetMinorSpecialtyViewQueryable(x => x.RecordStatus == (int)CF_GrademinorStatus.Opened);
                var minorApplyViewList = this.GetQueryByDataRangeByCollege(minorStudentList).ToList();

                var gmquery = gradeMinorList.GroupBy(x => new
                {
                    x.SchoolyearID,
                    x.GrademinorID,
                    x.YearID,
                    x.StandardID,
                }).ToList();

                var query = minorApplyViewList.GroupBy(x => new
                {
                    x.SchoolyearID,
                    x.GrademinorID,
                    x.GradeYearID,
                    x.GrademinorName
                }).ToList();
                foreach (var grademinor in gmquery)
                {
                    CF_Classminor classminor = new CF_Classminor();

                    if (dbClassList.Any(x => x.GrademinorID == grademinor.Key.GrademinorID && x.GradeYearID == grademinor.Key.YearID && x.RecordStatus != (int)CF_ClassminorStatus.NotOpen))
                    {
                        continue;
                    }
                    //未开班的更新学生名单
                    if (dbClassList.Any(x => x.GrademinorID == grademinor.Key.GrademinorID && x.GradeYearID == grademinor.Key.YearID && x.RecordStatus == (int)CF_ClassminorStatus.NotOpen))
                    {
                        classminor = minorClassDAL.classminorRepository.GetSingle(x => x.GrademinorID == grademinor.Key.GrademinorID && x.CF_Grademinor.YearID == grademinor.Key.YearID, (x => x.CF_Grademinor));
                        UnitOfWork.Delete<CF_ClassminorStudent>(x => x.ClassminorID == classminor.ClassminorID);
                        //UnitOfWork.Delete<CF_Classminor>(x => x.ClassminorID == classminor.ClassminorID);

                        classminor.RecordStatus = (int)CF_ClassminorStatus.NotOpen;
                        classminor.ModifyTime = DateTime.Now;
                        classminor.ModifyUserID = EMIS.Utility.FormValidate.CustomPrincipal.Current.UserID;
                        if (minorApplyViewList.Where(x => x.GrademinorID == grademinor.Key.GrademinorID && x.GradeYearID == grademinor.Key.YearID).Count() > 0)
                        {
                            var Student = minorApplyViewList.Where(x => x.GrademinorID == grademinor.Key.GrademinorID && x.GradeYearID == grademinor.Key.YearID).Select(x => new CF_ClassminorStudent
                            {
                                ClassminorStudentID = Guid.NewGuid(),
                                ClassminorID = classminor.ClassminorID,
                                UserID = x.UserID.Value,
                                RecordStatus = (int)SYS_STATUS.USABLE,
                                CreateTime = DateTime.Now,
                                CreateUserID = EMIS.Utility.FormValidate.CustomPrincipal.Current.UserID,
                                ModifyTime = DateTime.Now,
                                ModifyUserID = EMIS.Utility.FormValidate.CustomPrincipal.Current.UserID,
                            });
                            classminor.CF_ClassminorStudent = new HashSet<CF_ClassminorStudent>(Student.ToList());
                        }
                        else
                        {
                            classminor.CF_ClassminorStudent = new HashSet<CF_ClassminorStudent>();
                        }

                        updateClassminorList.Add(classminor);
                        //UnitOfWork.Update(classminorList);
                        //UnitOfWork.BulkInsert(classminorList.SelectMany(x => x.CF_ClassminorStudent).ToList());
                    }
                    else {
                        //未生成过班级的生成班级
                        var standardName = IdNameExt.GetDictionaryItem(DictionaryItem.CF_Standard.ToString()).Where(x => x.Value == grademinor.Key.StandardID).Select(x => x.Name).FirstOrDefault();
                        classminor.ClassminorID = Guid.NewGuid();
                        classminor.GrademinorID = grademinor.Key.GrademinorID;
                        classminor.Name = grademinor.Key.YearID.ToString() + standardName + "辅修班";
                        classminor.Abbreviation = classminor.Name;
                        classminor.ClassNum = 1;
                        classminor.RecordStatus = (int)CF_ClassminorStatus.NotOpen;
                        classminor.CreateTime = DateTime.Now;
                        classminor.CreateUserID = EMIS.Utility.FormValidate.CustomPrincipal.Current.UserID;
                        classminor.ModifyTime = DateTime.Now;
                        classminor.ModifyUserID = EMIS.Utility.FormValidate.CustomPrincipal.Current.UserID;
                        if (minorApplyViewList.Where(x => x.GrademinorID == grademinor.Key.GrademinorID && x.GradeYearID == grademinor.Key.YearID).Count() > 0)
                        {
                            var Student = minorApplyViewList.Where(x => x.GrademinorID == grademinor.Key.GrademinorID && x.GradeYearID == grademinor.Key.YearID).Select(x => new CF_ClassminorStudent
                            {
                                ClassminorStudentID = Guid.NewGuid(),
                                ClassminorID = classminor.ClassminorID,
                                UserID = x.UserID.Value,
                                RecordStatus = (int)SYS_STATUS.USABLE,
                                CreateTime = DateTime.Now,
                                CreateUserID = EMIS.Utility.FormValidate.CustomPrincipal.Current.UserID,
                                ModifyTime = DateTime.Now,
                                ModifyUserID = EMIS.Utility.FormValidate.CustomPrincipal.Current.UserID,
                            });
                            classminor.CF_ClassminorStudent = new HashSet<CF_ClassminorStudent>(Student.ToList());
                        }
                        else
                        {
                            classminor.CF_ClassminorStudent = new HashSet<CF_ClassminorStudent>();
                        }
                        addClassminorList.Add(classminor);
                        //UnitOfWork.BulkInsert(classminorList);
                        //UnitOfWork.BulkInsert(classminorList.SelectMany(x => x.CF_ClassminorStudent).ToList());
                    }
                }

                //UnitOfWork.BulkInsert(updateClassminorList);
                UnitOfWork.BulkInsert(updateClassminorList.SelectMany(x => x.CF_ClassminorStudent).ToList());
                UnitOfWork.BulkInsert(addClassminorList);
                UnitOfWork.BulkInsert(addClassminorList.SelectMany(x => x.CF_ClassminorStudent).ToList());

                //UnitOfWork.Commit();

                
            }
            catch (Exception)
            {
                
                throw;
            }
        }

        public void MinorClassEdit(MinorClassView minorClassView)
        {
            try
            {
                CF_Classminor classminor = new CF_Classminor();
                if (minorClassView.ClassminorID == null || minorClassView.ClassminorID == Guid.Empty)
                {
                    //新增、复制新增
                    classminor = minorClassDAL.classminorRepository
                            .GetSingle(x => x.GrademinorID == minorClassView.GrademinorID && x.Name == minorClassView.Name);

                    if (classminor != null)
                    {
                        throw new Exception("已存在名称相同的辅修班级信息。");
                    }

                    classminor = new CF_Classminor();
                    classminor.ClassminorID = Guid.NewGuid();
                    classminor.GrademinorID = minorClassView.GrademinorID;
                    classminor.Name = minorClassView.Name;
                    classminor.ClassNum = minorClassView.ClassNum ?? 1;
                    classminor.Abbreviation = minorClassView.ClassAbbreviation ?? minorClassView.Name;

                    SetNewStatus(classminor);
                    UnitOfWork.Add(classminor);
                }
                else
                {
                    //修改
                    classminor = minorClassDAL.classminorRepository
                            .GetSingle(x => x.ClassminorID != minorClassView.ClassminorID
                            && x.GrademinorID == minorClassView.GrademinorID && x.Name == minorClassView.Name);

                    if (classminor != null)
                    {
                        throw new Exception("已存在名称相同的辅修班级信息。");
                    }

                    classminor = minorClassDAL.classminorRepository
                            .GetSingle(x => x.ClassminorID == minorClassView.ClassminorID);

                    if (classminor == null)
                    {
                        throw new Exception("数据有误,请核查。");
                    }

                    classminor.GrademinorID = minorClassView.GrademinorID;
                    classminor.Name = minorClassView.Name;
                    classminor.ClassNum = minorClassView.ClassNum;
                    classminor.Abbreviation = minorClassView.ClassAbbreviation;
                    SetModifyStatus(classminor);
                }

                UnitOfWork.Commit();
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
        }

        public void MinorClassDelete(IList<Guid?> minorClassIDList)
        {
            try
            {
                if (minorClassIDList.Count > 0)
                {
                    UnitOfWork.Delete<CF_ClassminorStudent>(x => minorClassIDList.Contains(x.ClassminorID));
                    UnitOfWork.Delete<CF_Classminor>(x => minorClassIDList.Contains(x.ClassminorID));
                }
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
        }

        public IGridResultSet<StudentsView> GetStudentsByMinorClassID(Guid minorClassID)
        {
            Expression<Func<CF_ClassminorStudent, bool>> exp = x => x.ClassminorID == minorClassID;
            var query = minorClassDAL.GetStudentsQueryable(exp);

            return query.OrderBy(x => x.LoginID).ToGridResultSet<StudentsView>();
        }

        public void OpenClassMinor(List<Guid?> minorClassIDList)
        {
            try
            {
                var classminorList = minorClassDAL.classminorRepository.GetList(x => minorClassIDList.Contains(x.ClassminorID));
                foreach (var classMinor in classminorList)
                {
                    if (classMinor.RecordStatus != (int)CF_ClassminorStatus.NotOpen)
                    {
                        throw new Exception("只能对未开班的数据进行开班");
                    }
                    classMinor.RecordStatus = (int)CF_ClassminorStatus.Open;
                }
                UnitOfWork.Commit();
            }
            catch (Exception)
            {
                
                throw;
            }
        }

        public void CancelOpenClassMinor(List<Guid?> minorClassIDList)
        {
            try
            {
                var classminorList = minorClassDAL.classminorRepository.GetList(x => minorClassIDList.Contains(x.ClassminorID));
                foreach (var classMinor in classminorList)
                {
                    if (classMinor.RecordStatus != (int)CF_ClassminorStatus.Open)
                    {
                        throw new Exception("只能对已开班的数据进行开班");
                    }
                    classMinor.RecordStatus = (int)CF_ClassminorStatus.Cancel;
                }
                UnitOfWork.Commit();
            }
            catch (Exception)
            {

                throw;
            }
        }


    }
}