using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.Middlelayer.Dapper;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.DashboardRepository.Repositories.Interface;
using Siger.Middlelayer.QmsRepository.Repositories.Interface;
using Siger.Middlelayer.Share.Enum.ModuleEnum;
using Siger.Middlelayer.DashboardRepository.Response;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.ApiCommon.Filters;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.DashboardRepository.Request;
using Siger.Middlelayer.Common.Extensions;
using FluentScheduler;
using Siger.Middlelayer.TpmRepository.Repositories.Interface;
using Siger.ApiDashboard.Utilities;
using Siger.Middlelayer.Dapper.ResultData;

namespace Siger.ApiDashboard.Controllers
{
    /// <summary>
    /// 通道 动态看板
    /// </summary>
    public class DashboardChanelController : BaseController
    {
        private readonly IDashboardLevelRepository _dashboardLevelRepository;
        private readonly IQmsReworkDataRepository _qmsReworkDataRepository;
        private readonly ISigerProjectLevelSectionRepository _sigerProjectLevelSection;
        private readonly ISigerProjectAutoCalculationTotal _autoCalculationTotal;
        private readonly ISigerAndonInfoRepository _andonInfoRepository;
        private readonly OeeHelper _oeeHelper;

        public DashboardChanelController(IUnitOfWork unitOfWork, IDashboardLevelRepository dashboardLevel, IQmsReworkDataRepository qmsReworkData
            , ISigerProjectLevelSectionRepository sigerProjectLevelSection, ISigerProjectAutoCalculationTotal autoCalculationTotal,
            ISigerAndonInfoRepository andonInfoRepository, OeeHelper oeeHelper)
        {
            _dashboardLevelRepository = dashboardLevel;
            _qmsReworkDataRepository = qmsReworkData;
            _sigerProjectLevelSection = sigerProjectLevelSection;
            _autoCalculationTotal = autoCalculationTotal;
            _andonInfoRepository = andonInfoRepository;
            _oeeHelper = oeeHelper;
        }

