using Siger.CommonArchitect.DapperExtense;
using Siger.CommonUtil;
using Siger.DapperExtense.MysqlHelper;
using Siger.DW.Demo.Entity;
using Siger.DW.Demo.MidEnum;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Siger.DW.Demo
{
    public class SliceYieldDal
    {
        RedisOpHelper _redisHelp;
        SqlHelper<SliceSateEnti> sliceSqlHelper;
        SqlHelper<SliceSateTotal> sliceSateSqlHelper;

        Dictionary<string, string> dictMachineNum;
        bool IsStop = false;
        public SliceYieldDal()
        {
            _redisHelp = new RedisOpHelper();
            sliceSqlHelper = SqlFactory.CreateInstance<SliceSateEnti>(CommonInfo.DataProcessConfig);//切片数据表
            sliceSateSqlHelper = SqlFactory.CreateInstance<SliceSateTotal>(CommonInfo.MidDataProcessConfig);
            //sliceSqlHelper = SqlFactory.CreateInstance<SliceSateEnti>(CommonInfo.DataProcessConfig,"192_192");
        }

        public List<SliceSateEnti> GetDataByTime(DateTime startTime, DateTime endTime)
        {
            ISpecification<SliceSateEnti> prod = SpecificationContext<SliceSateEnti>.GetInstance();
            var itemStart = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.StartTime, SearchCondition.GtAndEqual, startTime);
            prod.Add(itemStart);
            var itemEnd = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.StartTime, SearchCondition.Lt, endTime, "EndTime");
            prod.Add(itemEnd);
            var sortItem = SearchItemHelper.CreateSortItem<SliceSateEnti>((i) => i.StartTime);
            prod.Sort(sortItem);
            var items = sliceSqlHelper.FindByConditions(prod);
            return items;
        }
        public List<SliceSateTotal> GetSliceSateDataByTime(int timeType)
        {
            List<SliceSateTotal> responseData = new List<SliceSateTotal>();
            if (timeType == 1)//1 代表以天为单位中间表添加切片数据
            {
                ISpecification<SliceSateTotal> condition = SpecificationContext<SliceSateTotal>.GetInstance();

                var itemDate = SearchItemHelper.CreateSearchItem<SliceSateTotal>((i) => i.Date, SearchCondition.Equal, DateTime.Now.Date);
                condition.Add(itemDate);
                var todayData = sliceSateSqlHelper.FindByConditions(condition); //中间表当天的数据
                
                if (!todayData.Any())
                {
                    var id = _redisHelp.HGet(CommonInfo.RedisNowDate, DateTime.Now.AddDays(-1).ToShortDateString());
                    if(!string.IsNullOrEmpty(id))
                    {
                        var yesDate = sliceSqlHelper.GetItemById(id);

                        ISpecification<SliceSateEnti> conditionYes = SpecificationContext<SliceSateEnti>.GetInstance();
                        
                        var idCondition = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.id, SearchCondition.Gt, id);
                        conditionYes.Add(idCondition);
                        var dateCondition = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.EndTime.Date, SearchCondition.Equal, yesDate.EndTime.Date);
                        conditionYes.Add(dateCondition);

                        var query = sliceSqlHelper.FindByConditions(conditionYes);
                        if (!query.Any())
                        {
                            ISpecification<SliceSateTotal> conditionYesMid = SpecificationContext<SliceSateTotal>.GetInstance();
                            var itemYestoday = SearchItemHelper.CreateSearchItem<SliceSateTotal>((i) => i.Date, SearchCondition.Equal, yesDate.EndTime.Date);
                            conditionYesMid.Add(itemYestoday);

                            var yestodayData = sliceSateSqlHelper.FindByConditions(conditionYesMid);
                            foreach (var item in yestodayData)
                            {
                                foreach (var slicedata in query)
                                {
                                    if (item.MachineID == slicedata.MachineID)
                                    {
                                        if (slicedata.Status == (int)StatusEnum.Shutdown)
                                        {
                                            item.Shutdown += (slicedata.EndTime - slicedata.StartTime).TotalSeconds;
                                        }
                                        else if (slicedata.Status == (int)StatusEnum.Running)
                                        {
                                            item.Run += (slicedata.EndTime - slicedata.StartTime).TotalSeconds;
                                        }
                                        else if (slicedata.Status == (int)StatusEnum.Debugging)
                                        {
                                            item.Debug += (slicedata.EndTime - slicedata.StartTime).TotalSeconds;
                                        }
                                        else if (slicedata.Status == (int)StatusEnum.Free)
                                        {
                                            item.Free += (slicedata.EndTime - slicedata.StartTime).TotalSeconds;
                                        }
                                        else if (slicedata.Status == (int)StatusEnum.Fault)
                                        {
                                            item.Fault += (slicedata.EndTime - slicedata.StartTime).TotalSeconds;
                                        }
                                    }
                                }
                                if (!sliceSateSqlHelper.UpdateItem(item))
                                {
                                    throw new Exception(MidEnums.DbDataInsertFail.ToString());
                                }
                            }
                        }
                    }

                    List<SliceSateTotal> response = new List<SliceSateTotal>();
                    ISpecification<SliceSateEnti> prod = SpecificationContext<SliceSateEnti>.GetInstance();
                    DateTime dtStartTime = DateTime.Now.Date;//当天的0点
                    DateTime dtEndTime = DateTime.Now;

                    var itemStart = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.StartTime, SearchCondition.GtAndEqual, dtStartTime);
                    prod.Add(itemStart);
                    var itemEnd = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.EndTime, SearchCondition.LtAndEqual, dtEndTime);
                    prod.Add(itemEnd);

                    var items = sliceSqlHelper.FindByConditions(prod);//切片表0点到当前时间的数据

                    if (!_redisHelp.HSet(CommonInfo.RedisNowDate, DateTime.Now.ToShortDateString(), items.Last().id.ToString()))//往redis中添加当前读取到的最后一条数据的id
                    {
                        throw new Exception(MidEnums.RedisDataFail.ToString());
                    }

                    var itemsGroup = items.GroupBy((i) => i.MachineID).ToList();
                    foreach (var slice in itemsGroup)
                    {
                        double sumTimeDown = 0d;//关机
                        double sumTimeRun = 0d;//运行
                        double sumTimeDebug = 0d;//调试
                        double sumTimeFree = 0d;//空闲
                        double sumTimeFault = 0d;//故障
                        foreach (var sliceItem in slice)
                        {
                            if (sliceItem.Status == (int)StatusEnum.Shutdown)
                            {
                                sumTimeDown += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                            }
                            else if (sliceItem.Status == (int)StatusEnum.Running)
                            {
                                sumTimeRun += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                            }
                            else if (sliceItem.Status == (int)StatusEnum.Debugging)
                            {
                                sumTimeDebug += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                            }
                            else if (sliceItem.Status == (int)StatusEnum.Free)
                            {
                                sumTimeFree += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                            }
                            else if (sliceItem.Status == (int)StatusEnum.Fault)
                            {
                                sumTimeFault += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                            }
                        }
                        response.Add(new SliceSateTotal
                        {
                            Shutdown = sumTimeDown,
                            Debug = sumTimeDebug,
                            Fault = sumTimeFault,
                            Free = sumTimeFree,
                            Run = sumTimeRun,
                            Date = DateTime.Now.Date,
                            MachineID = slice.Key
                        });
                    }
                    if (!sliceSateSqlHelper.AddItems(response))
                    {
                        throw new Exception(MidEnums.DbDataInsertFail.ToString());
                    }
                    responseData = response;
                }
                else//当中间表有了当天的数据时
                {
                    ISpecification<SliceSateEnti> prodThen = SpecificationContext<SliceSateEnti>.GetInstance();
                    ISpecification<SliceSateTotal> conditionThen = SpecificationContext<SliceSateTotal>.GetInstance();
                    //ISpecification<SliceSateEnti> conditionId = SpecificationContext<SliceSateEnti>.GetInstance();

                    List<SliceSateTotal> sliceList = new List<SliceSateTotal>();
                    var id = _redisHelp.HGet(CommonInfo.RedisNowDate, DateTime.Now.ToShortDateString());

                    //var dataById = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.id, SearchCondition.Equal, id);
                    //conditionId.Add(dataById);
                    var sliceById = sliceSqlHelper.GetItemById(id);//得到上一次读取到的那条数据

                    var itemId = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.id, SearchCondition.Gt, Convert.ToInt32(id));
                    prodThen.Add(itemId);
                    var endTime = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.EndTime.Date, SearchCondition.Equal, sliceById.EndTime.Date);
                    prodThen.Add(endTime);

                    var items = sliceSqlHelper.FindByConditions(prodThen);

                    if (!_redisHelp.HSet(CommonInfo.RedisNowDate, DateTime.Now.ToShortDateString(), items.Last().id.ToString()))
                    {
                        throw new Exception(MidEnums.RedisDataFail.ToString());
                    }

                    var itemToday = SearchItemHelper.CreateSearchItem<SliceSateTotal>((i) => i.Date, SearchCondition.Equal, DateTime.Now.Date);
                    conditionThen.Add(itemToday);

                    var query = sliceSateSqlHelper.FindByConditions(conditionThen).OrderBy((i) => i.id);
                    foreach (var item in query)
                    {
                        foreach (var slicedata in items)
                        {
                            if (item.MachineID == slicedata.MachineID)
                            {
                                if (slicedata.Status == (int)StatusEnum.Shutdown)
                                {
                                    item.Shutdown += (slicedata.EndTime - slicedata.StartTime).TotalSeconds;
                                }
                                else if (slicedata.Status == (int)StatusEnum.Running)
                                {
                                    item.Run += (slicedata.EndTime - slicedata.StartTime).TotalSeconds;
                                }
                                else if (slicedata.Status == (int)StatusEnum.Debugging)
                                {
                                    item.Debug += (slicedata.EndTime - slicedata.StartTime).TotalSeconds;
                                }
                                else if (slicedata.Status == (int)StatusEnum.Free)
                                {
                                    item.Free += (slicedata.EndTime - slicedata.StartTime).TotalSeconds;
                                }
                                else if (slicedata.Status == (int)StatusEnum.Fault)
                                {
                                    item.Fault += (slicedata.EndTime - slicedata.StartTime).TotalSeconds;
                                }
                            }
                        }
                        sliceList.Add(item);
                        if (!sliceSateSqlHelper.UpdateItem(item))
                        {
                            throw new Exception(MidEnums.DbDataInsertFail.ToString());
                        }
                    }
                    responseData = sliceList;
                }
            }else if(timeType==2)
            {
                ISpecification<SliceSateEnti> prod = SpecificationContext<SliceSateEnti>.GetInstance();

                DateTime.TryParse(DateTime.Now.ToString(CommonInfo.TimeHourConfig), out DateTime nowHour);

                DateTime dtStartTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.AddHours(-1).Hour, 0, 0);
                DateTime dtEndTime = dtStartTime.AddHours(1);

                ISpecification<SliceSateTotal> condition = SpecificationContext<SliceSateTotal>.GetInstance();
                var itemDate = SearchItemHelper.CreateSearchItem<SliceSateTotal>((i) => i.Hour, SearchCondition.Equal, nowHour);
                condition.Add(itemDate);
                var query = sliceSateSqlHelper.FindByConditions(condition);//前一个小时插入的切片数据

                ISpecification<SliceSateTotal> conditionToNow = SpecificationContext<SliceSateTotal>.GetInstance();
                var Start = SearchItemHelper.CreateSearchItem<SliceSateTotal>((i) => i.Hour, SearchCondition.GtAndEqual, DateTime.Now.Date);
                conditionToNow.Add(Start);
                var End= SearchItemHelper.CreateSearchItem<SliceSateTotal>((i) => i.Hour, SearchCondition.LtAndEqual, nowHour.AddHours(-1));
                conditionToNow.Add(End);
                var todayData = sliceSateSqlHelper.FindByConditions(conditionToNow);//当天0点到当前时间前2小时为止的数据
                var todayDataGroup = todayData.GroupBy(s => s.Hour);

                //表中的数据条数是否跟当前时间前2小时相等
                if (todayDataGroup.Count()!=(nowHour.Hour-1))
                {
                    var hourList = new List<int>();
                    var hourToday = todayData.Select(s => s.Hour.Hour).Distinct().OrderBy(s=>s).ToList();
                    for (int i = 0; i <= nowHour.Hour - 1; i++)
                    {
                        hourList.Add(i);
                    }
                    var diffList = hourList.Where(s => !hourToday.Contains(s)).ToList();//当日数据中没有记录切片数据的小时
                    foreach (var item in diffList)
                    {
                        ISpecification<SliceSateEnti> prodDiff = SpecificationContext<SliceSateEnti>.GetInstance();
                        DateTime dtStartTimeDiff = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, item - 1, 0, 0);
                        DateTime dtEndTimeDiff = dtStartTime.AddHours(1);
                        var itemStartDiff = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.StartTime, SearchCondition.GtAndEqual, dtStartTime);
                        prodDiff.Add(itemStartDiff);
                        var itemEndDiff = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.EndTime, SearchCondition.LtAndEqual, dtEndTime);
                        prodDiff.Add(itemEndDiff);

                        var items = sliceSqlHelper.FindByConditions(prodDiff);
                        var itemsGroup = items.GroupBy((i) => i.MachineID);
                        List<SliceSateTotal> response = new List<SliceSateTotal>();
                        foreach (var slice in itemsGroup)
                        {
                            double sumTimeDown = 0d;
                            double sumTimeRun = 0d;
                            double sumTimeDebug = 0d;
                            double sumTimeFree = 0d;
                            double sumTimeFault = 0d;
                            foreach (var sliceItem in slice)
                            {
                                if (sliceItem.Status == (int)StatusEnum.Shutdown)
                                {
                                    sumTimeDown += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds; 
                                }
                                else if (sliceItem.Status == (int)StatusEnum.Running)
                                {
                                    sumTimeRun += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                                }
                                else if (sliceItem.Status == (int)StatusEnum.Debugging)
                                {
                                    sumTimeDebug += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                                }
                                else if (sliceItem.Status == (int)StatusEnum.Free)
                                {
                                    sumTimeFree += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                                }
                                else if (sliceItem.Status == (int)StatusEnum.Fault)
                                {
                                    sumTimeFault += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                                }
                            }
                            response.Add(new SliceSateTotal()
                            {
                                Hour = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, item, 0, 0),
                                MachineID = slice.Key,
                                Shutdown = sumTimeDown,
                                Fault = sumTimeFault,
                                Debug = sumTimeDebug,
                                Free = sumTimeFree,
                                Run = sumTimeRun
                            });
                            if (!sliceSateSqlHelper.AddItems(response))
                            {
                                throw new Exception(MidEnums.DbDataInsertFail.ToString());
                            }
                        }
                    }
                }
                if (!query.Any())
                {
                    var itemStart = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.StartTime, SearchCondition.GtAndEqual, dtStartTime);
                    prod.Add(itemStart);
                    var itemEnd = SearchItemHelper.CreateSearchItem<SliceSateEnti>((i) => i.EndTime, SearchCondition.LtAndEqual, dtEndTime);
                    prod.Add(itemEnd);
                    var items = sliceSqlHelper.FindByConditions(prod);
                    var itemsGroup = items.GroupBy((i) => i.MachineID);
                    List<SliceSateTotal> response = new List<SliceSateTotal>(); 
                    foreach (var slice in itemsGroup)
                    {
                        double sumTimeDown = 0d;
                        double sumTimeRun = 0d;
                        double sumTimeDebug = 0d;
                        double sumTimeFree = 0d;
                        double sumTimeFault = 0d;
                        foreach (var sliceItem in slice)
                        {
                            if (sliceItem.Status == (int)StatusEnum.Shutdown)
                            {
                                sumTimeDown += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                            }
                            else if (sliceItem.Status == (int)StatusEnum.Running)
                            {
                                sumTimeRun += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                            }
                            else if (sliceItem.Status == (int)StatusEnum.Debugging)
                            {
                                sumTimeDebug += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                            }
                            else if (sliceItem.Status == (int)StatusEnum.Free)
                            {
                                sumTimeFree += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                            }
                            else if (sliceItem.Status == (int)StatusEnum.Fault)
                            {
                                sumTimeFault += (sliceItem.EndTime - sliceItem.StartTime).TotalSeconds;
                            }
                        }
                        response.Add(new SliceSateTotal()
                        {
                            Hour = nowHour,
                            MachineID = slice.Key,
                            Shutdown = sumTimeDown,
                            Debug = sumTimeDebug,
                            Fault = sumTimeFault,
                            Free = sumTimeFree,
                            Run = sumTimeRun
                        });
                        if (!sliceSateSqlHelper.AddItems(response))
                        {
                            throw new Exception(MidEnums.DbDataInsertFail.ToString());
                        }
                        responseData = response;
                    }
                }
            }
            return responseData;
        }
    }
}
