using FLY.OBJComponents.IService;
using MultiLayout.UiModule; 
using Misc;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using FLY.Thick.Base.UI;
using Unity;
using FLY.Thick.Base.Common;
using MultiLayout;
using System.Windows.Threading;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows;

namespace FLY.Thick.Base.UI.OnInit
{
    /// <summary>
    /// 监听 WarningSystemManager 的报警。  周期一个个显示 报警列表的内容
    /// </summary>
    public class OnInitWarnings : IOnInit
    {
        public int Level { get; private set; }


        WarningSystemManager warningSystemManager;
        IUnityContainer container;
        FlyLayoutManager flyLayoutManager;
        DispatcherTimer timer_error;
        int reason_list_index = -1;
        public OnInitWarnings(
            IUnityContainer container,
            FlyLayoutManager flyLayoutManager,
            WarningSystemManager warningSystemManager,
            ParamDictionary paramDictionary,
            int lv = 1) 
        {
            Level = lv;
            this.container = container;
            this.flyLayoutManager = flyLayoutManager;
            this.warningSystemManager = warningSystemManager;
            if (warningSystemManager.Warnings.Count() == 0)
                return;

            this.flyLayoutManager.ErrMsgClick = ErrMsg_OnClick;

        }
        public void OnInit()
        {
            if (warningSystemManager.Warnings.Count() == 0)
                return;

            warningSystemManager.PropertyChanged += WarningSystemManager_PropertyChanged;
            //报警原因轮流显示
            timer_error = new DispatcherTimer();
            timer_error.Interval = TimeSpan.FromSeconds(3);
            timer_error.Tick += (s, e) =>
            {
                reason_list_index--;
                if (reason_list_index < 0)
                    reason_list_index = warningSystemManager.Errors.Count();
                
                UpdateError();
            };
            UpdateError();
        }