        /// <summary>
        /// 获取 每小时 产出 数据
        /// </summary>
        /// <param name="section">产线 ID</param>
        /// <param name="date"></param>
        /// <param name="starttime"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetProduceHour(int section, string date, string starttime)
        {
            var level = _sigerProjectLevelSection.Get(f => f.id == section);
            if (level == null)
                throw new BadRequestException(RequestEnum.LevelSectionNotFound);
            var result = new ResponseOutputHourlist();
            var projectId = ProjectId;


            DateTime dtStart = StartDate(date);
            //var schedu = 8; //8，12小时制
            var cfg = _dashboardLevelRepository.Get(f => f.ProjectId == projectId && f.Section == section && f.PageType == (int)DashboardEnum.Chanel);

            if (!int.TryParse(starttime, out int searchTime))
                searchTime = cfg == null ? 8 : cfg.Startime;

            var sections = _sigerProjectLevelSection.GetAccStationByline(ProjectId, section).Select(s => s.id).ToList();
            //var reworkData = _qmsReworkDataRepository.GetList(f => f.projectid == projectId && sections.Contains(f.Route_Id) && f.DateTime > dtStart && f.DateTime < dtEnd && f.status == (int)RowState.Valid).ToList();
            var bottleMachines = _dashboardLevelRepository.GetBottleSection(sections, ProjectId).ToList();

            var stepStartDate = dtStart.AddHours(searchTime);
            var stepEndDate = stepStartDate.AddHours(cfg.Schedu);

            DateTime dtDay;
            if (!bottleMachines.Any())
            {
                for (dtDay = stepStartDate; dtDay.CompareTo(stepEndDate) < 0; dtDay = dtDay.AddHours(1))
                {
                    var stepStarTime = dtDay;
                    var stepEndTime = dtDay.AddHours(1).AddSeconds(-1);
                    var hourTimeStamp = UnixTimeHelper.GetUnixByDate(stepStarTime.ToString());
                    if (stepStarTime > DateTime.Now || !bottleMachines.Any())
                    {
                        result.data.Add(new ResponseOutputHour
                        {
                            hour = stepStarTime.Hour,
                            product = "",
                            balance = 0d,
                            produce = 0d,
                            target = 0d,
                            hourTimeStamp = hourTimeStamp
                        });
                        continue;
                    }
                }
            }
            var bottle = bottleMachines.FirstOrDefault();
            //产量
            var yieldRepository = new LocationYieldRepository(CompanyId, ProjectId);
            //整理数据/小时


            var totalHourData = new List<LocationYield>();
            var reworkData = _qmsReworkDataRepository.GetList(f => f.projectid == projectId && sections.Contains(f.Route_Id) && f.DateTime >= stepStartDate && f.DateTime <= stepEndDate && f.status == (int)RowState.Valid).ToList();
          
            for (dtDay = stepStartDate; dtDay.CompareTo(stepEndDate) < 0; dtDay = dtDay.AddHours(1))
            {
                var stepStarTime = dtDay;
                var stepEndTime = dtDay.AddHours(1).AddSeconds(-1);
                var hourTimeStamp = UnixTimeHelper.GetUnixByDate(stepStarTime.ToString());
                if (stepStarTime > DateTime.Now )
                {
                    result.data.Add(new ResponseOutputHour
                    {
                        hour = stepStarTime.Hour,
                        product = "",
                        balance = 0d,
                        produce = 0d,
                        target = 0d,
                        hourTimeStamp = hourTimeStamp
                    });
                    continue;
                }
               
                var hourData = yieldRepository.GetLocationYields(bottleMachines, stepStarTime, stepEndTime).ToList();
                totalHourData.AddRange(hourData);
                var targetVal = _dashboardLevelRepository.BottleProductTarget(ProjectId, bottle, stepStarTime, stepEndTime);
                var productCount = hourData.Sum(s => s.yield);
                result.data.Add(new ResponseOutputHour
                {
                    hour = stepStarTime.Hour,
                    product = targetVal.Name,
                    balance = productCount - targetVal.Val,
                    produce = productCount,
                    target = targetVal.Val,
                    hourTimeStamp = hourTimeStamp
                });
            }

            result.emplCount = cfg == null ? 0 : cfg.EmplCount;
            result.total.productPlan = cfg == null ? "0" : cfg.Column4 ?? "0";
            result.total.rework = reworkData.Where(f => f.Type == (int)ReworkDataType.Rework).Sum(s => s.Count);
            result.total.waste = reworkData.Where(f => f.Type == (int)ReworkDataType.Waste).Sum(s => s.Count);
            result.total.produceTotal = result.data.Sum(s => s.produce);
            result.total.targetTotal = result.data.Sum(s => s.target);
            result.total.balanceTotal = result.data.Sum(s => s.balance);
            if (result.total.targetTotal > 0)
            {
                var oeeRet = _oeeHelper.GetOee(UnixTimeHelper.ConvertDataTimeLong(stepStartDate), UnixTimeHelper.ConvertDataTimeLong(stepEndDate), section, ProjectId, CompanyId, totalHourData, bottle);
                result.oee = oeeRet.Oee;//综合OEE
            }
            result.passRated = 0;
            return new ObjectResult(result);
        }

        /// <summary>
        /// 查询时间
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        DateTime StartDate(string date)
        {
            if (string.IsNullOrEmpty(date))
            {
                return DateTimeHelper.GetTodayStartTime();
            }

            if (!DateTime.TryParse(date, out DateTime dt))
                return DateTimeHelper.GetTodayStartTime();
            return DateTimeHelper.GetTodayStartTime(dt);

        }

