using Siger.ApiDashboard.Tasks.Model;
using Siger.ApiDashboard.Utilities;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Share.Models;
using Siger.Middlelayer.Share.ModuleEnum;
using System;
using System.Linq;

namespace Siger.ApiDashboard.Tasks.Reports
{

    /// <summary>
    /// 拼接数据
    /// </summary>
    public class MouduleUtilizationComm
    {

        /// <summary>
        /// 获取使用率模板数据对象
        /// </summary>
        /// <param name="monthReport"></param>
        /// <param name="config"></param>
        /// <param name="template"></param>
        /// <param name="timeRange"></param>
        /// <returns></returns>
        public static UsageReportResult GetResponseSum(MonthReportHelper monthReport, siger_project_monthreport_config config, siger_project_monthreport_config_template template, TimeRange timeRange)
        {
            var result = new UsageReportResult { title = template.title };

            var lines = monthReport.GetAccLines(config.project_id);

            var beginTime = UnixTimeHelper.ConvertDataTimeLong(timeRange.StartTime);
            var endTime = UnixTimeHelper.ConvertDataTimeLong(timeRange.EndTime);

            foreach (var  chanel in lines)
            {
                var stations = monthReport.GetLevelSectionIds(chanel.id, config.project_id).ToList();

                var checkMaterial = monthReport.GetTraceMaterial(config.project_id, stations, timeRange.StartTime, timeRange.EndTime);
                var checkInspData=monthReport.GetTraceInspection(config.project_id, stations, timeRange.StartTime, timeRange.EndTime);
                var reworkData=monthReport.GetReworkDat(config.project_id, stations, timeRange.StartTime, timeRange.EndTime);
                // tbl1 数据量
                var incomInspCnt = checkMaterial.Count();
                var proceInspCnt = checkInspData.Where(f => f.inspection_type == 2).Count();
                var labInspCnt = checkInspData.Where(f => f.inspection_type == 1).Count();
                var labComplateCnt = checkInspData.Where(f => f.inspection_type == 1 && f.check_status == 2).Count();
                var reworkCnt = reworkData.Where(f => f.Type == 1).Count();
                var wasteCnt = reworkData.Where(f => f.Type == 2).Count();
                if (incomInspCnt > 0 || proceInspCnt > 0 || proceInspCnt > 0 || labInspCnt > 0 || labComplateCnt > 0 || reworkCnt > 0 || wasteCnt > 0)
                {
                    result.table_1.Add(new TableColumns
                    {
                        one = chanel.title,
                        two = incomInspCnt.ToStr(),
                        three = proceInspCnt.ToStr(),
                        four = labInspCnt.ToStr(),
                        five = labComplateCnt.ToStr(),
                        six = reworkCnt.ToStr(),
                        seven = wasteCnt.ToStr(),
                    });
                }

                //tbl2 操作人数
                var inspPersonCnt = checkMaterial.GroupBy(g => g.UserID).Count();
                var procPersonCnt = checkInspData.Where(f => f.inspection_type == 2).GroupBy(g => g.send_mid).Count();
                var labInspPersonCnt = checkInspData.Where(f => f.inspection_type == 1).GroupBy(g => g.send_mid).Count();
                var labCompPersonCnt = checkInspData.Where(f => f.inspection_type == 1 && f.check_status == 2).GroupBy(g => g.send_mid).Count();
                var reworkPersonCnt = reworkData.Where(f => f.Type == 1).GroupBy(g => g.User_Id).Count();
                var wastePersonCnt = reworkData.Where(f => f.Type == 2).GroupBy(g => g.User_Id).Count();
                if (inspPersonCnt > 0 || procPersonCnt > 0 || labInspPersonCnt > 0 || labCompPersonCnt > 0 || reworkPersonCnt > 0 || wastePersonCnt > 0)
                {
                    result.table_2.Add(new TableColumns
                    {
                        one = chanel.title,
                        two = inspPersonCnt.ToStr(),
                        three = procPersonCnt.ToStr(),
                        four = labInspPersonCnt.ToStr(),
                        five = labCompPersonCnt.ToStr(),
                        six = reworkPersonCnt.ToStr(),
                        seven = wastePersonCnt.ToStr()
                    });
                }

                //tbl4 andon 通道操作数据
                var andonInfo =monthReport.GetAndonInfo(config.project_id, stations, beginTime, endTime);
                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;
                if (triger > 0 || sign > 0 || done > 0 || redo > 0)
                {
                    result.table_4.Add(new TableColumns
                    {
                      
                        one = chanel.title,
                        two = triger.ToStr(),
                        three = sign.ToStr(),
                        four = done.ToStr(),
                        five = redo.ToStr(),
                        six = rate.ToString()
                    });
                }
                var handleData = andonInfo.Where(f => f.status >= (int)AndonState.Recovery);
                //tbl7 异常处理时长-通道
                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;

                }
                if (avgResponse > 0 || avgHandle > 0 || avgRenew > 0)
                {
                    result.table_7.Add(new TableColumns
                    {
                        one = chanel.title,
                        two = avgResponse.ToStr(),
                        three = avgHandle.ToStr(),
                        four = avgRenew.ToStr()
                    });
                }

                //tbl10 追溯数据通道
                var traceData = monthReport.GetSnTrace(config.project_id, stations, timeRange.StartTime, timeRange.EndTime);

                var traceCount = traceData.Count();
                if (traceCount > 0)
                {
                    result.table_10.Add(new TableColumns
                    {
                        one = chanel.title,
                        two = traceCount.ToStr(),
                        three = "0",
                    });
                }

            }

