using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Transactions;
using Bowin.Common.Linq;
using Bowin.Common.Linq.Entity;
using EMIS.Entities;
using EMIS.ViewModel;
using EMIS.ViewModel.StudentManage.OnlineChecking;
using EMIS.DataLogic.StudentManage.OnlineChecking;
using EMIS.CommonLogic.SystemServices;

namespace EMIS.CommonLogic.StudentWeb.InfoCenter
{
    public class CheckingResultServices : BaseWorkflowServices<CF_StudentContrast>, ICheckingResultServices
    {
        public Lazy<CheckingCollectDAL> CheckingCollectDAL { get; set; }

        /// <summary>
        /// 查询对应的校对结果信息CheckingHistoryView
        /// </summary>
        /// <param name="configuretView"></param>
        /// <param name="userID"></param>
        /// <param name="checkingTypeID"></param>
        /// <param name="approvalStatus"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IGridResultSet<CheckingHistoryView> GetStudentCheckingResultViewGrid(ConfiguretView configuretView, Guid? userID, int? checkingTypeID, int? approvalStatus, int pageIndex, int pageSize)
        {
            var approveStatusList = this.GetStatusViewList();
            var startStatusID = this.GetStartStatus();
            Expression<Func<CF_StudentRecordChangeHistory, bool>> expStudentRecordChangeHistory = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            if (checkingTypeID.HasValue)
            {
                expStudentRecordChangeHistory = expStudentRecordChangeHistory.And(x => x.CheckingTypeID == checkingTypeID);
            }
            Expression<Func<CF_StudentContrast, bool>> expStudentContrast = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            expStudentContrast = expStudentContrast.And(x => x.UserID == userID);
            expStudentContrast = expStudentContrast.And(x => x.ApprovalStatus != startStatusID);
            if (approvalStatus.HasValue)
            {
                expStudentContrast = expStudentContrast.And(x => x.ApprovalStatus == approvalStatus);
            }
            Expression<Func<CF_Student, bool>> expStudent = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            expStudent = expStudent.And(x => x.UserID == userID);
            var query = CheckingCollectDAL.Value.GetCheckingHistoryViewQueryable(expStudentRecordChangeHistory, expStudentContrast, expStudent);
            
            if (!string.IsNullOrEmpty(configuretView.ConditionValue))
            {
                query = query.DynamicWhere(configuretView.Attribute, configuretView.Condition, configuretView.ConditionValue.Trim());
            }
            var result = query.OrderBy(x => x.ColumnName).OrderByDescending(x => x.ApprovalTime).ToGridResultSet<CheckingHistoryView>(pageIndex, pageSize);
            result.rows.ForEach(x => x.ApprovalStatusName = approveStatusList.FirstOrDefault(w => w.ID == x.ApprovalStatus).Name);
            return result;
        }

        /// <summary>
        /// 查询对应的校对结果信息List
        /// </summary>
        /// <param name="configuretView"></param>
        /// <param name="userID"></param>
        /// <param name="checkingTypeID"></param>
        /// <param name="approvalStatus"></param>
        /// <returns></returns>
        public IList<CheckingHistoryView> GetStudentCheckingResultViewList(ConfiguretView configuretView, Guid? userID, int? checkingTypeID, int? approvalStatus)
        {
            var approveStatusList = this.GetStatusViewList();
            var startStatusID = this.GetStartStatus();
            Expression<Func<CF_StudentRecordChangeHistory, bool>> expStudentRecordChangeHistory = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            if (checkingTypeID.HasValue)
            {
                expStudentRecordChangeHistory = expStudentRecordChangeHistory.And(x => x.CheckingTypeID == checkingTypeID);
            }
            Expression<Func<CF_StudentContrast, bool>> expStudentContrast = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            expStudentContrast = expStudentContrast.And(x => x.UserID == userID);
            expStudentContrast = expStudentContrast.And(x => x.ApprovalStatus != startStatusID);
            if (approvalStatus.HasValue)
            {
                expStudentContrast = expStudentContrast.And(x => x.ApprovalStatus == approvalStatus);
            }
            Expression<Func<CF_Student, bool>> expStudent = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            expStudent = expStudent.And(x => x.UserID == userID);
            var query = CheckingCollectDAL.Value.GetCheckingHistoryViewQueryable(expStudentRecordChangeHistory, expStudentContrast, expStudent);

            if (!string.IsNullOrEmpty(configuretView.ConditionValue))
            {
                query = query.DynamicWhere(configuretView.Attribute, configuretView.Condition, configuretView.ConditionValue.Trim());
            }
            var result = query.OrderBy(x => x.ColumnName).OrderByDescending(x => x.ApprovalTime).ToList();
            result.ForEach(x => x.ApprovalStatusName = approveStatusList.FirstOrDefault(w => w.ID == x.ApprovalStatus).Name);
            return result;
        }