        //[NoTokenValidateFilter]
        [HttpPost]
        public IActionResult GetOeeSummary([FromBody] RequestOeeSummary request)
        {
            var pid = ProjectId;
            var ret = new ResponseOeeSumary();
            var type = request.type.ToInt();
            var x_type = request.x_type.ToInt();
            var dtEnd = DateTimeHelper.GetTodayStartTime();
            var interval = 0;
            var datetimes = new List<DateTime>();
            DateTime endttime = dtEnd;
            DateTime starttime;
            switch (type)
            {
                case 1://7天
                    interval = DateTimeHelper.GetInteral(0);
                    starttime = dtEnd.AddDays(-interval * 7);
                    datetimes = DateTimeHelper.GetDateTimes(starttime, dtEnd, 0);
                    break;
                case 2://昨天
                    starttime = DateTimeHelper.GetTodayStartTime().AddDays(-1);
                    endttime = starttime.AddDays(1).AddSeconds(-1);
                    datetimes.Add(starttime);
                    break;
                case 3://七周
                    interval = DateTimeHelper.GetInteral(1);
                    starttime = dtEnd.AddDays(-interval * 7);
                    datetimes = DateTimeHelper.GetDateTimes(starttime, dtEnd, 1);
                    break;
                case 4://1月
                    interval = DateTimeHelper.GetInteral(2);
                    starttime = dtEnd.AddDays(-interval);
                    datetimes = DateTimeHelper.GetDateTimes(starttime, dtEnd, 2);
                    break;
                default:
                    starttime = DateTimeHelper.GetTodayStartTime();
                    endttime = starttime.AddDays(1).AddSeconds(-1);
                    datetimes.Add(DateTimeHelper.GetTodayStartTime());
                    break;
            }
            if (!request.section.Any())
            {
                request.section = _sigerProjectLevelSection.GetAccLines(pid).Select(s => s.id).ToList();
            }
            var oeeInfo = _andonInfoRepository.GetOee(starttime, endttime, request.section);

            var totalTarget = 0d;
            if (oeeInfo.Any())
            {
                totalTarget = oeeInfo.Sum(s => s.denominator);
                ret.total = Math.Round((oeeInfo.Sum(s => s.numerator) / totalTarget) * 100, 2);
                if (totalTarget == 0)
                {
                    ret.total = 0d;
                }
            }
            else
            {
                ret.total = 0d;
                return new ObjectResult(ret);
            }
            if (x_type == 0)
            {
                for (int i = 0; i < datetimes.Count(); i++)
                {
                    var start = datetimes[i];
                    var end = datetimes[i].AddDays(1).AddSeconds(-1);
                    if (type == 3)
                    {
                        end = datetimes[i].AddDays(7).AddSeconds(-1);
                    }
                    else if (type == 4)
                    {
                        end = datetimes[i].AddDays(30).AddSeconds(-1);
                    }
                    var item = new ResponseOeeSumaryData();
                    if (type == 4)
                    {
                        item.name = datetimes[i].ToString(ParameterConstant.YearMonthFormat);
                    }
                    else
                    {
                        item.name = datetimes[i].ToString(ParameterConstant.DateFormat);
                    }
                    var target = oeeInfo.Where(f => f.busidate >= start && f.busidate <= end).Sum(s => s.denominator);
                    var actual = oeeInfo.Where(f => f.busidate >= start && f.busidate <= end).Sum(s => s.numerator);
                    var avg = 0d;
                    if (target != 0)
                    {
                        avg = actual / target;
                    }
                    item.number = Math.Round(avg * 100, 2);
                    ret.data.Add(item);
                }
            }
            else
            {
                var lines = _sigerProjectLevelSection.GetAccLines(pid).ToList();
                if (request.section.Any())
                {
                    lines = lines.Where(f => request.section.Contains(f.id)).ToList();
                }
                foreach (var line in lines)
                {
                    var item = new ResponseOeeSumaryData();
                    item.name = line.title;
                    var target = oeeInfo.Where(f => f.section == line.id).Sum(s => s.denominator);
                    var actual = oeeInfo.Where(f => f.section == line.id).Sum(s => s.numerator);
                    item.number = Math.Round((actual / target) * 100, 2);
                    ret.data.Add(item);
                }
            }
            if (ret.data.Any())
            {
                ret.X.AddRange(ret.data.Select(s => s.name).ToList());
                ret.Y.AddRange(ret.data.Select(s => s.number).ToList());
            }
            return new ObjectResult(ret);
        }

    }
}
