using Newtonsoft.Json;
using Sugar.Enties.DbModels;
using Sugar.Enties.DTO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Utils;

namespace PMS.NetCore.BusinessCore.BaseCore
{
    /// <summary>
    /// 巡更计划
    /// </summary>
    public class fdc_pm_inspection_planManager : DbContext<fdc_pm_inspection_plan>
    {

        private NLog.Logger logger;
        public fdc_pm_inspection_planManager()
        {
            logger = NLog.LogManager.GetCurrentClassLogger();
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public string PlanAdd(fdc_pm_inspection_plan model)
        {
            var routeManager = new fdc_pm_inspection_routeManager();
            var route = routeManager.GetById(model.routecode);

            var sql = @$"select a.* from fdc_pm_inspection_plan a
                        left join fdc_pm_inspection_route b on b.routecode=a.routecode
                        where a.routecode='{model.routecode}' and b.pcode='{route.pcode}'
                        and a.startdate<='{model.startdate}' and '{model.enddate}'<=a.enddate";

            var planList = Db.SqlQueryable<fdc_pm_inspection_plan>(sql).ToList();
            if (planList.Count > 0)
            {
                return "该时间段已经设置此巡检计划";
            }

            model.createtime = DateTime.Now;
            var row = Db.Insertable(model).ExecuteCommand();

            if (row > 0)
            {
                return "添加成功";
            }
            else
            {
                return "添加失败";
            }

        }

        /// <summary>
        /// 修改计划
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public string PlanUpdate(fdc_pm_inspection_plan model)
        {
            var routeManager = new fdc_pm_inspection_routeManager();
            var route = routeManager.GetById(model.routecode);

            var sql = @$"select a.* from fdc_pm_inspection_plan a
                        left join fdc_pm_inspection_route b on b.routecode=a.routecode
                        where a.routecode='{model.routecode}' and b.pcode='{route.pcode}'
                        and a.startdate<='{model.startdate}' and '{model.enddate}'<=a.enddate
                        and a.plancode<>'{model.plancode}'";

            var planList = Db.SqlQueryable<fdc_pm_inspection_plan>(sql).ToList();
            if (planList.Count > 0)
            {
                return "该时间段已经设置此巡检计划";
            }

            var plandetailManager = new fdc_pm_inspection_plandetailManager();
            var detailList = plandetailManager.GetList(i => i.plancode == model.plancode);
            if (detailList.Count > 0)
            {
                return "已分配给巡检人员，请先删除计划，重新设置";
            }

            model.createtime = DateTime.Now;
            var row = Db.Updateable(model).ExecuteCommand();

            if (row > 0)
            {
                return "修改成功";
            }
            else
            {
                return "修改失败";
            }

        }



        /// <summary>
        /// 删除计划
        /// </summary>
        /// <param name="planCode"></param>
        /// <returns></returns>
        public string PlanDelete(int planCode)
        {

            var model = CurrentDb.GetById(planCode);
            if (model == null)
            {
                return "该巡检计划不存在，不能删除";
            }

            Db.BeginTran();
            try
            {
                var success = CurrentDb.Delete(model);

                //巡检计划详情处理
                var planDetaiManager = new fdc_pm_inspection_plandetailManager();
                planDetaiManager.Delete(planCode);

                //删除巡检人员

                var employeeManager = new fdc_pm_inspection_employeeplanManager();
                employeeManager.Delete(planCode);


                Db.CommitTran();

                return "删除成功";

            }
            catch (Exception)
            {
                Db.RollbackTran();
                throw;
            }



        }
    }


    /// <summary>
    /// 员工巡检计划
    /// </summary>
    public class fdc_pm_inspection_employeeplanManager : DbContext<fdc_pm_inspection_employeeplan>
    {


    }