        private void WarningSystemManager_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(warningSystemManager.Errors)) {
                reason_list_index = warningSystemManager.Errors.Count() - 1;
                UpdateError();
            }
        }
        void UpdateError() 
        {
            if (warningSystemManager.Errors.Count() == 0)
            {
                flyLayoutManager.ErrMsg = null;
                timer_error.Stop();
            }
            else {
                if (reason_list_index < 0)
                    reason_list_index = 0;
                else if (reason_list_index > warningSystemManager.Errors.Count() - 1) {
                    reason_list_index = warningSystemManager.Errors.Count() - 1;
                }

                var err = warningSystemManager.Errors[reason_list_index];
                flyLayoutManager.ErrMsg = $"{err.DevName} {err.Description}";
                timer_error.Start();
            }
        }
        private void ErrMsg_OnClick() {

            //打开管理页面

            //当管理页面已经打开，不能再次执行
            if (FlyLayoutManager.NavigationService.Content is PgErrorsTable) {
                return;
            }

            var p = container.Resolve<PgErrorsTable>();
            FlyLayoutManager.NavigationService.Navigate(p);
        }
    }


    /// <summary>
    /// 从 warnings.service 容器获取全部 报警服务， 把 全部报警服务的报警内容 整合到 Errors
    /// </summary>
    public class WarningSystemManager : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public List<WarningSystem2ServiceClientWithName> Warnings { get; private set; } = new List<WarningSystem2ServiceClientWithName>();

        public List<ErrorWithName> Errors { get; private set; } = new List<ErrorWithName>();

        public bool IsRinging { get; set; }

        /// <summary>
        /// 报警服务容器
        /// </summary>
        IUnityContainer warning_container;
        ParamDictionary paramDictionary;
        [InjectionMethod]
        public void Init(IUnityContainer container, ParamDictionary paramDictionary)
        {
            //找到 warnings.service 容器
            if (!container.IsRegistered<IUnityContainer>("warnings.service"))
                return;
            this.warning_container = container.Resolve<IUnityContainer>("warnings.service");
            this.paramDictionary = paramDictionary;

            //不需要关注的 报警服务，不需要 resolve

            //获取 不需要关注 的报警服务 在容器中的名字
            var skipWarningUnityNames = paramDictionary.GetValue<List<string>>(ParamDistItemKeys.SkipWarningUnityNames, null);
            if (skipWarningUnityNames == null || skipWarningUnityNames.Count() == 0)
            {
                //全部获取
                Warnings.AddRange(warning_container.ResolveAll<WarningSystem2ServiceClientWithName>());
            }
            else 
            {
                Warnings = new List<WarningSystem2ServiceClientWithName>();

                foreach (var registration in warning_container.Registrations) 
                {
                    if (registration.RegisteredType == typeof(WarningSystem2ServiceClientWithName)) 
                    {
                        if (!skipWarningUnityNames.Contains(registration.Name)) { 
                            //没有被 忽略
                            var warning = warning_container.Resolve<WarningSystem2ServiceClientWithName>(registration.Name);
                            Warnings.Add(warning);
                        }
                    }
                }
            }


            IsRinging = Warnings.Any(w => w.IsRinging);

            foreach (var warning in Warnings)
            {
                warning.PropertyChanged += WarningService_PropertyChanged;
            }
            updateErrors();
        }
        private void WarningService_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if ((e.PropertyName == nameof(WarningSystem2ServiceClientWithName.ReasonList))
                || (e.PropertyName == nameof(WarningSystem2ServiceClientWithName.IsConnected)))
            {
                updateErrors();
            }
            else if (e.PropertyName == nameof(WarningSystem2ServiceClientWithName.IsRinging)) {
                IsRinging = Warnings.Any(w => w.IsRinging);
            }
            
        }
        void updateErrors()
        {
            List<ErrorWithName> errors = new List<ErrorWithName>();
            foreach (var warning in Warnings)
            {
                if (!warning.IsConnected)
                {
                    string errMsg = (string)Application.Current.TryFindResource("str.CtMicroGage.ServerDisconnected");
                    if (errMsg == null)
                    {
                        errMsg = "服务器连接断开";
                    }

                    errors.Add(new ErrorWithName()
                    {
                        DevName = warning.DevName,
                        Time = DateTime.Now,
                        ErrCode = 0,
                        Description = errMsg
                    });
                }
                else if (warning.ReasonList != null && warning.ReasonList.Count() > 0) {
                    errors.AddRange(warning.ReasonList.Select(e =>
                    new ErrorWithName()
                    {
                        DevName = warning.DevName,
                        Time = e.Time,
                        ErrCode = e.ErrCode,
                        Description = e.Description
                    }));
                }
            }
            if (errors.Count > 0)
            {
                errors.Sort((e1, e2) =>
                {
                    return e1.Time.CompareTo(e2.Time);
                });
                Errors = errors;
            }
            else {
                Errors = new List<ErrorWithName>();
            }
        }

        /// <summary>
        /// 返回 报警服务名字
        /// </summary>
        /// <returns></returns>
        public List<WarningName> GetWarningNames() 
        {
            List<WarningName> warningNames = new List<WarningName>();
            foreach (var registration in warning_container.Registrations)
            {
                if (registration.RegisteredType == typeof(WarningSystem2ServiceClientWithName))
                {
                    //没有被 忽略
                    //var warning = warning_container.Resolve<WarningSystem2ServiceClientWithName>(registration.Name);
                    warningNames.Add(new WarningName() { 
                        //DevName = warning.DevName,
                        UnityName = registration.Name });
                }
            }

            var skipWarningUnityNames = paramDictionary.GetValue<List<string>>(ParamDistItemKeys.SkipWarningUnityNames, null);
            if (skipWarningUnityNames != null && skipWarningUnityNames.Count() > 0) 
            {
                foreach (var unityName in skipWarningUnityNames) 
                {
                    var wn = warningNames.Find(w => w.UnityName == unityName);
                    if (wn != null)
                        wn.IsRegistered = false;
                }
            }

            return warningNames;
        }
        public void SetSkipWarningName(List<string> unityNames) 
        {
            paramDictionary.SetValue(ParamDistItemKeys.SkipWarningUnityNames, unityNames);
        }
    }
    public class WarningName:INotifyPropertyChanged
    {
        /// <summary>
        /// 设备名称
        /// </summary>
        //public string DevName { get; set; }
        public string UnityName { get; set; }

        public bool IsRegistered { get; set; } = true;

        public event PropertyChangedEventHandler PropertyChanged;
    }
    public class ErrorWithName:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 设备名称
        /// </summary>
        public string DevName { get; set; }

        /// <summary>
        /// 时间
        /// </summary>
        public DateTime Time { get; set; }

        /// <summary>
        /// 出错码
        /// </summary>
        public int ErrCode { get; set; }

        /// <summary>
        /// 描述
        /// </summary>
        public string Description { get; set; }


    }
}

