using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;
using EMIS.CommonLogic.AdministrativeOrgan;
using EMIS.CommonLogic.SystemServices;
using EMIS.DataLogic.DataCenterSynch;
using EMIS.Entities;
using EMIS.ViewModel;

namespace EMIS.CommonLogic.DataCenterSynch
{
    public class CollegeSynchServices : DepartmentServices, ICollegeSynchServices
    {
        public Lazy<IParameterServices> ParameterServices { get; set; }
        public CollegeSynchDAL CollegeSynchrDAL { get; set; }

        public void Synchr()
        {
            var lastSynchTime = ParameterServices.Value.GetParameterValue<DateTime>(CF_ParameterType.SynchCollegeLastTime);
            var nowTime = DateTime.Now;
            var allCollegeList = CollegeSynchrDAL.XXBZ_JWXT_YXXX_VIEWRepository.GetList(x => x.TIMESTAMPS >= lastSynchTime || lastSynchTime == null).ToList();
            var allCollegeNoList = allCollegeList.Select(x => x.USER_DM.Trim()).Distinct().ToList();
            var dbCollegeList = this.DepartmentDAL.CollegeRepository.GetList(x => allCollegeNoList.Contains(x.No), (x => x.CF_CollegeProfile)).ToList();
            var dbDepartmentList = this.DepartmentDAL.DepartmentRepository.GetList(x => allCollegeNoList.Contains(x.No), (x => x.CF_DepartmentProfile)).ToList();

            var insertCollegeMainList = (from all in allCollegeList
                              from db in dbCollegeList.Where(x => x.No == all.DM.Trim()).DefaultIfEmpty()
                              where db == null
                              select new { College = all, CollegeID = Guid.NewGuid() }).ToList();
            var insertCollegeList = insertCollegeMainList.Select(x => new CF_College
            {
                CollegeID = x.CollegeID,
                No = x.College.USER_DM.Trim(),
                Name = x.College.ZWMC,
                SimpleName = null,
                EnglishName = x.College.YWMC,
                RecordStatus = (int)SYS_STATUS.USABLE,
                CreateTime = nowTime,
                ModifyTime = nowTime
            }).ToList();
            var insertCollegeProfileList = insertCollegeMainList.Select(x => new CF_CollegeProfile
            {
                CollegeID = x.CollegeID,
                UnitCategoryID = (x.College.MENG_FLAG == "0") ? (int?)CF_UnitCategory.College : null,
                RecordStatus = (int)SYS_STATUS.USABLE,
                CreateTime = nowTime,
                ModifyTime = nowTime
            }).ToList();
            var insertDepartmentMainList = (from all in allCollegeList 
                                            from college in dbCollegeList.Where(x => x.No == all.USER_DM.Trim()).DefaultIfEmpty() 
                                            from insert in insertCollegeList.Where(x => x.No == all.USER_DM.Trim()).DefaultIfEmpty()  
                                            from db in dbDepartmentList.Where(x => x.No == all.USER_DM.Trim()).DefaultIfEmpty()
                                            where db == null
                                            select new { College = all, CollegeID = college == null ? insert.CollegeID : college.CollegeID, DepartmentID = Guid.NewGuid() }).ToList();
            var insertDepartmentList = insertDepartmentMainList.Select(x => new CF_Department
            {
                DepartmentID = x.DepartmentID,
                CollegeID = x.CollegeID,
                No = x.College.USER_DM.Trim(),
                Name = x.College.ZWMC,
                SimpleName = null,
                EnglishName = x.College.YWMC,
                RecordStatus = (int)SYS_STATUS.USABLE,
                CreateTime = nowTime,
                ModifyTime = nowTime
            }).ToList();
            var insertDepartmentProfileList = insertDepartmentMainList.Select(x => new CF_DepartmentProfile
            {
                DepartmentID = x.DepartmentID,
                RecordStatus = (int)SYS_STATUS.USABLE,
                CreateTime = nowTime,
                ModifyTime = nowTime
            }).ToList();

            var updateMainList = (from all in allCollegeList
                                     from db in dbCollegeList.Where(x => x.No == all.USER_DM.Trim())
                                     select new { College = all, DbCollege = db, DbCollegeProfile = db.CF_CollegeProfile });
            var updateCollegeList = updateMainList.Select(x => new CF_College
            {
                CollegeID = x.DbCollege.CollegeID,
                CampusID = x.DbCollege.CampusID,
                No = x.DbCollege.No,
                Name = x.College.ZWMC,
                SimpleName = x.DbCollege.SimpleName,
                EnglishName = x.College.YWMC,
                Remark = x.DbCollege.Remark,
                RecordStatus = x.DbCollege.RecordStatus,
                CreateUserID = x.DbCollege.CreateUserID,
                CreateTime = x.DbCollege.CreateTime,
                ModifyUserID = x.DbCollege.ModifyUserID,
                ModifyTime = nowTime
            }).ToList();
            var updateCollegeProfileList = updateMainList.Select(x => new CF_CollegeProfile
            {
                CollegeID = x.DbCollegeProfile.CollegeID,
                PoliticalManager = x.DbCollegeProfile.PoliticalManager,
                AdministrativeManager = x.DbCollegeProfile.AdministrativeManager,
                UnitCategoryID = (x.College.MENG_FLAG == "0") ? (int?)CF_UnitCategory.College : null,
                CollegeTypeID = x.DbCollegeProfile.CollegeTypeID,
                CollegeCategoryID = x.DbCollegeProfile.CollegeCategoryID,
                RunByCategoryID = x.DbCollegeProfile.RunByCategoryID,
                FoundDate = x.DbCollegeProfile.FoundDate,
                Officephone = x.DbCollegeProfile.Officephone,
                RecordStatus = x.DbCollegeProfile.RecordStatus,
                CreateUserID = x.DbCollegeProfile.CreateUserID,
                CreateTime = x.DbCollegeProfile.CreateTime,
                ModifyUserID = x.DbCollegeProfile.ModifyUserID,
                ModifyTime = nowTime
            }).ToList();
            var updateDepartmentMainList = (from all in allCollegeList
                                            from college in dbCollegeList.Where(x => x.No == all.USER_DM.Trim()).DefaultIfEmpty()
                                            from insert in insertCollegeList.Where(x => x.No == all.USER_DM.Trim()).DefaultIfEmpty()
                                            from db in dbDepartmentList.Where(x => x.No == all.USER_DM.Trim()) 
                                            select new { College = all, CollegeID = college == null ? insert.CollegeID : college.CollegeID, DbDepartment = db, DbDepartmentProfile = db.CF_DepartmentProfile });
            var updateDepartmentList = updateDepartmentMainList.Select(x => new CF_Department
            {
                DepartmentID = x.DbDepartment.DepartmentID,
                CollegeID = x.CollegeID,
                No = x.DbDepartment.No,
                Name = x.College.ZWMC,
                SimpleName = x.DbDepartment.SimpleName,
                EnglishName = x.College.YWMC,
                HierarchyID = x.DbDepartment.HierarchyID,
                Remark = x.DbDepartment.Remark,
                RecordStatus = x.DbDepartment.RecordStatus,
                CreateUserID = x.DbDepartment.CreateUserID,
                CreateTime = x.DbDepartment.CreateTime,
                ModifyUserID = x.DbDepartment.ModifyUserID,
                ModifyTime = nowTime
            }).ToList();
            var updateDepartmentProfileList = updateDepartmentMainList.Select(x => new CF_DepartmentProfile
            {
                DepartmentID = x.DbDepartmentProfile.DepartmentID,
                DirectorID = x.DbDepartmentProfile.DirectorID,
                DeputyDirectorID = x.DbDepartmentProfile.DeputyDirectorID,
                FoundDate = x.DbDepartmentProfile.FoundDate,
                RecordStatus = x.DbDepartmentProfile.RecordStatus,
                CreateUserID = x.DbDepartmentProfile.CreateUserID,
                CreateTime = x.DbDepartmentProfile.CreateTime,
                ModifyUserID = x.DbDepartmentProfile.ModifyUserID,
                ModifyTime = nowTime
            }).ToList();

            using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions { IsolationLevel = IsolationLevel.Serializable }))
            {
                UnitOfWork.BulkInsert(insertCollegeList);
                UnitOfWork.BulkInsert(insertCollegeProfileList);
                UnitOfWork.BulkInsert(insertDepartmentList);
                UnitOfWork.BulkInsert(insertDepartmentProfileList);
                UnitOfWork.BatchUpdate(updateCollegeList);
                UnitOfWork.BatchUpdate(updateCollegeProfileList);
                UnitOfWork.BatchUpdate(updateDepartmentList);
                UnitOfWork.BatchUpdate(updateDepartmentProfileList);

                scope.Complete();
            }

            ParameterServices.Value.SaveTo(CF_ParameterType.SynchCollegeLastTime, nowTime);
        }
    }
}