    /// <summary>
    /// 巡检计划详情
    /// </summary>
    public class fdc_pm_inspection_plandetailManager : DbContext<fdc_pm_inspection_plandetail>
    {
        private NLog.Logger logger;
        public fdc_pm_inspection_plandetailManager()
        {
            logger = NLog.LogManager.GetCurrentClassLogger();
        }


        public string updateStatus()
        {
            return "";
        }


        /// <summary>
        /// 更新巡检备注、附件
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public string UpdateDetailPlan(InspectionParamDTO model)
        {            
            var detailInfo = CurrentDb.GetById(model.autoid);
            if (detailInfo == null ||  detailInfo.realtime==null)
            {
                return "NFC未扫描当前巡更点";
            }
          

            Db.BeginTran();
            List<string> fileNameList = new List<string>();
            try
            {
              
                if(!string.IsNullOrEmpty(model.reamrk))
                {
                    var sql = @$"update fdc_pm_inspection_plandetail set 
                        remark='{model.reamrk}' 
                        where autoid={model.autoid}";

                    int rows = Db.Ado.ExecuteCommand(sql);
                }              

                foreach (var item in model.fileList)
                {
                    var name = Guid.NewGuid().ToString();
                    var filename = Guid.NewGuid().ToString() + Path.GetExtension(item.Name);
                    var uploadSuccess = UploadFileHelper.Base64StringToFile(item.Content, filename);
                    if (!uploadSuccess)
                    {
                        Db.RollbackTran();
                        return "上传失败";
                    }
                    fileNameList.Add(filename);                    
                }

                if(fileNameList.Count>0)
                {
                    string attachStr = string.Join(',', fileNameList);

                    string sqlfile = @$"update fdc_pm_inspection_plandetail set 
                                    attach='{attachStr}' 
                                    where autoid={model.autoid}";
                    var row = Db.Ado.ExecuteCommand(sqlfile);

                    if (row <= 0)
                    {
                        Db.RollbackTran();
                        return "保存上传文件失败";
                    }
                }               

                Db.CommitTran();
                return "success";
            }
            catch (Exception ex)
            {
                Db.RollbackTran();
                //logger.Error(ex);
                throw;
            }
        }


        /// <summary>
        /// NFC扫描巡更
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public string NfcScan(NfcScanDTO model)
        {
            var sql = @$"select b.autoid,a.plandate, a.plantime, b.pointcode
                        from fdc_pm_inspection_employeeplan a 
                        left join fdc_pm_inspection_plandetail b on a.plancode=b.plancode and a.plandate=b.plandate and a.plantime=b.plantime
                        where userid={model.userId} and pointcode='{model.pointCode}'  and a.plandate=CONVERT(varchar(100),getdate(),23) and 
                        getdate()  between  (CONVERT(varchar(100),getdate(),23)+' '+ SUBSTRING(a.plantime,0,6))and (CONVERT(varchar(100),getdate(),23)+' '+ SUBSTRING(a.plantime,7,5))";


            var planDetailManager = new fdc_pm_inspection_plandetailManager();

            var planDetailList = planDetailManager.Db.SqlQueryable<inspectionplandetail>(sql).ToList();
            if (planDetailList.Count <= 0) 
            {
                return "此巡更点不在巡更计划中";
            }

            var currentPoint = planDetailList.Find(i => i.pointcode == model.pointCode);

            sql = @$"update fdc_pm_inspection_plandetail set realtime=getdate()
                     where autoid={currentPoint.autoid}";

            int rows = Db.Ado.ExecuteCommand(sql);

            if (rows > 0)
            {
                return "success";
            }
            else
            {
                return "fail";
            }
        }