        /// <summary>
        /// 查询对应的校对结果信息CheckingHistoryView
        /// </summary>
        /// <param name="studentRecordChangeHistoryID"></param>
        /// <returns></returns>
        public CheckingHistoryView GetStudentCheckingResultView(Guid? studentRecordChangeHistoryID)
        {
            try
            {
                Expression<Func<CF_StudentRecordChangeHistory, bool>> exp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
                exp = exp.And(x => x.StudentRecordChangeHistoryID == studentRecordChangeHistoryID);
                var query = CheckingCollectDAL.Value.GetCheckingHistoryViewQueryable(exp).SingleOrDefault();
                return query;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 撤消
        /// </summary>
        /// <param name="studentRecordChangeHistoryIDs"></param>
        /// <param name="userID"></param>
        /// <returns></returns>
        public bool StudentCheckingResultCancel(List<Guid?> studentRecordChangeHistoryIDs, Guid userID)
        {
            try
            {
                var checkingHistoryViewList = CheckingCollectDAL.Value.GetCheckingHistoryViewQueryable(x => studentRecordChangeHistoryIDs.Contains(x.StudentRecordChangeHistoryID)).ToList();
                var studentContrastIDList = checkingHistoryViewList.Select(x => x.StudentContrastID).Distinct().ToList();
                var studentRecordChangeHistoryList = CheckingCollectDAL.Value.StudentRecordChangeHistoryRepository.GetList(x => studentContrastIDList.Contains(x.StudentContrastID)).ToList();
                var studentCstList = CheckingCollectDAL.Value.StudentContrastRepository.GetList(x => studentContrastIDList.Contains(x.StudentContrastID), (x => x.CF_StudentProfileContrast), (x => x.CF_StudentContactContrast), (x => x.CF_StudentAccountContrast), (x => x.CF_RecruitstudentsContrast), (x => x.Sys_UserContrast)).ToList();
                bool isUserCst = false;
                bool isStudentCst = false;
                bool isStuProfileCst = false;
                bool isStuContactCst = false;
                bool isStuAccountCst = false;
                bool isStuRecruitCst = false;
                List<Guid> studentContrastIDCalList = new List<Guid>();
                List<Sys_UserContrast> userCstUpList = new List<Sys_UserContrast>();
                List<CF_StudentContrast> studentCstUpList = new List<CF_StudentContrast>();
                List<CF_StudentProfileContrast> studentProfileCstUpList = new List<CF_StudentProfileContrast>();
                List<CF_StudentContactContrast> studentContactCstUpList = new List<CF_StudentContactContrast>();
                List<CF_StudentAccountContrast> studentAccountCstUpList = new List<CF_StudentAccountContrast>();
                List<CF_RecruitstudentsContrast> recruitstudentsCstUpList = new List<CF_RecruitstudentsContrast>();
                var checkingHistoryViewGroupByDictionary = checkingHistoryViewList.GroupBy(x => x.StudentContrastID).ToDictionary(x => x.Key.Value, x => x.DefaultIfEmpty());
                foreach (var checkingHistoryViewGroupBy in checkingHistoryViewGroupByDictionary)
                {
                    if (!studentContrastIDCalList.Any(x => x == checkingHistoryViewGroupBy.Key))
                    {
                        var stuHisList = studentRecordChangeHistoryList.Where(x => x.StudentContrastID == checkingHistoryViewGroupBy.Key && !studentRecordChangeHistoryIDs.Contains(x.StudentRecordChangeHistoryID)).ToList();
                        if (stuHisList != null && stuHisList.Count() > 0)
                        {
                            isUserCst = false;
                            isStudentCst = false;
                            isStuProfileCst = false;
                            isStuContactCst = false;
                            isStuAccountCst = false;
                            isStuRecruitCst = false;
                            var studentCst = studentCstList.Where(x => x.StudentContrastID == checkingHistoryViewGroupBy.Key).SingleOrDefault();
                            foreach (var checkingHistoryView in checkingHistoryViewGroupBy.Value)
                            {
                                var userCstProperty = typeof(Sys_UserContrast).GetProperties().Where(x => x.Name.ToLower() == checkingHistoryView.ColumnName.ToLower()).SingleOrDefault();
                                if (userCstProperty != null)
                                {
                                    userCstProperty.SetValue(studentCst.Sys_UserContrast, checkingHistoryView.CheckingBeforeValue, null);
                                    isUserCst = true;
                                }
                                var studentCstProperty = typeof(CF_StudentContrast).GetProperties().Where(x => x.Name.ToLower() == checkingHistoryView.ColumnName.ToLower()).SingleOrDefault();
                                if (studentCstProperty != null)
                                {
                                    studentCstProperty.SetValue(studentCst, checkingHistoryView.CheckingBeforeValue, null);
                                    isStudentCst = true;
                                }
                                var studentProfileCstProperty = typeof(CF_StudentProfileContrast).GetProperties().Where(x => x.Name.ToLower() == checkingHistoryView.ColumnName.ToLower()).SingleOrDefault();
                                if (studentProfileCstProperty != null)
                                {
                                    studentProfileCstProperty.SetValue(studentCst.CF_StudentProfileContrast, checkingHistoryView.CheckingBeforeValue, null);
                                    isStuProfileCst = true;
                                }
                                var studentContactCstProperty = typeof(CF_StudentContactContrast).GetProperties().Where(x => x.Name.ToLower() == checkingHistoryView.ColumnName.ToLower()).SingleOrDefault();
                                if (studentContactCstProperty != null)
                                {
                                    studentContactCstProperty.SetValue(studentCst.CF_StudentContactContrast, checkingHistoryView.CheckingBeforeValue, null);
                                    isStuContactCst = true;
                                }
                                var studentAccountCstProperty = typeof(CF_StudentAccountContrast).GetProperties().Where(x => x.Name.ToLower() == checkingHistoryView.ColumnName.ToLower()).SingleOrDefault();
                                if (studentAccountCstProperty != null)
                                {
                                    studentAccountCstProperty.SetValue(studentCst.CF_StudentAccountContrast, checkingHistoryView.CheckingBeforeValue, null);
                                    isStuAccountCst = true;
                                }
                                var recruitstudentsCstProperty = typeof(CF_RecruitstudentsContrast).GetProperties().Where(x => x.Name.ToLower() == checkingHistoryView.ColumnName.ToLower()).SingleOrDefault();
                                if (recruitstudentsCstProperty != null)
                                {
                                    recruitstudentsCstProperty.SetValue(studentCst.CF_RecruitstudentsContrast, checkingHistoryView.CheckingBeforeValue, null);
                                    isStuRecruitCst = true;
                                }
                            }
                            if (isUserCst)
                            {
                                studentCst.Sys_UserContrast.ModifyUserID = userID;
                                studentCst.Sys_UserContrast.ModifyTime = DateTime.Now;
                                userCstUpList.Add(studentCst.Sys_UserContrast);
                            }
                            if (isStudentCst)
                            {
                                studentCst.ModifyUserID = userID;
                                studentCst.ModifyTime = DateTime.Now;
                                studentCstUpList.Add(studentCst);
                            }
                            if (isStuProfileCst)
                            {
                                studentCst.CF_StudentProfileContrast.ModifyUserID = userID;
                                studentCst.CF_StudentProfileContrast.ModifyTime = DateTime.Now;
                                studentProfileCstUpList.Add(studentCst.CF_StudentProfileContrast);
                            }
                            if (isStuContactCst)
                            {
                                studentCst.CF_StudentContactContrast.ModifyUserID = userID;
                                studentCst.CF_StudentContactContrast.ModifyTime = DateTime.Now;
                                studentContactCstUpList.Add(studentCst.CF_StudentContactContrast);
                            }
                            if (isStuAccountCst)
                            {
                                studentCst.CF_StudentAccountContrast.ModifyUserID = userID;
                                studentCst.CF_StudentAccountContrast.ModifyTime = DateTime.Now;
                                studentAccountCstUpList.Add(studentCst.CF_StudentAccountContrast);
                            }
                            if (isStuRecruitCst)
                            {
                                studentCst.CF_RecruitstudentsContrast.ModifyUserID = userID;
                                studentCst.CF_RecruitstudentsContrast.ModifyTime = DateTime.Now;
                                recruitstudentsCstUpList.Add(studentCst.CF_RecruitstudentsContrast);
                            }
                        }
                        else
                        {
                            studentContrastIDCalList.Add(checkingHistoryViewGroupBy.Key);
                        }
                    }
                }
                TransactionOptions transactionOption = new TransactionOptions();
                transactionOption.IsolationLevel = System.Transactions.IsolationLevel.Serializable;
                transactionOption.Timeout = new TimeSpan(0, 3, 0);
                using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, transactionOption))
                {
                    if (userCstUpList != null && userCstUpList.Count() > 0)
                    {
                        UnitOfWork.BatchUpdate(userCstUpList);
                    }
                    if (studentCstUpList != null && studentCstUpList.Count() > 0)
                    {
                        UnitOfWork.BatchUpdate(studentCstUpList);
                    }
                    if (studentProfileCstUpList != null && studentProfileCstUpList.Count() > 0)
                    {
                        UnitOfWork.BatchUpdate(studentProfileCstUpList);
                    }
                    if (studentContactCstUpList != null && studentContactCstUpList.Count() > 0)
                    {
                        UnitOfWork.BatchUpdate(studentContactCstUpList);
                    }
                    if (studentAccountCstUpList != null && studentAccountCstUpList.Count() > 0)
                    {
                        UnitOfWork.BatchUpdate(studentAccountCstUpList);
                    }
                    if (recruitstudentsCstUpList != null && recruitstudentsCstUpList.Count() > 0)
                    {
                        UnitOfWork.BatchUpdate(recruitstudentsCstUpList);
                    }
                    UnitOfWork.Delete<CF_StudentRecordChangeHistory>(x => studentRecordChangeHistoryIDs.Contains(x.StudentRecordChangeHistoryID));
                    UnitOfWork.Delete<CF_RecruitstudentsSource>(x => studentContrastIDCalList.Contains(x.StudentContrastID));
                    UnitOfWork.Delete<CF_RecruitstudentsContrast>(x => studentContrastIDCalList.Contains(x.StudentContrastID));
                    UnitOfWork.Delete<CF_StudentAccountSource>(x => studentContrastIDCalList.Contains(x.StudentContrastID));
                    UnitOfWork.Delete<CF_StudentAccountContrast>(x => studentContrastIDCalList.Contains(x.StudentContrastID));
                    UnitOfWork.Delete<CF_StudentContactSource>(x => studentContrastIDCalList.Contains(x.StudentContrastID));
                    UnitOfWork.Delete<CF_StudentContactContrast>(x => studentContrastIDCalList.Contains(x.StudentContrastID));
                    UnitOfWork.Delete<CF_StudentProfileSource>(x => studentContrastIDCalList.Contains(x.StudentContrastID));
                    UnitOfWork.Delete<CF_StudentProfileContrast>(x => studentContrastIDCalList.Contains(x.StudentContrastID));
                    UnitOfWork.Delete<Sys_UserSource>(x => studentContrastIDCalList.Contains(x.StudentContrastID));
                    UnitOfWork.Delete<Sys_UserContrast>(x => studentContrastIDCalList.Contains(x.StudentContrastID));
                    UnitOfWork.Delete<CF_StudentSource>(x => studentContrastIDCalList.Contains(x.StudentContrastID));
                    UnitOfWork.Delete<CF_StudentContrast>(x => studentContrastIDCalList.Contains(x.StudentContrastID));
                    ts.Complete();
                }
                return true;
            }
            catch (Exception)
            {
                throw;
            }
        }

    }
}