using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiDashboard.Utilities;
using Siger.Middlelayer.AccRepository.Repositories.Interface;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.DashboardRepository.Response;
using Siger.Middlelayer.KpiRespository.Repositories.Interface;
using Siger.Middlelayer.QmsRepository.Repositories.Interface;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.TpmRepository.Repositories.Interface;
using Siger.Middlelayer.TpmRepository.Response;
using ICheckSnTraceInspectionRepository = Siger.Middlelayer.QmsRepository.Repositories.Interface.ICheckSnTraceInspectionRepository;

namespace Siger.ApiDashboard.Controllers
{

    public class DashboardSumController : BaseController
    {
        private readonly ICheckSnTraceMaterialRepository _checkSnTraceMaterial;
        private readonly ICheckSnTraceInspectionRepository _checkSnTraceInspection;
        private readonly ISigerProjectLevelSectionRepository _sigerProjectLevelSection;
        private readonly IQmsReworkDataRepository _qmsReworkData;
        private readonly IQmsReworkDataMaterialRepository _qmsReworkDataMaterial;
        private readonly ISigerProjectUserRepository _sigerProjectUser;
        private readonly ISigerAndonInfoRepository _sigerAndonInfo;
        private readonly ISigerAndonInfoDetailRepository _sigerAndonInfoDetail;
        private readonly ISigerTrSnTraceRepository _sigerTrSnTrace;
        private readonly IQmsBarcodeBatchRepository _qmsBarcodeBatch;
        private readonly ISigerKpiTasklist _kpiTasklist;
        private readonly ISigerProjectSectionRepository _sigerProjectSection;
        private readonly ISigerKpiAction _sigerKpiAction;
        private readonly IRepairRepository _repairRepository;