        /// <summary>
        /// 获取巡更点详情
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public inspectionplandetail GetPointDetail(int pkCode)
        {
           

            var sql = @$"select a.* ,c.routename, d.pointname,e.bname,f.hname
                                from fdc_pm_inspection_plandetail a
                                left join fdc_pm_inspection_plan b on a.plancode=b.plancode
                                left join fdc_pm_inspection_route c on c.routecode = b.routecode
                                left join fdc_pm_inspection_point d on a.pointcode= d.pointcode
                                left join fdc_pm_build e on e.bcode = d.bcode
                                left join fdc_pm_house f on f.hcode = d.hcode
                              where a.autoid='{pkCode}'";

            var planDetailManager = new fdc_pm_inspection_plandetailManager();

            var planDetailList = planDetailManager.Db.SqlQueryable<inspectionplandetail>(sql).ToList();            

            if (planDetailList.Count > 0)
            {               
                planDetailList.ForEach(i => i.status = (i.realtime != null ? "已巡检" : "未巡检"));
                return planDetailList.Find(i => i.autoid == pkCode);
            }

            return null;
        }


        /// <summary>
        /// 获取巡检路线详情
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public List<inspectionplandetail> GetPlanDetailList(string planCode, string planDate, string planTime)
        {                

            var sql = @$"select a.* ,c.routename, d.pointname,e.bname,f.hname
                                from fdc_pm_inspection_plandetail a
                                left join fdc_pm_inspection_plan b on a.plancode=b.plancode
                                left join fdc_pm_inspection_route c on c.routecode = b.routecode
                                left join fdc_pm_inspection_point d on a.pointcode= d.pointcode
                                left join fdc_pm_build e on e.bcode = d.bcode
                                left join fdc_pm_house f on f.hcode = d.hcode
                              where a.plancode='{planCode}' and a.plandate='{planDate}'and a.plantime='{planTime}'";

            var planDetailManager = new fdc_pm_inspection_plandetailManager();

            var planDetailList = planDetailManager.Db.SqlQueryable<inspectionplandetail>(sql).ToList();

            if (planDetailList.Count > 0)
            {
                planDetailList.ForEach(i => i.status = (i.realtime != null ? "已巡检" : "未巡检"));
            } 
            return planDetailList;
        }



        /// <summary>
        /// 获取员工巡检计划
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public List<InspectionEmployeePlanDTO> GetEmployeePlanList(string userid, string plandate, int pageNumber, int pageSize)
        {
            List<InspectionEmployeePlanDTO> result = new List<InspectionEmployeePlanDTO>();
            int startindex = (pageNumber - 1) * pageSize + 1;
            int limitindex = (pageNumber - 1) * pageSize + pageSize;

            var sql = @$" select * from ( 
				                select top 100 percent ROW_NUMBER() OVER(order by a.plandate,a.plantime asc ) AS RowNumber,COUNT(*) OVER(PARTITION BY '') AS TotalCount,
		                        a.plancode,a.plandate,a.plantime, d.planname,
                                stuff(
                                     (SELECT ','+ convert(varchar,b.userid)
                                      FROM fdc_pm_inspection_employeeplan b				
                                      WHERE a.plancode=b.plancode and a.plandate=b.plandate and a.plantime=b.plantime
                                      FOR xml path('')),1,1,'') userid,                              
                                stuff(
                                     (SELECT ','+ convert(varchar,c.UserName)
                                      FROM fdc_pm_inspection_employeeplan b	
				                      left join users c on b.userid = c.StaffCode			
                                      WHERE a.plancode=b.plancode and a.plandate=b.plandate and a.plantime=b.plantime
                                      FOR xml path('')),1,1,'') username                              
                              from fdc_pm_inspection_employeeplan a
							        left join fdc_pm_inspection_plan d on a.plancode = d.plancode
                                      where a.userid='{userid}' and a.plandate = CONVERT(varchar(100), '{plandate}', 23)
					                   group by a.plancode,d.planname,a.plandate,a.plantime
					                   ) bb
					           where  RowNumber between {startindex} and  {limitindex}";


