using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using DeviceLibrary.manager;
using TcpKPIO;

namespace DeviceLibrary
{
    public class Node
    {
        /// <summary>
        /// 节点ID
        /// </summary>
        public int Id { get; set; }
        /// <summary>
        /// 节点名称
        /// </summary>
        public string Name { get; set; }
        public NodeType Type { get; set; }
        /// <summary>
        /// 所属车间
        /// </summary>
        public string Workshop { get; set; }
        /// <summary>
        /// 节点IP
        /// </summary>
        public string IP { get; set; } = "";
        /// <summary>
        /// 在线状态
        /// </summary>
        public bool Online { get; set; }
        public string IOState
        {
            get
            {
                if (IP.Equals(""))
                    return "";
                else
                    return IOManager.GetDI(IP);
            }
        }
        /// <summary>
        /// 是否可调用
        /// </summary>
        public bool IsUse
        {
            set
            {
                if (!isuse.Equals(value))
                {
                    isuse = value;
                    XmlConfigOperation.SetNodeIsUse(this);
                }
            }
            get { return isuse; }
        }
        private bool isuse;
        /// <summary>
        /// 节点状态
        /// </summary>
        public NodeStatus nodeStatus { get; set; }
        protected string rfid = "00";

        public ExtendEquip ExtendEquip { get; set; }
        /// <summary>
        /// RFID
        /// </summary>
        public string RFID
        {
            set
            {
                if (value.Length < 2)
                    rfid = value.PadLeft(2, '0');
                else
                    rfid = value;
            }
            get
            {
                return rfid;
            }
        }

        public ClientLevel ClientLevel { get; set; } = ClientLevel.Low;
        /// <summary>
        /// 别名
        /// </summary>
        public string AliceName { get; set; }
        /// <summary>
        /// 警告信息
        /// </summary>
        public string WarnMsg { get; set; } = "";
        /// <summary>
        /// 状态比较
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public bool StateEquals(NodeStatus obj)
        {
            return nodeStatus.Equals(obj);
        }
        /// <summary>
        /// 获取当前状态
        /// </summary>
        /// <returns></returns>
        public NodeStatus GetState()
        {
            return nodeStatus;
        }
        /// <summary>
        /// 更新节点状态
        /// </summary>
        /// <param name="status"></param>
        public void UpdateNodeStatus(NodeStatus status)
        {
            nodeStatus = status;
        }

        /// <summary>
        /// 客户端节点
        /// </summary>
        /// <param name="name"></param>
        /// <param name="rfid"></param>
        /// <param name="action"></param>
        /// <param name="level"></param>
        public Node(string name, string rfid = "", NodeStatus status = NodeStatus.None)
        {
            Name = name;
            RFID = rfid;
            nodeStatus = status;
        }
        public Node() { }
        Thread tPingClient;   //ping
        public void Init()
        {
            ExtendEquip = new ExtendEquip(IP);
            tPingClient = new Thread(new ThreadStart(KeepLiveClient));
            tPingClient.IsBackground = true;
            tPingClient.Start();
        }
        string nodeIostate = "";
        /// <summary>
        /// 节点改变事件
        /// </summary>
        /// <param name="nodeIndex"></param>
        public delegate void NodeChangedEvent(Node node);
        /// <summary>
        /// 节点改变
        /// </summary>
        public event NodeChangedEvent NodeChanged;
        /// <summary>
        /// 节点在线
        /// </summary>
        public event NodeChangedEvent NodeOnline;
        private void KeepLiveClient()
        {
            while (true)
            {
                try
                {
                    if (!isuse)
                        continue;
                    Thread.Sleep(300);
                    if (!string.IsNullOrEmpty(IP))
                    {
                        bool check = HttpManager.CheckIP(Name, IP);
                        if (Online != check)
                        {
                            Online = check;
                            NodeOnline?.Invoke(this);
                        }
                    }
                    else
                    {
                        if (Online == false)
                        {
                            Online = true;
                            NodeOnline?.Invoke(this);
                        }
                    }
                    if (!nodeIostate.Equals(IOState))
                    {
                        nodeIostate = IOState;
                        NodeChanged?.Invoke(this);
                    }
                }
                catch (Exception e)
                {
                    Common.LogUtil.error("KeepLiveClient:" + Name, e);
                }
            }
        }