        public DashboardSumController(ICheckSnTraceMaterialRepository checkSnTraceMaterial, ICheckSnTraceInspectionRepository checkSnTraceInspection, ISigerProjectLevelSectionRepository sigerProjectLevelSection, IQmsReworkDataRepository qmsReworkData, IQmsReworkDataMaterialRepository qmsReworkDataMaterial, ISigerProjectUserRepository sigerProjectUser
            , ISigerAndonInfoRepository sigerAndonInfo, ISigerAndonInfoDetailRepository sigerAndonInfoDetail, ISigerTrSnTraceRepository sigerTrSnTrace, IQmsBarcodeBatchRepository qmsBarcodeBatch, ISigerKpiTasklist kpiTasklist, ISigerProjectSectionRepository sigerProjectSection, ISigerKpiAction sigerKpiAction, IRepairRepository repairRepository
            )
        {
            _checkSnTraceMaterial = checkSnTraceMaterial;
            _checkSnTraceInspection = checkSnTraceInspection;
            _sigerProjectLevelSection = sigerProjectLevelSection;
            _qmsReworkData = qmsReworkData;
            _qmsReworkDataMaterial = qmsReworkDataMaterial;
            _sigerProjectUser = sigerProjectUser;
            _sigerAndonInfo = sigerAndonInfo;
            _sigerAndonInfoDetail = sigerAndonInfoDetail;
            _sigerTrSnTrace = sigerTrSnTrace;
            _qmsBarcodeBatch = qmsBarcodeBatch;
            _kpiTasklist = kpiTasklist;
            _sigerProjectSection = sigerProjectSection;
            _sigerKpiAction = sigerKpiAction;
            _repairRepository = repairRepository;
        }
        [HttpGet]
        public IActionResult GetData(string dtstart, string dtend)
        {
            if (string.IsNullOrEmpty(dtstart) || string.IsNullOrEmpty(dtend))
                throw new BadRequestException(RequestEnum.ParameterError);

            var ret = new ResponseSum();
            DateTime.TryParse(dtstart, out DateTime begin);
            DateTime.TryParse(dtend, out DateTime end);

            var beginTime = UnixTimeHelper.ConvertDataTimeLong(begin);
            var endTime = UnixTimeHelper.ConvertDataTimeLong(end);

            var lines = _sigerProjectLevelSection.GetAccLines(ProjectId);

            foreach (var chanel in lines)
            {
                var stations = _sigerProjectLevelSection.GetLevelSectionIds(chanel.id, ProjectId).ToList();
                var checkMaterial = _checkSnTraceMaterial.GetList(f => f.projectid == ProjectId && stations.Contains(f.SectionID) && f.CreateTime >= begin && f.CreateTime <= end);
                var checkInspData = _checkSnTraceInspection.GetList(f => f.projectid == ProjectId && stations.Contains(f.sectionid) && f.send_time >= begin && f.send_time <= end);
                var reworkData = _qmsReworkData.GetList(f => f.projectid == ProjectId && stations.Contains(f.Section_Id) && f.DateTime >= begin && f.DateTime <= end);
 
                // 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)
                {
                    ret.QmsCount.Add(new ResponseSumQmsDataCount
                    {
                        Section = chanel.id,
                        Title = chanel.title,
                        IncomInspect = incomInspCnt,
                        ProcessInspect = proceInspCnt,
                        LabInspect = labInspCnt,
                        LabInspectCompalte = labComplateCnt,
                        Rework = reworkCnt,
                        Waste = wasteCnt
                    });
                }
                //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)
                {
                    ret.QmsPerson.Add(new ResponseSumQmsDataCount
                    {
                        Section = chanel.id,
                        Title = chanel.title,
                        IncomInspect = inspPersonCnt,
                        ProcessInspect = procPersonCnt,
                        LabInspect = labInspPersonCnt,
                        LabInspectCompalte = labCompPersonCnt,
                        Rework = reworkPersonCnt,
                        Waste = wastePersonCnt
                    });
                }
                //tbl3 操作人员录入数据量

                //tbl4 andon 通道操作数据
                var andonInfo = _sigerAndonInfo.GetList(f => f.projectid == ProjectId && stations.Contains(f.station) && f.create_time >= beginTime && f.create_time <= endTime && f.status> (int)AndonState.Abnormal && f.status<= (int)AndonState.CancleAbnormal);
                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)
                {
                    ret.AndonCount.Add(new ResponseSumAndonDataCount
                    {
                        Section = chanel.id,
                        Title = chanel.title,
                        Trigger = triger,
                        Sign = sign,
                        Done = done,
                        Redo = redo,
                        RateOfDone = 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)
                {
                    ret.AndonExcepTimeBySection.Add(new ResponseSumAndonExcepTime
                    {
                        Title = chanel.title,
                        AvgAction = avgResponse,
                        AvgWorking = avgHandle,
                        AvgReWork = avgRenew
                    });
                }

                //tbl10 追溯数据通道
                var traceData = _sigerTrSnTrace.GetList(f => f.projectId == ProjectId && stations.Contains(f.Station) && f.TransDateTime >= begin && f.TransDateTime <= end);

                var traceCount = traceData.Count();
                if (traceCount > 0)
                {
                    ret.traceData.Add(new ResponseSumTraceData
                    {
                        Title = chanel.title,
                        Sigle = traceCount,
                        Batch = 0,
                    });
                }
            }

            #region Tbl3  质量模块人员数据录入量
            var checkMaterials = _checkSnTraceMaterial.GetList(f => f.projectid == ProjectId && f.CreateTime >= begin && f.CreateTime <= end);
            var checkInspDatas = _checkSnTraceInspection.GetList(f => f.projectid == ProjectId && f.send_time >= begin && f.send_time <= end);
            var reworkDatas = _qmsReworkData.GetList(f => f.projectid == ProjectId && f.DateTime >= begin && f.DateTime <= end);

            ret.QmsPersonData = ReportSumHelper.Instance.qmsPersonData(checkMaterials, checkInspDatas, reworkDatas);
            #endregion

            //安灯待接单开始数据
            var andonData = _sigerAndonInfo.AndonDetials(ProjectId, beginTime, endTime, (int)AndonState.Abnormal);
            var userInfos = _sigerProjectUser.GetUserInfoList(ProjectId);


            #region tbl5  安灯模块异常类别数据量
            ret.AndonType = ReportSumHelper.Instance.responseSumAndonsByDepart(andonData);
            #endregion

            #region tbl6 安灯模块人员数据量
            ret.AndonPersonData = ReportSumHelper.Instance.responseSumAndonsByUser(andonData, userInfos);
            #endregion

            //安灯完成数据
            var andonDataComplated = _sigerAndonInfo.AndonDetials(ProjectId, beginTime, endTime, (int)AndonState.Approve);
            #region tbl8 异常处理时长-责任部门
            ret.AndonExcepTimeByDepart = ReportSumHelper.Instance.sumAndonExcepTimeBysDepart(andonDataComplated);
            #endregion


            #region tbl9 异常处理时长- 责任人
            ret.AndonExcepTimeByPerson = ReportSumHelper.Instance.sumAndonExcepTimeByhandler(andonDataComplated,userInfos);
            #endregion

            #region tbl11 kpi 汇总
            ret.KpisInfo = GetSumKpis(begin, end);
            #endregion

            #region TPM 汇总tabl12,13
            var tpmData = _repairRepository.GetRepairWorkCount(beginTime, endTime, ProjectId);
            foreach(var tpm in tpmData)
            {
                ret.TpmInfoOrder.Add(new ResponseSumTpm
                {
                    Title=tpm.title,
                    Repairt = tpm.handle,
                    Sign = tpm.sign,
                    Done = tpm.complete,
                    PlanPart = tpm.sparepart
                });
                ret.TpmInfoPerson.Add(new ResponseSumTpm
                {
                    Title = tpm.title,
                    Repairt = tpm.handle_count,
                    Sign = tpm.sign_count,
                    Done = tpm.complete_count,
                    PlanPart = tpm.sparepart
                });

            }

            #endregion

            return new ObjectResult(ret);
        }

        /// <summary>
        /// Kpi 数据
        /// </summary>
        /// <param name="begin"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private List<ResponseSumKpi> GetSumKpis(DateTime begin ,DateTime end)
        {
            var result = new List<ResponseSumKpi>();
            var data = _kpiTasklist.GetList(f => f.projectId == ProjectId && f.Busidate >= begin && f.Busidate <= end);
            var grpSection = data.GroupBy(g => g.Section);
            foreach(var section in grpSection)
            {
                var sectionObj = _sigerProjectSection.Get(f => f.projectid == ProjectId && f.id == section.Key);
                var sectionList = section.ToList();
                var normal = sectionList.Where(f => f.Result ==  Middlelayer.Share.ModuleEnum.KpiTaskResult.Normal);
                var excep = sectionList.Where(f => f.Result == Middlelayer.Share.ModuleEnum.KpiTaskResult.Exception);
                var notCfg = sectionList.Where(f => f.Result == Middlelayer.Share.ModuleEnum.KpiTaskResult.NoConfg);

                var taskIds = excep.Select(s => s.id).ToList();
                var actionList = _kpiTasklist.GetActionResult(ProjectId,taskIds);
                result.Add(new ResponseSumKpi
                {
                    Title = sectionObj.title,
                    Normal = normal.Count(),
                    Exception = excep.Count(),
                    NotCfg = notCfg.Count(),
                    NotAction = excep.Where(f => f.Excption ==  Middlelayer.Share.ModuleEnum.KpiExecption.Default).Count(),
                    Pending = excep.Where(f => f.Excption == Middlelayer.Share.ModuleEnum.KpiExecption.Processing).Count(),
                    Closed = excep.Where(f => f.Excption == Middlelayer.Share.ModuleEnum.KpiExecption.Complated).Count(),
                    LateAction= actionList.Where(f=>f.Expire==1).Count()
                }) ;
            }
            return result;
        }


    }
}