            var employeeManager = new fdc_pm_inspection_employeeplanManager();
            var planList = employeeManager.Db.SqlQueryable<fdc_pm_inspection_employeeplan>(sql).ToList();
            if (planList.Count <= 0)
            {
                return null;
            }
            var planDetailManager = new fdc_pm_inspection_plandetailManager();

            foreach (var item in planList)
            {
                var sqll = @$"select a.* ,b.pointname from fdc_pm_inspection_plandetail a                            
                            left join fdc_pm_inspection_point b on a.pointcode= b.pointcode
                            where a.plancode='{item.plancode}' and a.plandate='{item.plandate}'and a.plantime='{item.plantime}'";

                var planDetailList = planDetailManager.Db.SqlQueryable<inspectionplandetail>(sqll).ToList();

                var completeList = planDetailList.FindAll(i => i.realtime != null);

                InspectionEmployeePlanDTO mod = new InspectionEmployeePlanDTO();
                mod.userids = item.userid;
                mod.usernames = item.username;
                mod.plancode = item.plancode;
                mod.planname = item.planname;
                mod.plandate = item.plandate.ToString("yyyy-MM-dd");
                mod.plantime = item.plantime;
                mod.planprogress = planDetailList.Count > 0 ? string.Format("{0}/{1}", completeList.Count, planDetailList.Count) : "";
                mod.planstatus = getPlanStatus(item.plandate, item.plantime);
                mod.totalcount = item.totalcount;
                result.Add(mod);

            }
            return result;
        }



        /// <summary>
        /// 设置修改计划详情
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string PlandetailAdd(InspectionPlanDTO input)
        {

            //按时巡检周期设置计划巡检时间
            var planManager = new fdc_pm_inspection_planManager();
            var plan = planManager.GetById(Convert.ToInt32(input.planCode));
            //获取巡检计划日期
            DateTime[] arr = ArrayTime(plan.startdate, plan.enddate, 1);

            try
            {
                //遍历巡更日期设置巡更计划
                string plantimeStr = "8:00-10:00";
                foreach (var item in arr)
                {

                    var sql = @$"select a.* from fdc_pm_inspection_plandetail a
                        inner join fdc_pm_inspection_employeeplan b on a.plancode=b.plancode
                        where b.userid in({input.userStr}) and a.plancode='{input.planCode}' 
						and a.plandate='{item}'
						and a.plantime='{plantimeStr}'";


                    var detailList = Db.SqlQueryable<fdc_pm_inspection_plandetail>(sql).ToList();
                    if (detailList.Count > 0)
                    {
                        logger.Debug($"PlandetailAdd 输出参数】res:员工已分配过该巡检计划");
                        continue;

                    }

                    insertPlanDetail(plan.routecode, input.planCode, item, plantimeStr, input.userStr);
                }

                return "success";
            }
            catch (Exception ex)
            {
                logger.Error($"PlandetailAdd 输出参数】res:" + ex);
                throw;
            }



        }


        private bool insertPlanDetail(int routeCode, int planCode, DateTime planDate, string planTime, string userStr)
        {
            //获取指定线路巡检点列表
            var manager = new fdc_pm_inspection_routeManager();
            var pointList = manager.GetRouteDetail(new Sugar.Enties.DTO.InspectionDTO() { routeCode = routeCode });

            List<fdc_pm_inspection_plandetail> detailList = new List<fdc_pm_inspection_plandetail>();
            foreach (var item in pointList)
            {
                var planDetail = new fdc_pm_inspection_plandetail()
                {
                    plancode = planCode,
                    pointcode = item.pointCode,
                    sort = item.sort,
                    planDate = planDate,
                    plantime = planTime,
                    createtime = DateTime.Now
                };

                detailList.Add(planDetail);
            }


            //巡检人员
            string[] userArr = userStr.Split(',');
            var userManager = new fdc_pm_inspection_employeeplanManager();
            var userList = new List<fdc_pm_inspection_employeeplan>();
            foreach (var item in userArr)
            {
                userList.Add(new fdc_pm_inspection_employeeplan()
                {
                    userid = item,
                    plancode = planCode,
                    plandate = planDate,
                    createtime = DateTime.Now
                });
            }

            Db.BeginTran();
            try
            {

                //添加计划详情              

                CurrentDb.InsertRange(detailList);

                //绑定员工计划             

                userManager.Insert(userList);


                Db.CommitTran();
                return true;
            }
            catch (Exception)
            {
                Db.RollbackTran();
                throw;
            }

        }


