using NEIntelligentControl2.Models;
using NEIntelligentControl2.Models.Alarm;
using NEIntelligentControl2.Models.Messages;
using NEIntelligentControl2.Service.Voice;
using NEIntelligentControl2.Service.WebSocket;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace NEIntelligentControl2.Views.Alarm
{
    /// <summary>
    /// 报警弹窗
    /// </summary>
    public partial class AlarmShowView : UserControl
    {
        // ----------依赖属性-----------
        public static readonly DependencyProperty IsFixedProperty = DependencyProperty.Register("IsFixed", typeof(bool), typeof(AlarmShowView));

        /// <summary>
        /// 是否固定
        /// </summary>
        public bool IsFixed { get => (bool)GetValue(IsFixedProperty); set => SetValue(IsFixedProperty, value); }
        /// <summary>
        /// 报警数据
        /// </summary>
        public ObservableCollection<AlarmCardInfo> Alarms { get; set; }

        private FaultPopupBridge _FaultPopupBridge;
        private MessageBridge _MessageBridge;
        private VoiceManager _VoiceManager;
        private bool _IsFirst = true;
        private Dictionary<long, AlarmCardInfo> _ActivedFaults;
        private AlarmType _AlarmType;                                                                       // 要显示的报警类型
        private ListBox _LBMain;
        public AlarmShowView()
        {
            InitializeComponent();
            Alarms = new ObservableCollection<AlarmCardInfo>();
            _FaultPopupBridge = new FaultPopupBridge() { Messaged = OnAlarmMessage };
            _MessageBridge = App.ServiceProvider.GetService(typeof(MessageBridge)) as MessageBridge;
            _VoiceManager = App.ServiceProvider.GetService(typeof(VoiceManager)) as VoiceManager;
            _ActivedFaults = new Dictionary<long, AlarmCardInfo>();
            try
            {
                _AlarmType = (AlarmType)Enum.Parse(typeof(AlarmType), "AlarmType".GetConfiguration(), true);
            }
            catch { }
            _MessageBridge.Register(_FaultPopupBridge);
        }

        private void OnAlarmMessage(List<FaultInfo> obj)
        {
            if (obj == null || obj.Count == 0) return;
            obj = FiletAlarms(obj);

            // 新的报警列表
            var lsnew = obj.Select(fi => fi.SnapID).ToList();
            // 已经解除的报警
            var unopenedls = Alarms.Where(a => !lsnew.Contains(a.Info.SnapID)).ToList();

            Dispatcher.Invoke(() =>
                {
                    AddAlarm(obj);
                    RemoveAlarm(unopenedls);

                    if (_IsFirst && obj.Count > 0)
                    {
                        IsFixed = true;
                        _VoiceManager.Add($"报警数量：{obj.Count}");
                    }
                    _IsFirst = false;
                });
        }

        /// <summary>
        /// 移除报警
        /// </summary>
        private void RemoveAlarm(List<AlarmCardInfo> unopenedls)
        {
            if (unopenedls == null || unopenedls.Count == 0) return;
            DateTime dt = DateTime.Now;
            foreach (var v in unopenedls)
            {
                // 解除超过10分钟的报警移除
                if (!v.IsOpened && (dt - v.UpdateTime).Minutes >= 10)
                {
                    Alarms.Remove(v);
                    _ActivedFaults.Remove(v.Info.SnapID);
                }
                else if (v.IsOpened)
                {
                    v.IsOpened = false;
                    v.UpdateTime = DateTime.Now;
                }
            }
        }

        /// <summary>
        /// 添加报警
        /// </summary>
        private void AddAlarm(List<FaultInfo> obj)
        {
            foreach (var v in obj)
            {
                if (_ActivedFaults.ContainsKey(v.SnapID))
                {
                    var af = _ActivedFaults[v.SnapID];
                    // 已经解除重新触发的报警
                    if (!af.IsOpened)
                    {
                        af.IsOpened = true;
                        af.UpdateTime = DateTime.Now;
                    }
                    continue;
                }
                var ac = new AlarmCardInfo(v);
                Alarms.Insert(0, ac);
                if (!this.IsMouseOver)
                {
                    _LBMain?.ScrollIntoView(_LBMain.Items[0]);
                }
                _ActivedFaults.Add(v.SnapID, ac);
                if (!_IsFirst)
                {
                    IsFixed = true;
                    _VoiceManager.Add(ac.Message);
                }
            }
        }

        private List<FaultInfo> FiletAlarms(List<FaultInfo> obj)
        {
            if (_IsFirst)
            {
                obj.Sort((x, y) =>
                {
                    var v = x.LastUpdateTime?.CompareTo(y.LastUpdateTime.Value);
                    if (v == null) return 0;
                    return v.Value;
                });
            }
            if (_AlarmType == AlarmType.WindTurbine)
            {
                return obj.Where(fi => fi.Category1 != "SYZ").ToList();
            }
            else if (_AlarmType == AlarmType.BoosterStation)
            {
                return obj.Where(fi => fi.Category1 == "SYZ").ToList();
            }
            return obj;
        }

        private void cc_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            IsFixed = !IsFixed;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var v = ((Control)sender).DataContext as AlarmCardInfo;
            if (v == null||v.Info==null) return;
            if (!v.IsOpened)
            {
                Alarms.Remove(v);
                _ActivedFaults.Remove(v.Info.SnapID);
                return;
            }
            var b = Windows.Alarm.DeviceDetailAlarmWindow.Show(v.Info, true);
            if (b)
            {
                Alarms.Remove(v);
                _ActivedFaults.Remove(v.Info.SnapID);
            }
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            var cp = FindVisualChild<ContentPresenter>(this);
            if (cp == null) return;
            _LBMain = this.ContentTemplate.FindName("_LBMain", cp) as ListBox;
        }

        private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is childItem)
                    return (childItem)child;
                else
                {
                    childItem childOfChild = FindVisualChild<childItem>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }
            return null;
        }
    }

    public class AlarmCardInfo : INotifyPropertyChanged
    {
        /// <summary>
        /// 标题
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// 时间
        /// </summary>
        public string Time { get; set; }
        private string message;
        /// <summary>
        /// 信息
        /// </summary>
        public string Message { get => IsOpened ? message : $"{message}--已解除"; set { message = value; OnPropertyChanged(); } }
        private bool isOpened;
        /// <summary>
        /// 是否未解除
        /// </summary>
        public bool IsOpened { get => isOpened; set { isOpened = value; OnPropertyChanged(); } }
        /// <summary>
        /// 信息更新时间
        /// </summary>
        public DateTime UpdateTime { get; set; }
        public FaultInfo Info { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string name = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

        public AlarmCardInfo(FaultInfo info)
        {
            Info = info;
            if (info == null) return;
            Title = info.ObjectName;
            Time = info.LastUpdateTime == null ? info.FaultTime?.ToString("yyyy-MM-dd HH:mm:ss") : info.LastUpdateTime?.ToString("yyyy-MM-dd HH:mm:ss");
            Message = info.AlertText;
            IsOpened = info.IsOpened;
            UpdateTime = DateTime.Now;
        }
    }

    /// <summary>
    /// 报警类型
    /// </summary>
    public enum AlarmType
    {
        /// <summary>
        /// 所有类型
        /// </summary>
        All,
        /// <summary>
        /// 升压站
        /// </summary>
        BoosterStation,
        /// <summary>
        /// 风机
        /// </summary>
        WindTurbine
    }
}
