
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.DashboardRepository.Response;
using Siger.Middlelayer.KpiRespository.Respose;
using Siger.Middlelayer.QmsRepository.Entities;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.TpmRepository.Response;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Siger.ApiDashboard.Utilities
{
    public class ReportSumHelper
    {
        private static ReportSumHelper _helper;
        public static ReportSumHelper Instance = _helper ?? (_helper = new ReportSumHelper());

        public ReportSumHelper()
        {

        }
        /// <summary>
        /// tbl3 Qms 模块人员数据录入量
        /// </summary>
        /// <param name="checkMaterial"></param>
        /// <param name="checkInspData"></param>
        /// <param name="reworkData"></param>
        /// <returns></returns>
        public List<ResponseSumQmsDataCount> qmsPersonData(IEnumerable<siger_check_sn_trace_material> checkMaterial, IEnumerable<siger_check_sn_trace_inspection> checkInspData, IEnumerable<siger_qms_rework_data> reworkData)
        {
            var result = new List<ResponseSumQmsDataCount>();
            var grpMaterial = checkMaterial.GroupBy(g => g.UserID);
            var grpCheckInsp = checkInspData.GroupBy(g => g.send_mid);
            var grpRewordData = reworkData.GroupBy(g => g.User_Id);

            var temp = new List<ResponseSumQmsDataCount>();
            foreach (var m in grpMaterial)
            {

                temp.Add(new ResponseSumQmsDataCount
                {
                    Section = m.FirstOrDefault().SectionID,
                    id = m.Key,
                    IncomInspect = m.ToList().Count
                });
            }
            foreach (var m in grpCheckInsp)
            {
                temp.Add(new ResponseSumQmsDataCount
                {
                    id = m.Key,
                    Section = m.FirstOrDefault().sectionid,
                    ProcessInspect = m.Where(f => f.inspection_type == 2).Count(),
                    LabInspect = m.Where(f => f.inspection_type == 1).Count(),
                });
            }
            foreach (var r in grpRewordData)
            {
                temp.Add(new ResponseSumQmsDataCount
                {
                    id = r.Key,
                    Section = r.FirstOrDefault().Section_Id,
                    Rework = r.Where(f => f.Type == 1).Count(),
                    Waste = r.Where(f => f.Type == 2).Count()
                });
            }

            var grpResult = temp.GroupBy(g => g.id);

            foreach (var g in grpResult)
            {
                var curObj = g.FirstOrDefault();
                result.Add(new ResponseSumQmsDataCount
                { 
                    id = g.Key,
                    Section=curObj.Section,
                    Title = string.Empty,
                    IncomInspect = g.Sum(s => s.IncomInspect),
                    ProcessInspect = g.Sum(s => s.ProcessInspect),
                    LabInspect = g.Sum(s => s.LabInspect),
                    Rework = g.Sum(s => s.Rework),
                    Waste = g.Sum(s => s.Waste),
                });
            }
            return result;
        }

        /// <summary>
        /// tbl5 安灯 责任部门
        /// </summary>
        /// <param name="andonData"></param>
        /// <returns></returns>
        public List<ResponseSumAndonDataCount> responseSumAndonsByDepart(IEnumerable<ResponseAndonDetials> andonData)
        {
            var result = new List<ResponseSumAndonDataCount>();

            var grpSectonData = andonData.GroupBy(g => g.station);
            foreach (var se in grpSectonData)
            {
                var andonInfo = se.ToList();
                var triger = andonInfo.Count();
                var sign = andonInfo.Where(f => f.status >= (int)AndonState.Handling).Count();
                var done = andonInfo.Where(f => f.status >= (int)AndonState.Complete).Count();
                double redo = andonInfo.Where(f => f.status >= (int)AndonState.Recovery).Count();
                var rate = 0d;
                if (triger > 0)
                    rate = Math.Round(redo / triger, 2) * 100;
                result.Add(new ResponseSumAndonDataCount
                {
                    Section = se.Key,
                    Title = se.FirstOrDefault().stationTitle,
                    Trigger = triger,
                    Sign = sign,
                    Done = done,
                    Redo = redo,
                    RateOfDone = rate.ToString()
                });
            }
            return result;
        }

        /// <summary>
        /// tbl6 岗位人员
        /// </summary>
        /// <param name="andonData"></param>
        /// <param name="userInfos"></param>
        /// <returns></returns>
        public List<ResponseSumAndonDataCount> responseSumAndonsByUser(IEnumerable<ResponseAndonDetials> andonData,IEnumerable<UserInfo> userInfos)
        {
            var result = new List<ResponseSumAndonDataCount>();
            var templst = new List<ResponseSumAndonDataCount>();
            var datacreate = andonData.GroupBy(g => g.creater);
            foreach (var d in datacreate)
            {
                var user = userInfos.FirstOrDefault(f=>f.mid==d.Key);
                if (user == null)
                    continue;
                var name = user != null ? user.name : "";
                var grpExctype = d.GroupBy(g => g.expectype);
                foreach (var type in grpExctype)
                {
                    var typeObj = type.FirstOrDefault();

                    templst.Add(new ResponseSumAndonDataCount
                    {
                        Title = $"{ typeObj.stationTitle}-{name}",
                        Trigger = type.Count(),
                    });
                }
            }
            var dataHandle = andonData.GroupBy(g => g.hanlder);
            foreach (var d in dataHandle)
            {
                var user = userInfos.FirstOrDefault(f => f.mid == d.Key);

                var name = user != null ? user.name : "";
                var grpExctype = d.GroupBy(g => g.expectype);
                foreach (var type in grpExctype)
                {
                    var typeObj = type.FirstOrDefault();
                    templst.Add(new ResponseSumAndonDataCount
                    {
                        Title = $"{ typeObj.stationTitle}-{name}",
                        Sign = type.Count(),
                    });
                }
            }
            var dataComplate = andonData.GroupBy(g => g.complater);
            foreach (var d in dataComplate)
            {

                var grpExctype = d.GroupBy(g => g.expectype);
                foreach (var type in grpExctype)
                {
                    var typeObj = type.FirstOrDefault();
                    templst.Add(new ResponseSumAndonDataCount
                    {
                        Title = $"{ typeObj.stationTitle}-{d.Key}",
                        Done = type.Count(),
                    });
                }
            }

            var dataRenew = andonData.GroupBy(g => g.approver);
            foreach (var d in dataRenew)
            {

                var grpExctype = d.GroupBy(g => g.expectype);
                foreach (var type in grpExctype)
                {
                    var typeObj = type.FirstOrDefault();
                    templst.Add(new ResponseSumAndonDataCount
                    {
                        Title = $"{ typeObj.stationTitle}-{d.Key}",
                        Redo = type.Count(),
                    });
                }
            }
            var grpTem = templst.GroupBy(g => g.Title);
            foreach (var g in grpTem)
            {
                result.Add(new ResponseSumAndonDataCount
                {
                    Title = g.Key,
                    Trigger = g.Sum(s => s.Trigger),
                    Sign = g.Sum(s => s.Sign),
                    Done = g.Sum(s => s.Done),
                    Redo = g.Sum(s => s.Redo)
                });
            }
            return result;
        }

        /// <summary>
        /// tbl8 异常时长 - 岗位
        /// </summary>
        /// <param name="andonData"></param>
        /// <returns></returns>
        public List<ResponseSumAndonExcepTime> sumAndonExcepTimeBysDepart(IEnumerable<ResponseAndonDetials> andonData)
        {
            var result = new List<ResponseSumAndonExcepTime>();
            var data = andonData.GroupBy(g => g.station).ToList();
            foreach (var d in data)
            {
                var sectionObj = d.FirstOrDefault();
                var handleData = d.ToList();
                var now = UnixTimeHelper.GetNow();
                var count = handleData.Count();
                var avgResponse = 0d; //平均响应
                var avgHandle = 0d; //平均处理
                var avgRenew = 0d;
                if (count != 0)
                {
                    avgRenew = handleData.Select(s => new { cost = (s.approve_time == 0 ? now : s.approve_time) - (s.complete_time == 0 ? now : s.complete_time) }).Sum(s => s.cost) / count;
                    avgHandle = handleData.Select(s => new { cost = (s.complete_time == 0 ? now : s.complete_time) - (s.handle_time == 0 ? now : s.handle_time) }).Sum(s => s.cost) / count;
                    avgResponse = handleData.Select(s => new { handle = (s.handle_time == 0 ? now : s.handle_time) - s.create_time }).Sum(s => s.handle) / count;
                }
                result.Add(new ResponseSumAndonExcepTime
                {
                    Title = sectionObj.stationTitle,
                    AvgAction = avgResponse,
                    AvgReWork = avgRenew,
                    AvgWorking = avgHandle
                });
            }
            return result;
        }

        /// <summary>
        /// tbl9 异常处理时长- 责任人
        /// </summary>
        /// <param name="andonDataSource"></param>
        /// <param name="userInfos"></param>
        /// <returns></returns>
        public List<ResponseSumAndonExcepTime> sumAndonExcepTimeByhandler(IEnumerable<ResponseAndonDetials> andonDataSource,IEnumerable<UserInfo> userInfos)
        {
            var result = new List<ResponseSumAndonExcepTime>();

            var templist = new List<ResponseSumAndonExcepTime>();

            var now = UnixTimeHelper.GetNow();

            var groupType = andonDataSource.GroupBy(g => g.expectype);
            foreach (var excptype in groupType)
            {
                var andonData = excptype.ToList();
                var ttResponse = andonData.Select(s => new { cost = (s.handle_time == 0 ? now : s.handle_time) - s.create_time }).Sum(s => s.cost);
                var ttHandle = andonData.Select(s => new { cost = (s.complete_time == 0 ? now : s.complete_time) - (s.handle_time == 0 ? now : s.handle_time) }).Sum(s => s.cost);
                var ttRenew = andonData.Select(s => new { cost = (s.approve_time == 0 ? now : s.approve_time) - (s.complete_time == 0 ? now : s.complete_time) }).Sum(s => s.cost);

                var dataHandle = andonData.GroupBy(g => g.hanlder).ToList();
                var reponseTime = 0L;
                if (ttResponse > 0)
                    reponseTime = ttResponse / dataHandle.Count; // 

                var dataComplate = andonData.GroupBy(g => g.complater).ToList();
                var handleTime = 0L;
                if (ttHandle > 0)
                    handleTime = ttHandle / dataComplate.Count; // 

                var dataRenew = andonData.GroupBy(g => g.approver).ToList();
                var renewTime = 0L;
                if (ttRenew > 0)
                    renewTime = ttRenew / dataRenew.Count; // 


                foreach (var d in dataHandle)
                {
                    var user = userInfos.FirstOrDefault(f=>f.mid==d.Key);
                    if (user == null)
                        continue;
                    var orderCnt = d.ToList().Count();
                    var grpExctype = d.GroupBy(g => g.expectype);
                    foreach (var type in grpExctype)
                    {
                        templist.Add(new ResponseSumAndonExcepTime
                        {
                            Title = $"{type.FirstOrDefault().stationTitle}-{user.name ?? ""}",
                            AvgAction = (reponseTime / orderCnt) / dataHandle.Count(),
                        });
                    }
                }
                foreach (var d in dataComplate)
                {
                    if (string.IsNullOrEmpty(d.Key))
                        continue;
                    var orderCnt = d.ToList().Count();
                    var grpExctype = d.GroupBy(g => g.expectype);
                    foreach (var type in grpExctype)
                    {
                        templist.Add(new ResponseSumAndonExcepTime
                        {
                            Title = $"{type.FirstOrDefault().stationTitle}-{d.Key}",
                            AvgWorking = (handleTime / orderCnt) / dataComplate.Count(),
                        });
                    }
                }
                foreach (var d in dataRenew)
                {
                    if (string.IsNullOrEmpty(d.Key))
                        continue;
                    var orderCnt = d.ToList().Count();
                    var grpExctype = d.GroupBy(g => g.expectype);
                    foreach (var type in grpExctype)
                    {
                        templist.Add(new ResponseSumAndonExcepTime
                        {
                            Title = $"{type.FirstOrDefault().stationTitle}-{d.Key}",
                            AvgReWork = (renewTime / orderCnt) / dataRenew.Count(),
                        });
                    }
                }
            }

            var grpUsr = templist.GroupBy(g => g.Title);
            foreach (var grp in grpUsr)
            {
                result.Add(new ResponseSumAndonExcepTime
                {
                    Title = grp.Key,
                    AvgAction = grp.Sum(s => s.AvgAction),
                    AvgWorking = grp.Sum(s => s.AvgWorking),
                    AvgReWork = grp.Sum(s => s.AvgReWork)
                });
            }

            return result;
        }

   

        public void Dispose()
        {
          
        }

    }
}