        /// <summary>
        /// 返回按AddDays拆分的时间段（包含多个逗号隔开）
        /// </summary>
        private string StrTimes(DateTime starttime, DateTime endtime, int AddDays)
        {
            DateTime nowtime = starttime; string strtimes = starttime.ToString("yyyy-MM-dd HH:mm:ss") + ",";
            do
            {
                nowtime = nowtime.AddDays(AddDays);
                if (nowtime < endtime)
                    strtimes += nowtime.ToString("yyyy-MM-dd HH:mm:ss") + ",";
                else
                    strtimes += endtime.ToString("yyyy-MM-dd HH:mm:ss") + ",";

            } while (nowtime < endtime);

            return strtimes.Trim(',');
        }
        /// <summary>
        /// 根据时间段和AddDays来拆分， 返回一个时间数组
        /// </summary>
        private DateTime[] ArrayTime(DateTime starttime, DateTime endtime, int AddDays)
        {
            string strtime = StrTimes(starttime, endtime, AddDays);

            string[] arrstrtime = strtime.Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries);

            List<string> arrstrtimeList = new List<string>(arrstrtime);
            DateTime[] arrayTimes = arrstrtimeList.ConvertAll((a) => { return DateTime.Parse(a); }).ToArray();
            return arrayTimes;
        }


        /// <summary>
        /// 获取巡更计划状态 状态值  0 即将开始   1 开始巡逻   2 已结束
        /// </summary>
        /// <param name="plandate"></param>
        /// <param name="plantime"></param>
        /// <returns></returns>
        private string getPlanStatus(DateTime plandate, string plantime)
        {
            try
            { 
                DateTime currentTime = DateTime.Now;
                string[] timeArr = plantime.Split('-');
                DateTime startTime = Convert.ToDateTime(string.Format("{0} {1}:00", plandate.ToString("yyyy-MM-dd"), timeArr[0]));
                DateTime endTime = Convert.ToDateTime(string.Format("{0} {1}:00", plandate.ToString("yyyy-MM-dd"), timeArr[1]));

                if (currentTime.ToShortDateString() == plandate.ToShortDateString()) //同一天
                {
                    if (getTimeSpan(currentTime, timeArr[0], timeArr[1]))
                    {
                        return "开始巡逻";
                    }
                    else if (DateTime.Compare(currentTime, endTime) > 0)
                    {

                        return "已结束";
                    }

                    return "即将开始";
                }

                if (DateTime.Compare(Convert.ToDateTime(currentTime.ToShortDateString()), Convert.ToDateTime(plandate.ToShortDateString())) > 0)
                {
                    return "已结束";

                }
                return "即将开始";

            }
            catch (Exception ex)
            {
                logger.Error($"getPlanStatus 输出参数】res:" + ex);
                throw;
            }

        }


        private static bool getTimeSpan(DateTime currentTime, string _strWorkingDayAM, string _strWorkingDayPM)
        {
            //判断当前时间是否在工作时间段内           
            TimeSpan dspWorkingDayAM = DateTime.Parse(_strWorkingDayAM).TimeOfDay;
            TimeSpan dspWorkingDayPM = DateTime.Parse(_strWorkingDayPM).TimeOfDay;

            TimeSpan dspNow = currentTime.TimeOfDay;
            if (dspNow > dspWorkingDayAM && dspNow < dspWorkingDayPM)
            {
                return true;
            }
            return false;
        }

    }
}