        /// <summary>
        /// 节点状态的文本形式
        /// </summary>
        /// <returns></returns>
        public string StatetText()
        {
            string s = string.Format("[Name={0}, NodeStatus={1}, RFID={2},ClientLevel ={3}]", Name, nodeStatus.ToString(), RFID, ClientLevel.ToString());
            return s;
        }
        public override string ToString()
        {
            return string.Format("[Name={0},AliceName={1},Workshop={2}]", Name,AliceName,Workshop);
        }
        /// <summary>
        /// 脱机
        /// </summary>
        public void Offline()
        {
            RFID = "00";
            nodeStatus = NodeStatus.None;
            Online = false;
            NodeOnline?.Invoke(this);
        }
        public Node ToCopy()
        {
            PropertyInfo[] infos = this.GetType().GetProperties();
            Node node = new Node();
            PropertyInfo[] infos2 = node.GetType().GetProperties();
            for (int i = 0; i < infos2.Length; i++)
            {
                infos2[i].SetValue(node, Convert.ChangeType(infos[i].GetValue(this), infos[i].PropertyType));
            }
            return node;
        }
        public override bool Equals(object obj)
        {
            Node node = obj as Node;
            if (node == null)
                return false;

            if (!node.StateEquals(GetState()) || node.RFID != RFID || node.ClientLevel != ClientLevel)
                return true;
            return false;
        }
        public void UpdateNode(Node node)
        {
            UpdateNodeStatus(node.GetState());
            ClientLevel = node.ClientLevel;
            RFID = node.RFID;
            Common.LogUtil.info("节点更新 " + StatetText());
            NodeChanged?.Invoke(this);
        }
    }

    public class ExtendEquip
    {
        public string IP { get; set; }
        /// <summary>
        /// 确认按钮
        /// </summary>
        public bool ButtonConfirmSig
        {
            get
            {
                if (CanConfirm)
                {
                    if (IP.Equals(""))
                        return false;
                    else
                        return IOManager.GetDI(IP, 0);
                }
                else
                {
                    return false;
                }
            }
        }
        /// <summary>
        /// Api确认
        /// </summary>
        public bool ApiConfirmSig
        {
            get
            {
                if (CanConfirm)
                {
                    return apiconfirmSig;
                }
                else
                {
                    return false;
                }
            }
            set
            {
                if (CanConfirm)
                {
                    apiconfirmSig = value;
                }
            }
        }
        private bool apiconfirmSig = false;
        public bool CanConfirm { get; private set; }
        public ExtendEquip(string ip)
        {
            IP = ip;
        }

        /// <summary>
        /// 允许确认
        /// </summary>
        public void AllowConfirm()
        {
            CanConfirm = true;
        }
        public void Reset()
        {
            CanConfirm = false;
        }
    }
    /// <summary>
    /// 节点状态
    /// </summary>
    public enum NodeStatus : byte
    {
        /// <summary>
        /// 没有动作
        /// </summary>
        None = 0,
        /// <summary>
        /// 需要7寸D料车
        /// </summary>
        NeedD = 1,
        /// <summary>
        /// 需要大尺寸C料车
        /// </summary>
        NeedC = 2,
        /// <summary>
        /// 需要进入料车
        /// </summary>
        NeedEnter = 3,
        /// <summary>
        /// 需要出去料车
        /// </summary>
        NeedLeave = 4,
        /// <summary>
        /// 需要进入离开料车
        /// </summary>
        NeedEnterLeave = 5,
        /// <summary>
        /// 准备进入料车,服务器发送
        /// </summary>
        ReadyEnter = 6,
        /// <summary>
        /// 可以进入料车
        /// </summary>
        MayEnter = 7,
        /// <summary>
        /// 完成进入料车
        /// </summary>
        FinishEnter = 8,
        /// <summary>
        /// 准备离开料车,服务器发送
        /// </summary>
        ReadyLeave = 9,
        /// <summary>
        /// 可以出去料车
        /// </summary>
        MayLeave = 10,
        /// <summary>
        /// 完成出去料车
        /// </summary>
        FinishLeave = 11,

    }

    /// <summary>
    /// 客户端的优先级
    /// </summary>
    public enum ClientLevel : byte
    {
        /// <summary>
        /// 低
        /// </summary>
        Low = 0,
        /// <summary>
        /// 中等
        /// </summary>
        Middle = 1,
        /// <summary>
        /// 高
        /// </summary>
        High = 2
    }

    public enum NodeType
    {
        AutoCharge,
        Standby,
        Node,
        Lift
    }
}