using HighWayIot.Log4net;
using HighWayIot.Repository.domain;
using HighWayIot.Repository.service;
using HighWayIot.Winform.Business;
using Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Timer = System.Threading.Timer;

namespace HighWayIot.Winform.UserControlPages
{
    public partial class MonitorMainPage : UserControl
    {
        LogHelper logHelper = LogHelper.Instance;

        /// <summary>
        /// 班次服务类
        /// </summary>
        private SysShiftTimeService _shiftTimeService = SysShiftTimeService.Instance;

        /// <summary>
        /// 报表服务类
        /// </summary>
        private ZxDailyReportService _zxDailyReportService = ZxDailyReportService.Instance;

        /// <summary>
        /// datagridview 数据源
        /// 必须使用BindingList， 如果使用LIST，无法实现更改，添加、删除数据源自动更新datagridview
        /// </summary>
        //private BindingList<MonitorDataSource> _monitorDataSources = new BindingList<MonitorDataSource>();

        private List<MonitorDataSource> _monitorDataSources = new List<MonitorDataSource>();

        private DateTime DayStartTime;

        private DateTime DayEndTine;

        private DateTime NightStartTime;

        private DateTime NightEndTime;

        public static Action MonitorRefreshAction;

        /// <summary>
        /// 前端刷新锁
        /// </summary>
        private static readonly object GridRefreshLocker = new object();

        public MonitorMainPage()
        {
            InitializeComponent();

            MonitorDataGridView.AutoGenerateColumns = false;

            DateTimeRefresh();

            MonitorRefreshAction += BindData;
            MonitorRefreshAction.Invoke();
        }

        /// <summary>
        /// TImer事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DataRefresh_Tick(object sender, EventArgs e)
        {
            if (DateTime.Now.Second == 0)
            {
                DateTimeRefresh();
            }
        }

        /// <summary>
        /// 白夜班时间，现在时间控件刷新
        /// </summary>
        private void DateTimeRefresh()
        {
            var timeList = _shiftTimeService.GetShiftInfos();
            var morningShift = timeList.Where(x => x.ShiftName == "早").FirstOrDefault();
            var midShift = timeList.Where(x => x.ShiftName == "中").FirstOrDefault();
            var nightShift = timeList.Where(x => x.ShiftName == "夜").FirstOrDefault();

            if (morningShift == null || midShift == null || nightShift == null)
            {
                logHelper.Error("检查班次数据库是否早中夜班配置齐全！");
                return;
            }

            DateTime Today = DateTime.Now.Date;
            var startArray = morningShift.ShiftStartTime.Split(':');
            var endArray = midShift.ShiftEndTime.Split(':');
            if (startArray.Length != 3 || endArray.Length != 3)
            {
                return;
            }
            TimeSpan StartTime = new TimeSpan(Convert.ToInt32(startArray[0]), Convert.ToInt32(startArray[1]), Convert.ToInt32(startArray[2]));
            TimeSpan EndTime = new TimeSpan(Convert.ToInt32(endArray[0]), Convert.ToInt32(endArray[1]), Convert.ToInt32(endArray[2]));
            if (DateTime.Now.TimeOfDay > StartTime && DateTime.Now.TimeOfDay < EndTime)
            {//白班
                DayStartTime = DateTime.Now.Date + StartTime;
                DayEndTine = DateTime.Now.Date + EndTime;
                NightStartTime = DateTime.Now.Date - TimeSpan.FromDays(1) + EndTime;
                NightEndTime = DateTime.Now.Date + StartTime;
            }
            else
            {//夜班
                if (DateTime.Now.TimeOfDay < StartTime) //前半夜
                {
                    DayStartTime = DateTime.Now.Date + StartTime;
                    DayEndTine = DateTime.Now.Date + EndTime;
                    NightStartTime = DateTime.Now.Date + EndTime;
                    NightEndTime = DateTime.Now + TimeSpan.FromDays(1) + StartTime;
                }
                else if (DateTime.Now.TimeOfDay > EndTime) //后半夜
                {
                    DayStartTime = DateTime.Now.Date - TimeSpan.FromDays(1) + StartTime;
                    DayEndTine = DateTime.Now.Date - TimeSpan.FromDays(1) + EndTime;
                    NightStartTime = DateTime.Now.Date - TimeSpan.FromDays(1) + EndTime;
                    NightEndTime = DateTime.Now + StartTime;
                }
            }

            string dayString = morningShift.ShiftStartTime.Substring(0, 5) + "-" + midShift.ShiftEndTime.Substring(0, 5);
            string nightString = nightShift.ShiftStartTime.Substring(0, 5) + "-" + nightShift.ShiftEndTime.Substring(0, 5);
            DayTimeLabel.Text = dayString;
            NightTimeLabel.Text = nightString;

            NowDateProductNumLabel.Text = DateTime.Now.ToString("MM 月 dd 日 产量");
        }