            var stationIds = monthReport.GetLevelSectionIds(0, config.project_id).ToList();
            #region Tbl3  质量模块人员数据录入量
            var checkMaterials = monthReport.GetTraceMaterial(config.project_id, stationIds, timeRange.StartTime, timeRange.EndTime);
            var checkInspDatas = monthReport.GetTraceInspection(config.project_id, stationIds, timeRange.StartTime, timeRange.EndTime);
            var reworkDatas = monthReport.GetReworkDat(config.project_id, stationIds, timeRange.StartTime, timeRange.EndTime);

            var qmsPerData = ReportSumHelper.Instance.qmsPersonData(checkMaterials, checkInspDatas, reworkDatas);
            foreach(var p in qmsPerData)
            {
                result.table_3.Add(new TableColumns
                {
                     one=p.Title,
                     two=p.IncomInspect.ToStr(),
                     three=p.ProcessInspect.ToStr(),
                     four=p.LabInspect.ToStr(),
                     five=p.Rework.ToStr(),
                     six=p.Waste.ToStr()
                });
            }

            #endregion

            //安灯待接单开始数据
            var andonData = monthReport.AndonDetials(config.project_id, beginTime, endTime, (int)AndonState.Abnormal);
            var userInfos = monthReport.GetUserInfoList(config.project_id);
            #region tbl5  安灯模块异常类别数据量
            var andonDepart = ReportSumHelper.Instance.responseSumAndonsByDepart(andonData);

            foreach(var d in andonDepart)
            {
                result.table_5.Add(new TableColumns
                {
                     one=d.Title,
                     two=d.Trigger.ToStr(),
                     three=d.Sign.ToStr(),
                     four=d.Done.ToStr(),
                     five=d.Redo.ToStr(),
                     six=d.RateOfDone.ToStr()
                });
            }
            #endregion

            #region tbl6 安灯模块人员数据量
            var sumAndonsByUser = ReportSumHelper.Instance.responseSumAndonsByUser(andonData, userInfos);
            foreach (var d in sumAndonsByUser)
            {
                result.table_6.Add(new TableColumns
                {
                    one = d.Title,
                    two = d.Trigger.ToStr(),
                    three = d.Sign.ToStr(),
                    four = d.Done.ToStr(),
                    five = d.Redo.ToStr()
                });
            }

            #endregion

            //安灯完成数据
            var andonDataComplated = monthReport.AndonDetials(config.project_id, beginTime, endTime, (int)AndonState.Approve);

            #region tbl8 异常处理时长-责任部门
            var excepTimeBysDepart = ReportSumHelper.Instance.sumAndonExcepTimeBysDepart(andonDataComplated);
            foreach(var d in excepTimeBysDepart)
            {
                result.table_6.Add(new TableColumns
                {
                    one = d.Title,
                    two = d.AvgAction.ToStr(),
                    three = d.AvgWorking.ToStr(),
                    four = d.AvgReWork.ToStr(),
                });
            }
            #endregion

            #region tbl9 异常处理时长- 责任人
            var excepTimeByhandler = ReportSumHelper.Instance.sumAndonExcepTimeByhandler(andonDataComplated, userInfos);
            foreach (var d in excepTimeByhandler)
            {
                result.table_6.Add(new TableColumns
                {
                    one = d.Title,
                    two = d.AvgAction.ToStr(),
                    three = d.AvgWorking.ToStr(),
                    four = d.AvgReWork.ToStr(),
                });
            }
            #endregion

            #region tbl11 kpi 汇总
            var data = monthReport.GetKpiTasklist(config.project_id, timeRange.StartTime, timeRange.EndTime);
            var grpSection = data.GroupBy(g => g.Section);
            foreach (var section in grpSection)
            {
                var sectionObj = monthReport.getSection(section.Key);
                var sectionList = section.ToList();
                var normal = sectionList.Where(f => f.Result == KpiTaskResult.Normal);
                var excep = sectionList.Where(f => f.Result == KpiTaskResult.Exception);
                var notCfg = sectionList.Where(f => f.Result == KpiTaskResult.NoConfg);

                var taskIds = excep.Select(s => s.id).ToList();
                var actionList = monthReport.GetActionResult(config.project_id, taskIds);
                result.table_11.Add(new  TableColumns
                {
                    one = sectionObj.title,
                    two = normal.Count().ToStr(),
                    three = excep.Count().ToStr(),
                    four = notCfg.Count().ToStr(),
                    five = excep.Where(f => f.Excption == KpiExecption.Default).Count().ToStr(),
                    six = excep.Where(f => f.Excption == KpiExecption.Processing).Count().ToStr(),
                    seven = excep.Where(f => f.Excption == KpiExecption.Complated).Count().ToStr(),
                    eight = actionList.Where(f => f.Expire == 1).Count().ToStr()
                });
            }

            #endregion

            #region TPM 汇总tabl12,13
            var tpmData = monthReport.GetRepairWorkCount(beginTime, endTime, config.project_id);
            foreach (var tpm in tpmData)
            {
                result.table_12.Add(new TableColumns
                {
                    one = tpm.title,
                    two = tpm.handle.ToStr(),
                    three = tpm.sign.ToStr(),
                    four = tpm.complete.ToStr(),
                    five = tpm.sparepart.ToStr()
                });
                result.table_12.Add(new TableColumns
                {
                    one = tpm.title,
                    two = tpm.handle_count.ToStr(),
                    three = tpm.sign_count.ToStr(),
                    four = tpm.complete_count.ToStr(),
                    five = tpm.sparepart.ToStr()
                });

            }
            #endregion

            return result;
        }

       
    }
}
