using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
namespace BLL
{
    public static class GetDataService
    {      
        #region 培训计划提交后 按照培训任务 生成培训人员的培训教材明细
        /// 
        /// 生成培训人员的培训教材明细
        /// 
        /// 
        public static void CreateTrainingTaskItemByTaskId(string taskId)
        {
            using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
            {
                try
                {
                    /////查找未生成教材明细的 培训任务
                    var getTasks = from x in db.Training_Task
                                   where x.States == Const.State_0 && (x.TaskId == taskId || taskId == null)
                                   select x;
                    if (getTasks.Count() > 0)
                    {
                        foreach (var item in getTasks)
                        {
                            var getPerson = db.SitePerson_Person.FirstOrDefault(e => e.PersonId == item.UserId);
                            if (getPerson != null)
                            {
                                ////获取计划下 人员培训教材明细
                                var getDataList = db.Sp_GetTraining_TaskItemTraining(item.PlanId, getPerson.WorkPostId);
                                foreach (var dataItem in getDataList)
                                {
                                    Model.Training_TaskItem newTaskItem = new Model.Training_TaskItem
                                    {
                                        TaskId = item.TaskId,
                                        PlanId = item.PlanId,
                                        PersonId = item.UserId,
                                        TrainingItemCode = dataItem.TrainingItemCode,
                                        TrainingItemName = dataItem.TrainingItemName,
                                        AttachUrl = dataItem.AttachUrl,
                                    };
                                    var getTaskItem = db.Training_TaskItem.FirstOrDefault(x => x.TaskId == item.TaskId && x.TrainingItemName == newTaskItem.TrainingItemName && x.AttachUrl == newTaskItem.AttachUrl);
                                    if (getTaskItem == null)
                                    {
                                        newTaskItem.TaskItemId = SQLHelper.GetNewID();
                                        db.Training_TaskItem.InsertOnSubmit(newTaskItem);
                                        db.SubmitChanges();
                                    }
                                }
                            }
                            ////更新培训任务
                            item.States = Const.State_1;
                            db.SubmitChanges();
                        }
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }
        #endregion
        #region 自动结束考试
        /// 
        ///  自动结束考试
        /// 
        public static void UpdateTestPlanStates()
        {
            using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
            {
                try
                {
                    var getTestPlans = from x in db.Training_TestPlan
                                       where x.States == Const.State_2 && x.TestEndTime.AddMinutes(x.Duration) < DateTime.Now
                                       select x;
                    if (getTestPlans.Count() > 0)
                    {
                        foreach (var item in getTestPlans)
                        {
                            APITestPlanService.SubmitTest(item);
                            item.States = "3";
                            db.SubmitChanges();
                        }
                    }
                    var getTrainingTestRecords = from x in db.Training_TestRecord
                                                 where x.TestStartTime.Value.AddMinutes(x.Duration) < DateTime.Now
                                                 && (!x.TestEndTime.HasValue || !x.TestScores.HasValue)
                                                 select x;
                    foreach (var itemRecord in getTrainingTestRecords)
                    {
                        itemRecord.TestEndTime = itemRecord.TestStartTime.Value.AddMinutes(itemRecord.Duration);
                        itemRecord.TestScores = db.Training_TestRecordItem.Where(x => x.TestRecordId == itemRecord.TestRecordId).Sum(x => x.SubjectScore) ?? 0;
                        TestRecordService.UpdateTestRecord(itemRecord);
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }
        #endregion
        #region 自动结束考试-知识竞赛
        /// 
        ///  自动结束考试
        /// 
        public static void UpdateServerTestPlanStates()
        {
            using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
            {
                try
                {
                    var getTrainingTestRecords = from x in db.Test_TestRecord
                                                 where x.TestStartTime.Value.AddMinutes(x.Duration.Value) < DateTime.Now
                                                 && (!x.TestEndTime.HasValue || !x.TestScores.HasValue)
                                                 select x;
                    foreach (var itemRecord in getTrainingTestRecords)
                    {
                        itemRecord.TestEndTime = itemRecord.TestStartTime.Value.AddMinutes(itemRecord.Duration.Value);
                        itemRecord.TestScores = db.Test_TestRecordItem.Where(x => x.TestRecordId == itemRecord.TestRecordId).Sum(x => x.SubjectScore) ?? 0;
                        db.SubmitChanges();
                    }
                }
                catch (Exception ex)
                { }
            }
        }
        #endregion
        #region 自动校正出入场人数及工时
        /// 
        ///  自动校正出入场人数及工时
        /// 
        public static void CorrectingPersonInOutNumber(string projectId)
        {
            using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
            {
                try
                {
                    var getProjects = (from x in db.Base_Project
                                       where x.ProjectState == null || x.ProjectState == Const.ProjectState_1
                                       orderby x.ProjectCode descending
                                       select x).ToList();
                    if (!string.IsNullOrEmpty(projectId))
                    {
                        getProjects = getProjects.Where(x => x.ProjectId == projectId).ToList();
                    }
                    foreach (var projectItem in getProjects)
                    {
                        var getAllPersonInOutList = from x in db.SitePerson_PersonInOut
                                                    where x.ProjectId == projectItem.ProjectId && x.ChangeTime <= DateTime.Now
                                                    select x;
                        if (getAllPersonInOutList.Count() > 0)
                        {
                            #region 现场当前人员数
                            int SitePersonNum = 0;
                            var getDayAll = from x in db.SitePerson_PersonInOutNow
                                            where x.ChangeTime.Value.Year == DateTime.Now.Year && x.ChangeTime.Value.Month == DateTime.Now.Month
                                            && x.ChangeTime.Value.Day == DateTime.Now.Day
                                            select x;
                            if (getDayAll.Count() > 0)
                            {
                                var getInMaxs = from x in getDayAll
                                                group x by x.PersonId into g
                                                select new { g.First().PersonId, ChangeTime = g.Max(x => x.ChangeTime) };
                                if (getInMaxs.Count() > 0)
                                {
                                    SitePersonNum = (from x in getInMaxs
                                                     join y in getDayAll on new { x.PersonId, x.ChangeTime } equals new { y.PersonId, y.ChangeTime }
                                                     where y.IsIn == true
                                                     select y).Count();
                                }
                            }
                            #endregion
                            #region 获取工时                  
                            int SafeHours = 0;
                            var getPersonOutTimes = from x in getAllPersonInOutList
                                                    where x.IsIn == false
                                                    select x;
                            var getInLists = getAllPersonInOutList.Where(x => x.IsIn == true);
                            //// 查找当前项目 最新的人工时数量记录
                            var getMaxInOutDate = db.SitePerson_PersonInOutNumber.Where(x => x.ProjectId == projectItem.ProjectId).OrderByDescending(x => x.InOutDate).FirstOrDefault();
                            if (getMaxInOutDate != null)
                            {
                                SafeHours = (getMaxInOutDate.WorkHours ?? 0) * 60;
                                getPersonOutTimes = from x in getPersonOutTimes
                                                    where x.ChangeTime > getMaxInOutDate.InOutDate
                                                    select x;
                                if (getPersonOutTimes.Count() > 0)
                                {
                                    getInLists = from x in getInLists
                                                 where x.ChangeTime > getMaxInOutDate.InOutDate
                                                 select x;
                                }
                            }
                            if (getPersonOutTimes.Count() > 0)
                            {
                                List personIdList = new List();
                                foreach (var item in getPersonOutTimes)
                                {
                                    var getMaxInTime = getInLists.Where(x => x.ChangeTime < item.ChangeTime
                                                && x.PersonId == item.PersonId && x.ChangeTime.Value.AddDays(1) >= item.ChangeTime).Max(x => x.ChangeTime);
                                    if (getMaxInTime.HasValue)
                                    {
                                        SafeHours += Convert.ToInt32((item.ChangeTime - getMaxInTime).Value.TotalMinutes);
                                    }
                                    else
                                    {
                                        personIdList.Add(item.PersonId);
                                    }
                                }
                                if (personIdList.Count() > 0)
                                {
                                    SafeHours += (personIdList.Distinct().Count() * 8 * 60);
                                }
                            }
                            #endregion
                            SafeHours = Convert.ToInt32(SafeHours * 1.0 / 60);
                            var getPersonInOutNumber = db.SitePerson_PersonInOutNumber.FirstOrDefault(x => x.ProjectId == projectItem.ProjectId
                                                                                && x.InOutDate.Year == DateTime.Now.Year
                                                                                && x.InOutDate.Month == DateTime.Now.Month
                                                                                && x.InOutDate.Day == DateTime.Now.Day);
                            if (getPersonInOutNumber == null)
                            {
                                Model.SitePerson_PersonInOutNumber newNum = new Model.SitePerson_PersonInOutNumber
                                {
                                    PersonInOutNumberId = SQLHelper.GetNewID(),
                                    ProjectId = projectItem.ProjectId,
                                    InOutDate = DateTime.Now,
                                    PersonNum = SitePersonNum,
                                    WorkHours = SafeHours,
                                };
                                db.SitePerson_PersonInOutNumber.InsertOnSubmit(newNum);
                                db.SubmitChanges();
                            }
                            else
                            {
                                getPersonInOutNumber.InOutDate = DateTime.Now;
                                getPersonInOutNumber.PersonNum = SitePersonNum;
                                getPersonInOutNumber.WorkHours = SafeHours;
                                db.SubmitChanges();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }
        #endregion
        #region 自动校正出入场人数及工时
        /// 
        ///  自动校正出入场人数及工时
        /// 
        public static void CorrectingPersonInOutNumberD(string projectId)
        {
            using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
            {
                try
                {
                    DateTime dateS = DateTime.Now.AddMonths(-12);
                    dateS = Funs.GetNewDateTimeOrNow(DateTime.Now.AddMonths(-12).Year + "-" + DateTime.Now.AddMonths(-12).Month + "-01");
                    var getNums = from x in db.SitePerson_PersonInOutNumber
                                  where x.ProjectId == projectId  && x.InOutDate >= dateS
                                  orderby x.InOutDate
                                  select x;                    
                    var getInouts = from x in db.SitePerson_PersonInOut
                                    where x.ProjectId == projectId && x.ChangeTime.Value >= dateS
                                    select x;
                    //int SafeHours = 0;
                    int SafeHours = db.SitePerson_PersonInOutNumber.Where(x => x.ProjectId == projectId && x.InOutDate < dateS).Max(x => x.WorkHours) ?? 0;
                    foreach (var itemNum in getNums)
                    {
                        DateTime date = Funs.GetNewDateTimeOrNow(itemNum.InOutDate.ToShortDateString());                      
                        ///获取当日出入记录
                        var getAllPersonInOutList = from x in getInouts
                                                    where x.ChangeTime > date.AddDays(-1) && x.ChangeTime < date.AddDays(1)
                                                    select x;
                        if (getAllPersonInOutList.Count() > 0)
                        {
                            /// 出场记录
                            var getPersonOutTimes = getAllPersonInOutList.Where(x => x.IsIn == false);
                            var getInLists = getAllPersonInOutList.Where(x => x.IsIn == true);
                            //// 查找当前项目 最新的人工时数量记录
                            if (SafeHours == 0)
                            {
                                var getMaxInOutDate = getNums.Where(x => x.InOutDate < date).OrderByDescending(x => x.InOutDate).FirstOrDefault();
                                if (getMaxInOutDate != null)
                                {
                                    SafeHours = getMaxInOutDate.WorkHours ?? 0;
                                }
                                else
                                {
                                    SafeHours = db.SitePerson_PersonInOutNumber.Where(x => x.ProjectId == projectId && x.InOutDate < dateS).Max(x => x.WorkHours) ?? 0;
                                }
                            }
                            int getOutPersonCount = getPersonOutTimes.Select(x => x.PersonId).Distinct().Count();
                            SafeHours += getOutPersonCount * 8;
                        }
                        //SafeHours = Convert.ToInt32(SafeHours * 1.0 / 60);
                        if (itemNum != null)
                        {
                            itemNum.InOutDate = date;
                            itemNum.WorkHours = SafeHours;
                            db.SubmitChanges();
                        }
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }
        #endregion
        #region 自动批量生成人员二维码
        /// 
        ///  自动批量生成人员二维码
        /// 
        public static void CreateQRCode()
        {
            using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
            {
                try
                {
                    var getPersons = from x in db.SitePerson_Person
                                     where x.IdentityCard != null && x.QRCodeAttachUrl == null
                                     select x;
                    if (getPersons.Count() > 0)
                    {
                        foreach (var item in getPersons)
                        {
                            string url = CreateQRCodeService.CreateCode_Simple("person$" + item.IdentityCard);
                            if (!string.IsNullOrEmpty(url))
                            {
                                item.QRCodeAttachUrl = url;
                                db.SubmitChanges();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }
        #endregion
        #region 自动 出场人员 自动离场
        /// 
        ///  自动校正出入场人数及工时
        /// 
        public static void SitePersonjAutomaticOut()
        {
            using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
            {
                var getPersons = from x in db.SitePerson_Person
                                 where x.OutTime < DateTime.Now && x.IsUsed == true
                                 select x;
                if (getPersons.Count() > 0)
                {
                    foreach (var item in getPersons)
                    {
                        item.IsUsed = false;
                        item.ExchangeTime2 = null;
                        db.SubmitChanges();
                    }
                }
            }
        }
        #endregion
        #region 定时推送待办 订阅服务内容
        /// 
        /// 定时推送待办 订阅服务内容
        /// 
        public static void SendSubscribeMessage()
        {
            using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
            {
                try
                { 
                    string miniprogram_state = ConfigurationManager.AppSettings["miniprogram_state"];
                    if (!string.IsNullOrEmpty(miniprogram_state) && miniprogram_state == "formal")
                    {
                        //// 获取所有待办事项
                        var getToItems = from x in db.View_APP_GetToDoItems select x;
                        if (getToItems.Count() > 0)
                        {
                            //// 获取施工中的项目
                            var getProjects = ProjectService.GetProjectWorkList();
                            foreach (var item in getProjects)
                            {
                                ////获取当前项目下的待办
                                var getPItems = getToItems.Where(x => x.ProjectId == item.ProjectId);
                                if (getPItems.Count() > 0)
                                {
                                    foreach (var itemP in getPItems)
                                    {
                                        //"项目【" + item.ProjectCode + "】上有" + itemP.Counts.ToString() + "条待办事件,需要您处理!"
                                        APICommonService.SendSubscribeMessage(itemP.UserId, "项目" + item.ProjectCode + "有待办", "施工信息管理", string.Format("{0:yyyy-MM-dd HH:mm:ss}", DateTime.Now));
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                { }
            }
        }
        #endregion
        #region 关闭超期未关闭作业许可
        /// 
        /// 关闭超期未关闭作业许可
        /// 
        public static void CloseLicenseData()
        {
            using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
            {
                try
                {
                    ////动火作业
                    var getFireWorks = from x in db.License_FireWork
                                       where x.States == Const.State_2 && x.ValidityEndTime <= DateTime.Now
                                       select new Model.LicenseDataItem
                                       {
                                           LicenseId = x.FireWorkId,
                                           MenuId = Const.ProjectFireWorkMenuId,
                                           ProjectId = x.ProjectId,
                                           CloseManId = x.ApplyManId,
                                           CloseReasons = "到期自动关闭。",
                                           States = Const.State_3,
                                       };
                    foreach (var itemFire in getFireWorks)
                    {
                        APILicenseDataService.SaveLicenseData(itemFire);
                    }
                    ////高处作业票
                    var getHeightWorks = from x in db.License_HeightWork
                                         where x.States == Const.State_2 && x.ValidityEndTime <= DateTime.Now
                                         select new Model.LicenseDataItem
                                         {
                                             LicenseId = x.HeightWorkId,
                                             MenuId = Const.ProjectHeightWorkMenuId,
                                             ProjectId = x.ProjectId,
                                             CloseManId = x.ApplyManId,
                                             CloseReasons = "到期自动关闭。",
                                             States = Const.State_3,
                                         };
                    foreach (var itemHeightWork in getHeightWorks)
                    {
                        APILicenseDataService.SaveLicenseData(itemHeightWork);
                    }
                    ////受限空间作业票
                    var getLimitedSpaces = from x in db.License_LimitedSpace
                                           where x.States == Const.State_2 && x.ValidityEndTime <= DateTime.Now
                                           select new Model.LicenseDataItem
                                           {
                                               LicenseId = x.LimitedSpaceId,
                                               MenuId = Const.ProjectLimitedSpaceMenuId,
                                               ProjectId = x.ProjectId,
                                               CloseManId = x.ApplyManId,
                                               CloseManName = db.Sys_User.First(u => u.UserId == x.CloseManId).UserName,
                                               CloseReasons = "到期自动关闭。",
                                               CloseTime = string.Format("{0:yyyy-MM-dd HH:mm}", x.ValidityEndTime),
                                               States = Const.State_3,
                                           };
                    foreach (var itemLimitedSpace in getLimitedSpaces)
                    {
                        APILicenseDataService.SaveLicenseData(itemLimitedSpace);
                    }
                    ////射线作业票
                    var getRadialWorks = from x in db.License_RadialWork
                                         where x.States == Const.State_2 && x.ValidityEndTime <= DateTime.Now
                                         select new Model.LicenseDataItem
                                         {
                                             LicenseId = x.RadialWorkId,
                                             MenuId = Const.ProjectRadialWorkMenuId,
                                             ProjectId = x.ProjectId,
                                             CloseManId = x.ApplyManId,
                                             CloseManName = db.Sys_User.First(u => u.UserId == x.CloseManId).UserName,
                                             CloseReasons = "到期自动关闭。",
                                             CloseTime = string.Format("{0:yyyy-MM-dd HH:mm}", x.ValidityEndTime),
                                             States = Const.State_3,
                                         };
                    foreach (var itemRadialWork in getRadialWorks)
                    {
                        APILicenseDataService.SaveLicenseData(itemRadialWork);
                    }
                    ////断路(占道)作业票
                    var getOpenCircuits = from x in db.License_OpenCircuit
                                          where x.States == Const.State_2 && x.ValidityEndTime <= DateTime.Now
                                          select new Model.LicenseDataItem
                                          {
                                              LicenseId = x.OpenCircuitId,
                                              MenuId = Const.ProjectOpenCircuitMenuId,
                                              ProjectId = x.ProjectId,
                                              CloseManId = x.ApplyManId,
                                              CloseManName = db.Sys_User.First(u => u.UserId == x.CloseManId).UserName,
                                              CloseReasons = "到期自动关闭。",
                                              CloseTime = string.Format("{0:yyyy-MM-dd HH:mm}", x.ValidityEndTime),
                                              States = Const.State_3,
                                          };
                    foreach (var itemOpenCircuit in getOpenCircuits)
                    {
                        APILicenseDataService.SaveLicenseData(itemOpenCircuit);
                    }
                    ////动土作业票
                    var getBreakGrounds = from x in db.License_BreakGround
                                          where x.States == Const.State_2 && x.ValidityEndTime <= DateTime.Now
                                          select new Model.LicenseDataItem
                                          {
                                              LicenseId = x.BreakGroundId,
                                              MenuId = Const.ProjectBreakGroundMenuId,
                                              ProjectId = x.ProjectId,
                                              CloseManId = x.ApplyManId,
                                              CloseManName = db.Sys_User.First(u => u.UserId == x.CloseManId).UserName,
                                              CloseReasons = "到期自动关闭。",
                                              CloseTime = string.Format("{0:yyyy-MM-dd HH:mm}", x.ValidityEndTime),
                                              States = Const.State_3,
                                          };
                    foreach (var itemBreakGround in getBreakGrounds)
                    {
                        APILicenseDataService.SaveLicenseData(itemBreakGround);
                    }
                    ////夜间施工作业票
                    var getNightWorks = from x in db.License_NightWork
                                        where x.States == Const.State_2 && x.ValidityEndTime <= DateTime.Now
                                        select new Model.LicenseDataItem
                                        {
                                            LicenseId = x.NightWorkId,
                                            MenuId = Const.ProjectNightWorkMenuId,
                                            ProjectId = x.ProjectId,
                                            CloseManId = x.ApplyManId,
                                            CloseManName = db.Sys_User.First(u => u.UserId == x.CloseManId).UserName,
                                            CloseReasons = "到期自动关闭。",
                                            CloseTime = string.Format("{0:yyyy-MM-dd HH:mm}", x.ValidityEndTime),
                                            States = Const.State_3,
                                        };
                    foreach (var itemNightWork in getNightWorks)
                    {
                        APILicenseDataService.SaveLicenseData(itemNightWork);
                    }
                    ////吊装作业票
                    var getLiftingWorks = from x in db.License_LiftingWork
                                          where x.States == Const.State_2 && x.ValidityEndTime <= DateTime.Now
                                          select new Model.LicenseDataItem
                                          {
                                              LicenseId = x.LiftingWorkId,
                                              MenuId = Const.ProjectLiftingWorkMenuId,
                                              ProjectId = x.ProjectId,
                                              CloseManId = x.ApplyManId,
                                              CloseManName = db.Sys_User.First(u => u.UserId == x.CloseManId).UserName,
                                              CloseReasons = "到期自动关闭。",
                                              CloseTime = string.Format("{0:yyyy-MM-dd HH:mm}", x.ValidityEndTime),
                                              States = Const.State_3,
                                          };
                    foreach (var itemLiftingWork in getLiftingWorks)
                    {
                        APILicenseDataService.SaveLicenseData(itemLiftingWork);
                    }
                    ////作业票【定稿】
                    var getLicenseManagers = from x in db.License_LicenseManager
                                             where x.WorkStates == Const.State_2 && x.EndDate <= DateTime.Now
                                             select new Model.LicenseDataItem
                                             {
                                                 LicenseId = x.LicenseManagerId,
                                                 MenuId = Const.ProjectLicenseManagerMenuId,
                                                 ProjectId = x.ProjectId,
                                                 LicenseCode = x.LicenseManagerCode,
                                                 ApplyUnitId = x.UnitId,
                                                 ApplyManName = x.ApplicantMan,
                                                 WorkAreaIds = x.WorkAreaId,
                                                 ApplyManId = x.CompileMan,
                                                 ApplyDate = string.Format("{0:yyyy-MM-dd HH:mm}", x.CompileDate),
                                                 ValidityEndTime = string.Format("{0:yyyy-MM-dd HH:mm}", x.EndDate),
                                                 ValidityStartTime = string.Format("{0:yyyy-MM-dd HH:mm}", x.StartDate),
                                                 States = Const.State_3,
                                             };
                    foreach (var itemLicenseManager in getLicenseManagers)
                    {
                        APILicenseDataService.SaveLicenseData(itemLicenseManager);
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }
        #endregion
    }
}