using NEIntelligentControl2.Models;
using NEIntelligentControl2.Models.Matrix;
using NEIntelligentControl2.Models.Messages;
using NEIntelligentControl2.Models.Windturbine;
using NEIntelligentControl2.Service.User;
using NEIntelligentControl2.Service.WebSocket;
using NEIntelligentControl2.Service.Windturbine;
using NEIntelligentControl2.Views.Basic;
using NEIntelligentControl2.Views.Infos;
using NEIntelligentControl2.Windows;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
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.Matrix
{
    /// <summary>
    /// 风机矩阵块
    /// </summary>
    public partial class WindBlock : UserControl, IOptional
    {
        // ----------依赖属性------------
        public static readonly DependencyProperty CardColorProperty = DependencyProperty.Register("CardState", typeof(WindturbineState), typeof(WindBlock));
        public static readonly DependencyProperty StationNameValueProperty = DependencyProperty.Register("StationName", typeof(string), typeof(WindBlock));
        public static readonly DependencyProperty WindturbineNameValueProperty = DependencyProperty.Register("WindturbineName", typeof(string), typeof(WindBlock));
        public static readonly DependencyProperty WindSpeedValueProperty = DependencyProperty.Register("WindSpeed", typeof(string), typeof(WindBlock));
        public static readonly DependencyProperty PowerValueProperty = DependencyProperty.Register("Power", typeof(string), typeof(WindBlock));
        public static readonly DependencyProperty RotateSpeedValueProperty = DependencyProperty.Register("RotateSpeed", typeof(string), typeof(WindBlock));
        public static readonly DependencyProperty ToolTipValueProperty = DependencyProperty.Register("ToolTipValue", typeof(string), typeof(WindBlock));
        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(WindBlock));
        public static readonly DependencyProperty IsLockedProperty = DependencyProperty.Register("IsLocked", typeof(bool), typeof(WindBlock));
        public static readonly DependencyProperty LockTypeProperty = DependencyProperty.Register("LockType", typeof(LockType), typeof(WindBlock));

        public event SelectedEventHandler SelectedChanged;

        /// <summary>
        /// 风机状态
        /// </summary>
        public WindturbineState CardState
        {
            get { return (WindturbineState)GetValue(CardColorProperty); }
            set { SetValue(CardColorProperty, value); }
        }

        /// <summary>
        /// 站点名称
        /// </summary>
        public string StationName
        {
            get { return (string)GetValue(StationNameValueProperty); }
            set { SetValue(StationNameValueProperty, value); }
        }

        /// <summary>
        /// 风机名称
        /// </summary>
        public string WindturbineName
        {
            get { return (string)GetValue(WindturbineNameValueProperty); }
            set { SetValue(WindturbineNameValueProperty, value); }
        }

        /// <summary>
        /// 风机风速
        /// </summary>
        public string WindSpeed
        {
            get { return (string)GetValue(WindSpeedValueProperty); }
            set { SetValue(WindSpeedValueProperty, value); }
        }

        /// <summary>
        /// 风机功率
        /// </summary>
        public string Power
        {
            get { return (string)GetValue(PowerValueProperty); }
            set { SetValue(PowerValueProperty, value); }
        }

        /// <summary>
        /// 风机转速
        /// </summary>
        public string RotateSpeed
        {
            get { return (string)GetValue(RotateSpeedValueProperty); }
            set { SetValue(RotateSpeedValueProperty, value); }
        }
        /// <summary>
        /// 提示消息
        /// </summary>
        public string ToolTipValue { get => GetValue(ToolTipValueProperty) as string; set => SetValue(ToolTipValueProperty, value); }

        /// <summary>
        /// 风机ID
        /// </summary>
        public string WindturbineId { get; set; }

        /// <summary>
        /// 是否挂牌
        /// </summary>
        public bool IsLocked { get => (bool)GetValue(IsLockedProperty); set => SetValue(IsLockedProperty, value); }

        /// <summary>
        /// 挂牌类型
        /// </summary>
        public LockType LockType { get => (LockType)GetValue(LockTypeProperty); set => SetValue(LockTypeProperty, value); }
        /// <summary>
        /// 型号
        /// </summary>
        public string ModelId { get; set; }
        /// <summary>
        /// 是否被选中
        /// </summary>
        public bool IsSelected { get => (bool)GetValue(IsSelectedProperty); set => SetValue(IsSelectedProperty, value); }

        /// <summary>
        /// 风机信息
        /// </summary>
        public WindturbineInfo WindturbineInfo { get; set; }
        /// <summary>
        /// 操作时间
        /// </summary>
        public DateTime OperateTime { get; set; }
        /// <summary>
        /// 推荐操作
        /// </summary>
        public WindturbineSuggestion Suggestion { get; set; }

        private long _Timestamp { get; set; }// 状态持续时长
        /// <summary>
        /// 自定义挂牌信息
        /// </summary>
        public CustomLockInfo CustomLockInfo { get; internal set; }

        private int _PopupInterval = 0;
        private Grid g;
        public WindBlock(WindturbineInfo v = null)
        {
            InitializeComponent();

            WindturbineInfo = v;
            _PopupInterval = App.GetService<UrlManager>().WindturbineDetailsInterval;

        }

        private void InitToolTip()
        {
            if (_PopupInterval <= 0) return;
            ToolTip tp = new ToolTip();
            tp.Opened += ToolTipOpened;
            if (g == null)
            {
                ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(this);
                DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
                g = myDataTemplate.FindName("_GDMain", myContentPresenter) as Grid;
            }
            g.ToolTip = tp;
            ToolTipService.SetInitialShowDelay(g, _PopupInterval);

        }

        private void ToolTipOpened(object sender, RoutedEventArgs e)
        {
            if (this.WindturbineInfo == null) return;
            ToolTip tp = sender as ToolTip;
            if (tp == null) return;
            if (tp.Content == null)
            {
                var wdv = new WindturbineDetailsView(WindturbineInfo) { ToolTipValue = this.ToolTipValue };
                tp.Content = wdv;
            }
            (tp.Content as WindturbineDetailsView)?.RefreshData();
        }

        /// <summary>
        /// 更新数据
        /// </summary>
        public void Update(object obj)
        {
            WindturbineInfo windturbineInfo = obj as WindturbineInfo;
            if (windturbineInfo == null) return;
            WindturbineInfo = windturbineInfo;
            /*初始化	1
停机	2
待机	4
启动	8
加速	16
发电	32
维护	64

            //停机 0
    Stop,
    //上电 1
    OnPower,
    //待机 2
    Standby,
    //启动 3
    Start,
    //并网 4
    Online,
    //故障 5
    Fault,
    //维护 6
    Maintain,
    //离线 7
    Offline
*/
            switch (windturbineInfo.Status)
            {
                case 1:
                    CardState = WindturbineState.Standby;
                    break;
                case 2:
                    CardState = WindturbineState.Stoped;
                    break;
                case 4:
                    CardState = WindturbineState.Standby;
                    break;
                case 8:
                    CardState = WindturbineState.StartUp;
                    break;
                case 16:
                    CardState = WindturbineState.PowerOn;
                    break;
                case 32:
                case 33:
                case 34:
                case 35:
                case 36:
                    CardState = WindturbineState.GridConnected;
                    break;
                case 64:
                    CardState = WindturbineState.Maintain;
                    break;
                case 96:
                case 97:
                    CardState = WindturbineState.Malfunction;
                    break;
                case 100:
                    CardState = WindturbineState.Offline;
                    break;
            }
            WindturbineName = windturbineInfo.WindturbineId;
            WindSpeed = $"{windturbineInfo.WindSpeed.ToString("f2")} m/s";
            Power = $"{windturbineInfo.Power.ToString("f2")} kW";

            var rs = windturbineInfo.ModelId.ToLower().Contains("up105") ? windturbineInfo.RollSpeed * 9.55 : windturbineInfo.RollSpeed;
            RotateSpeed = $"{rs.ToString("f2")} rpm";
            IsLocked = windturbineInfo.IsLocked;

            this.ModelId = windturbineInfo.ModelId;
            if (windturbineInfo.LockValue == 8 || windturbineInfo.LockValue == 2 || (this.CustomLockInfo?.Value?.Contains("[检修]")) == true)
            {
                this.LockType = LockType.Normal;
            }
            else if (windturbineInfo.LockValue == 7 || windturbineInfo.LockValue == 3 || (this.CustomLockInfo?.Value?.StartsWith("[故障]")) == true)
            {
                this.LockType = LockType.Fault;
            }
            else if (this.IsLocked)
            {
                this.LockType = LockType.Normal;
            }

            _Timestamp = windturbineInfo.Ts;
            string time = _Timestamp.GetTimeString();
            string timespan = _Timestamp.GetTimeSpanString();
            ToolTipValue = $"开始时间:{time} 时长:{timespan}分钟";
            if (this.CustomLockInfo != null)
            {
                ToolTipValue += $"\n挂牌:{CustomLockInfo.Value}  挂牌时间:{CustomLockInfo.FollowTime.ToString("yyyy-MM-dd HH:mm:ss")}";
            }
            else if (windturbineInfo.IsLocked)
            {
                ToolTipValue += $"\n挂牌:{((HungType)windturbineInfo.LockValue).GetStringValue()}";
            }
            if (g == null) return;
            var v = (g.ToolTip as ToolTip)?.Content as WindturbineDetailsView;
            if (v == null) return;
            v.ToolTipValue = ToolTipValue;
        }

        private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            //this.Height = this.ActualWidth * 0.47;
        }

        private void UserControl_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            IsSelected = true;
        }

        private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var b = Keyboard.Modifiers == ModifierKeys.Shift;
            if (SelectedChanged == null)
            {
                IsSelected = !IsSelected;
            }
            else
            {
                SelectedChanged(this, b);
            }

            if (e.ClickCount > 1)
            {
                //WinForms.WindtrubineInfoWindow.ShowWindow(WindturbineInfo);
                //Windows.Windturbine.WindturbineInfoWindow.ShowInfo();
                WindturbineInfoWindow.ShowWindow(this.WindturbineInfo);
            }
        }

        private void ContentControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            string tag = ((Control)sender).Tag as string;
            if (tag == null) return;
            if (tag == "time")
            {
                //WinForms.WindtrubineInfoWindow.ShowWindow(WindturbineInfo);
                WindturbineInfoWindow.ShowWindow(this.WindturbineInfo);
                return;
            }
            var b = MessageWindow.ShowMessage("是否发送控制指令");
            if (!b) return;

            var um = App.ServiceProvider.GetService(typeof(UserManager)) as UserManager;
            if (!um.IsLogined)
            {
                bool b1 = um.TempLogin();
                if (!b1) return;
            }

            if (tag == "Lock" || tag == "UnLock")
            {
                Task.Run(sendLock);
            }
            else
            {
                Task.Run(send);
            }
            void sendLock()
            {
                try
                {
                    ControlManager cm = App.ServiceProvider.GetService(typeof(ControlManager)) as ControlManager;

                    HungType ht = HungType.UnLock;
                    if (tag == "Lock")
                    {
                        ht = HungType.CheckLock;
                    }

                    Dictionary<string, ControlInstruction> cis = GetControlInstructions(ht);

                    var v = cm.SendLock(cis);
                    if (v == null) return;
                    Dispatcher.Invoke(() =>
                    {
                        if (v.Length > 0)
                        {
                            MessageWindowBig.ShowMessage(v);
                        }
                    });
                }
                catch { }
            }

            void send()
            {
                try
                {
                    ControlManager cm = App.ServiceProvider.GetService(typeof(ControlManager)) as ControlManager;
                    OperateStyle os = (OperateStyle)Enum.Parse(typeof(OperateStyle), tag);

                    Dictionary<string, ControlInstruction> cis = GetControlInstructions(os);

                    var v = cm.SendCmd(cis);
                    if (v == null) return;
                    Dispatcher.Invoke(() =>
                    {
                        if (v.Length > 0)
                        {
                            MessageWindowBig.ShowMessage(v);
                        }
                    });
                }
                catch { }
            }
        }

        private Dictionary<string, ControlInstruction> GetControlInstructions(HungType ht)
        {
            Dictionary<string, ControlInstruction> ll = new Dictionary<string, ControlInstruction>();

            ControlInstruction ci = new ControlInstruction();
            ci.WindturbineId = WindturbineInfo.WindturbineId;
            ci.StationId = WindturbineInfo.StationId;
            ci.ProjectId = WindturbineInfo.ProjectId;
            ci.ModelId = WindturbineInfo.ModelId;
            ci.LockType = ht;
            ll.Add(ci.WindturbineId, ci);

            return ll;
        }

        private Dictionary<string, ControlInstruction> GetControlInstructions(OperateStyle os)
        {
            Dictionary<string, ControlInstruction> ll = new Dictionary<string, ControlInstruction>();


            ControlInstruction ci = new ControlInstruction();
            ci.WindturbineId = WindturbineInfo.WindturbineId;
            ci.StationId = WindturbineInfo.StationId;
            ci.ProjectId = WindturbineInfo.ProjectId;
            ci.ModelId = WindturbineInfo.ModelId;
            ci.ControlType = os;
            ci.LockType = WindturbineInfo.LockType;
            ll.Add(ci.WindturbineId, ci);

            return ll;
        }

        private void ContentControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            InitToolTip();
        }

        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;
        }
    }

    /// <summary>
    /// 挂牌类型
    /// </summary>
    public enum LockType
    {
        /// <summary>
        /// 常规
        /// </summary>
        Normal,
        /// <summary>
        /// 检修
        /// </summary>
        Overhaul,
        /// <summary>
        /// 故障
        /// </summary>
        Fault,
    }
}