        /// <summary>
        /// 数据刷新
        /// </summary>
        private void BindData()
        {
            lock (GridRefreshLocker)
            {
                List<ZxDailyReportEntity> dailyEntity = _zxDailyReportService.GetOneDayDailyReportInfos();
                _monitorDataSources.Clear();
                if (dailyEntity == null)
                {
                    return;
                }
                for (int i = 0; i < dailyEntity.Count; i++)
                {
                    _monitorDataSources.Add(new MonitorDataSource()
                    {
                        No = i + 1,
                        VulcanizationNo = dailyEntity[i].VulcanizationNo,
                        StartTime = dailyEntity[i].StartTime.ToString("MM月dd日 HH:mm:ss"),
                        RecipeName = dailyEntity[i].RecipeName,
                        RecipeCode = dailyEntity[i].RecipeCode,
                        SpecCode = dailyEntity[i].SpecCode,
                        DeviceNo = dailyEntity[i].DeviceNo.ToString(),
                        RawTireWeight = dailyEntity[i].RawTireWeight ?? 0,
                        BaseRubTimeSpan = GeneralUtils.DateTimeToString(dailyEntity[i].StartTime, dailyEntity[i].BaseEndTime),
                        MidRubTimeSpan = GeneralUtils.DateTimeToString(dailyEntity[i].StartTime, dailyEntity[i].MidEndTime),
                        FaceRubTimeSpan = GeneralUtils.DateTimeToString(dailyEntity[i].StartTime, dailyEntity[i].FaceEndTime),
                        RepeatWeight = dailyEntity[i].RepeatWeight ?? 0,
                        IsDone = dailyEntity[i].IsDone == 1 ? "已完成" : "未完成"
                    });
                }

                MonitorDataGridView.DataSource = null;
                MonitorDataGridView.DataSource = _monitorDataSources;

                int daycount = dailyEntity.Count(x => x.StartTime >= DayStartTime && x.StartTime <= DayEndTine && x.IsDone == 1);
                DayProductNumTextBox.Text = daycount.ToString();
                int nightcount = dailyEntity.Count(x => x.StartTime >= NightStartTime && x.StartTime <= NightEndTime && x.IsDone == 1);
                NightProductNumTextBox.Text = nightcount.ToString();
                NowDateProductNumTextBox.Text = (daycount + nightcount).ToString();

                ZxDailyReportEntity first = dailyEntity.FirstOrDefault();
                if (first == null)
                {
                    return;
                }
                RecipeCodeLabel.Text = first.RecipeCode;
                SpecCodeLabel.Text = first.SpecCode;
                RecipeNameLabel.Text = first.RecipeName;
                ZxRecipeEntity recipeEntity = ZxRecipeService.Instance.GetRecipeInfosByRecipeCode(first.RecipeCode).FirstOrDefault();
                if (recipeEntity != null)
                {
                    SpecNameLabel.Text = recipeEntity.RecipeName;
                    ZxRecipeParaEntity paraEntity = ZxRecipeParaService.Instance.GetRecipeParaInfoByRecipeCode(recipeEntity.RecipeCode).FirstOrDefault();
                    if (paraEntity != null)
                    {
                        RawTireWeightLabel.Text = paraEntity.TireWeight.ToString();
                    }
                }
                RgvNoLabel.Text = first.DeviceNo.ToString();

            }

        }

    }
}
