using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WjwLib.API.System;

namespace GatewayTool.Models
{
    /// <summary>
    /// DTU配置
    /// </summary>
    public class DTUConfig
    {
        /// <summary>
        /// mqtt主机地址
        /// </summary>
        [Category("\tMQTT设置")]
        [DisplayName("服务器地址")]
        [JsonProperty(PropertyName = "host")]
        public string Host { get; set; } = string.Empty;

        /// <summary>
        /// mqtt端口
        /// </summary>
        [Category("\tMQTT设置")]
        [DisplayName("端口号")]
        [JsonProperty(PropertyName = "port")]
        public UInt16 Port { get; set; }

        private string _MessageTopic = string.Empty;
        /// <summary>
        /// mqtt发布主题
        /// </summary>
        [Category("\tMQTT设置")]
        [DisplayName("发布主题")]
        [JsonProperty(PropertyName = "messageTopic")]
        [Description("字符串长度不能超过50")]
        public string MessageTopic
        {
            get => _MessageTopic;
            set
            {
                if (value.Length > 50)
                {
                    throw new Exception("字符串长度不能超过50！");
                }
                else
                {
                    _MessageTopic = value;
                }
            }
        }

        private string _CommandTopic = string.Empty;
        /// <summary>
        /// mqtt订阅主题
        /// </summary>
        [Category("\tMQTT设置")]
        [DisplayName("订阅主题")]
        [JsonProperty(PropertyName = "commandTopic")]
        [Description("字符串长度不能超过50")]
        public string CommandTopic
        {
            get => _CommandTopic;
            set
            {
                if (value.Length > 50)
                {
                    throw new Exception("字符串长度不能超过50！");
                }
                else
                {
                    _CommandTopic = value;
                }
            }
        }

        /// <summary>
        /// 波特率
        /// </summary>
        [Category("\t串口设置")]
        [DisplayName("波特率")]
        [JsonProperty(PropertyName = "baudrate")]
        [TypeConverter(typeof(EnumTypeConverter))]
        public EnumBaudrate Baudrate { get; set; } = EnumBaudrate.rate_9600;

        /// <summary>
        /// 数据位
        /// </summary>
        [Category("\t串口设置")]
        [DisplayName("数据位")]
        [JsonProperty(PropertyName = "dataBit")]
        [TypeConverter(typeof(EnumTypeConverter))]
        public EnumDataBits DataBits { get; set; } = EnumDataBits.Bit_8;

        /// <summary>
        /// 停止位
        /// </summary>
        [Category("\t串口设置")]
        [DisplayName("停止位")]
        [JsonProperty(PropertyName = "stopBit")]
        [TypeConverter(typeof(EnumTypeConverter))]
        public EnumStopBits StopBit { get; set; } = EnumStopBits.Bit_1;

        /// <summary>
        /// 校验位（none,odd,even,mark,Space）
        /// </summary>
        [Category("\t串口设置")]
        [DisplayName("校验位")]
        [JsonProperty(PropertyName = "checkBit")]
        [Description("none-无，odd-奇，even-偶，mark-标记，space-空格")]
        [TypeConverter(typeof(EnumTypeConverter))]
        public EnumCheckBit CheckBit { get; set; } = EnumCheckBit.none;

        /// <summary>
        /// 流控制（hardware,software,none,custom）
        /// </summary>
        [Category("\t串口设置")]
        [DisplayName("流控制")]
        [JsonProperty(PropertyName = "flowControl")]
        [Description("none-无，hardware-硬件，software-软件，custom-自定义")]
        [TypeConverter(typeof(EnumTypeConverter))]
        public EnumFlowControl FlowControl { get; set; } = EnumFlowControl.none;

        /// <summary>
        /// DTU设备ID
        /// </summary>
        [ReadOnly(true)]
        [Category("\t协议设置")]
        [DisplayName("DTU设备ID")]
        [JsonProperty(PropertyName = "deviceId")]
        [Description("网关设备序列号，最大长度24位，参数值不可更改")]
        public string DeviceId { get; set; } = string.Empty;

        /// <summary>
        /// 数据来源（1-645协议,2-mdb协议...）
        /// </summary>
        [Category("\t协议设置")]
        [DisplayName("数据来源")]
        [JsonProperty(PropertyName = "dataSource")]
        [TypeConverter(typeof(EnumTypeConverter))]
        public EnumDataSource DataSource { get; set; } = EnumDataSource.Protocol_645;

        /// <summary>
        /// 645协议版本（1-07版,2-97版）
        /// </summary>
        [Category("\t协议设置")]
        [DisplayName("645协议版本")]
        [JsonProperty(PropertyName = "version645")]
        [TypeConverter(typeof(EnumTypeConverter))]
        [Browsable(true)]
        public EnumVersion645 Version645 { get; set; } = EnumVersion645.Version_07;

        /// <summary>
        /// 上发时间（单位：毫秒）
        /// </summary>
        [Category("\t协议设置")]
        [DisplayName("上发时间")]
        [JsonProperty(PropertyName = "inboundTime")]
        [Description("设备采集数据后多久上发一次到服务器。单位：毫秒")]
        public UInt64 InboundTime { get; set; }

        /// <summary>
        /// 轮询时间（单位：毫秒）
        /// </summary>
        [Category("\t协议设置")]
        [DisplayName("轮询时间")]
        [JsonProperty(PropertyName = "pollTime")]
        [Description("单位：毫秒（只在有本地存储的设备含有此字段）")]
        public UInt64 PollTime { get; set; }

        private SensorDataItemCollection _SensorDataCollection = new SensorDataItemCollection();
        /// <summary>
        /// 上发配置
        /// </summary>
        [Category("\t上发设置")]
        [DisplayName("上发配置")]
        [JsonProperty(PropertyName = "sensorData")]
        [Editor(typeof(SensorDataItemCollectionEditor), typeof(System.Drawing.Design.UITypeEditor))]
        public SensorDataItemCollection SensorData
        {
            get => _SensorDataCollection;
            set => _SensorDataCollection = value;
        }

        private CommandDataItemCollection _CommandDataCollection = new CommandDataItemCollection();
        /// <summary>
        /// 下发配置
        /// </summary>
        [Category("\t下发设置")]
        [DisplayName("下发配置")]
        [JsonProperty(PropertyName = "commandData")]
        [Editor(typeof(CommandDataItemCollectionEditor), typeof(System.Drawing.Design.UITypeEditor))]
        [Browsable(false)]
        public CommandDataItemCollection CommandData
        {
            get => _CommandDataCollection;
            set => _CommandDataCollection = value;
        }
    }

    /// <summary>
    /// 上发配置项
    /// </summary>   
    public class SensorDataItem
    {
        /// <summary>
        /// Mdb功能码_读
        /// </summary>
        [Category("\tModbus设置")]
        [DisplayName("Mdb功能码_读（输入0x开头的数）")]
        [JsonProperty(PropertyName = "rFunctionCode")]
        [Browsable(false)]
        public UInt16 RFunctionCode { get; set; }

        /// <summary>
        /// Mdb寄存器地址
        /// </summary>
        [Category("\tModbus设置")]
        [DisplayName("Mdb寄存器地址（输入0x开头的数）")]
        [JsonProperty(PropertyName = "registerAddress")]
        [Browsable(false)]
        public UInt16 RegisterAddress { get; set; }

        /// <summary>
        /// Mdb从站地址
        /// </summary>
        [Category("\tModbus设置")]
        [DisplayName("Mdb从站地址（输入0x开头的数）")]
        [JsonProperty(PropertyName = "slaveAddress")]
        [Browsable(false)]
        public UInt16 SlaveAddress { get; set; }

        /// <summary>
        /// 寄存器字节数
        /// </summary>
        [Category("\tModbus设置")]
        [DisplayName("寄存器字节数（输入0x开头的数）")]
        [JsonProperty(PropertyName = "registerByteNum")]
        [Browsable(false)]
        public UInt16 RegisterByteNum { get; set; }

        private string _Identifier = string.Empty;
        /// <summary>
        /// 唯一标识符
        /// </summary>
        [Category("\t通用设置")]
        [DisplayName("唯一标识符")]
        [JsonProperty(PropertyName = "identifier")]
        [Description("字符串长度不能超过20")]
        [StringLength(0, 20)]
        public string Identifier
        {
            get => _Identifier;
            set
            {
                if (value.Length > 20)
                {
                    throw new Exception("字符串长度不能超过20！");
                }
                else
                {
                    _Identifier = value;
                }
            }
        }

        private string _DeviceId = string.Empty;
        /// <summary>
        /// 子设备序列号
        /// </summary>
        [Category("\t通用设置")]
        [DisplayName("子设备序列号")]
        [JsonProperty(PropertyName = "deviceId")]
        [Description("字符串长度不能超过20")]
        [StringLength(0, 20)]
        public string DeviceId
        {
            get => _DeviceId;
            set
            {
                if (value.Length > 20)
                {
                    throw new Exception("字符串长度不能超过20！");
                }
                else
                {
                    _DeviceId = value;
                }
            }
        }

        /// <summary>
        /// 645数据标识（上发到DTU为十进制）
        /// </summary>
        [Category("\t645设置")]
        [DisplayName("645数据标识")]
        [JsonProperty(PropertyName = "identifier645")]
        [Description("上发到DTU为十进制")]
        [Browsable(true)]
        public UInt64 Identifier645 { get; set; }

        /// <summary>
        /// 645设备ID（如表号等）
        /// </summary>
        [Category("\t645设置")]
        [DisplayName("645设备ID")]
        [JsonProperty(PropertyName = "deviceID645")]
        [Description("如表号等")]
        [Browsable(true)]
        public string DeviceID645 { get; set; } = string.Empty;

        /// <summary>
        /// 保留小数点位数
        /// </summary>
        [Category("\tModbus设置")]
        [DisplayName("保留小数点位数")]
        [JsonProperty(PropertyName = "precise")]
        [Browsable(false)]
        public UInt16 Precise { get; set; }

        /// <summary>
        /// 大小端格式（1大端,2小端）
        /// </summary>
        [Category("\tModbus设置")]
        [DisplayName("大小端格式")]
        [JsonProperty(PropertyName = "bigLittleFormat")]
        [TypeConverter(typeof(EnumTypeConverter))]
        [Browsable(false)]
        public EnumBigLittleFormat BigLittleFormat { get; set; } = EnumBigLittleFormat.Big;

        /// <summary>
        /// 是否序列化645设备ID属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeDeviceID645()
        {
            return IsPropertyBrowsable("DeviceID645"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化645数据标识属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeIdentifier645()
        {
            return IsPropertyBrowsable("Identifier645"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化保留小数点位数属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializePrecise()
        {
            return IsPropertyBrowsable("Precise"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化寄存器地址属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeRegisterAddress()
        {
            return IsPropertyBrowsable("RegisterAddress"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化从站地址属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeSlaveAddress()
        {
            return IsPropertyBrowsable("SlaveAddress"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化Mdb读功能码属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeRFunctionCode()
        {
            return IsPropertyBrowsable("RFunctionCode"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化寄存器字节数属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeRegisterByteNum()
        {
            return IsPropertyBrowsable("RegisterByteNum"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化大小端格式属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeBigLittleFormat()
        {
            return IsPropertyBrowsable("BigLittleFormat"); //可见就可序列化
        }

        /// <summary>
        /// 获取属性的可见性
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <returns>true可见，false不可见</returns>
        private bool IsPropertyBrowsable(string propertyName)
        {
            AttributeCollection attributes = TypeDescriptor.GetProperties(this)[propertyName].Attributes;
            BrowsableAttribute myAttribute = (BrowsableAttribute)attributes[typeof(BrowsableAttribute)];
            return myAttribute.Browsable;
        }
    }

    /// <summary>
    /// 下发配置项
    /// </summary>
    public class CommandDataItem
    {
        private string _DeviceId = string.Empty;
        /// <summary>
        /// 子设备序列号
        /// </summary>
        [Category("\t通用设置")]
        [DisplayName("子设备序列号")]
        [JsonProperty(PropertyName = "deviceId")]
        [Browsable(true)]
        [Description("字符串长度不能超过20")]
        [StringLength(0, 20)]
        public string DeviceId
        {
            get => _DeviceId;
            set
            {
                if (value.Length > 20)
                {
                    throw new Exception("字符串长度不能超过20！");
                }
                else
                {
                    _DeviceId = value;
                }
            }
        }

        private string _Identifier = string.Empty;
        /// <summary>
        /// 唯一标识符
        /// </summary>
        [Category("\t通用设置")]
        [DisplayName("唯一标识符")]
        [JsonProperty(PropertyName = "identifier")]
        [Browsable(true)]
        [Description("字符串长度不能超过20")]
        [StringLength(0, 20)]
        public string Identifier
        {
            get => _Identifier;
            set
            {
                if (value.Length > 20)
                {
                    throw new Exception("字符串长度不能超过20！");
                }
                else
                {
                    _Identifier = value;
                }
            }
        }

        /// <summary>
        /// Mdb寄存器地址
        /// </summary>
        [Category("\tModbus设置")]
        [DisplayName("Mdb寄存器地址（输入0x开头的数）")]
        [JsonProperty(PropertyName = "registerAddress")]
        [Browsable(true)]
        public UInt16 RegisterAddress { get; set; }

        /// <summary>
        /// Mdb从站地址
        /// </summary>
        [Category("\tModbus设置")]
        [DisplayName("Mdb从站地址（输入0x开头的数）")]
        [JsonProperty(PropertyName = "slaveAddress")]
        [Browsable(true)]
        public UInt16 SlaveAddress { get; set; }

        /// <summary>
        /// Mdb功能码_写
        /// </summary>
        [Category("\tModbus设置")]
        [DisplayName("Mdb功能码_写（输入0x开头的数）")]
        [JsonProperty(PropertyName = "wFunctionCode")]
        [Browsable(true)]
        public UInt16 WFunctionCode { get; set; }

        /// <summary>
        /// 寄存器字节数
        /// </summary>
        [Category("\tModbus设置")]
        [DisplayName("寄存器字节数（输入0x开头的数）")]
        [JsonProperty(PropertyName = "registerByteNum")]
        [Browsable(true)]
        public UInt16 RegisterByteNum { get; set; }

        /// <summary>
        /// 大小端格式（1大端,2小端）
        /// </summary>
        [Category("\tModbus设置")]
        [DisplayName("大小端格式")]
        [JsonProperty(PropertyName = "bigLittleFormat")]
        [TypeConverter(typeof(EnumTypeConverter))]
        [Browsable(true)]
        public EnumBigLittleFormat BigLittleFormat { get; set; } = EnumBigLittleFormat.Big;

        /// <summary>
        /// 是否序列化子设备序列号属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeDeviceId()
        {
            return IsPropertyBrowsable("DeviceId"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化唯一标识符属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeIdentifier()
        {
            return IsPropertyBrowsable("Identifier"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化Mdb寄存器地址属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeRegisterAddress()
        {
            return IsPropertyBrowsable("RegisterAddress"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化Mdb从站地址属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeSlaveAddress()
        {
            return IsPropertyBrowsable("SlaveAddress"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化Modbus写功能码属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeWFunctionCode()
        {
            return IsPropertyBrowsable("WFunctionCode"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化寄存器字节数属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeRegisterByteNum()
        {
            return IsPropertyBrowsable("RegisterByteNum"); //可见就可序列化
        }

        /// <summary>
        /// 是否序列化大小端格式属性
        /// </summary>
        /// <returns>true是，false否</returns>
        public bool ShouldSerializeBigLittleFormat()
        {
            return IsPropertyBrowsable("BigLittleFormat"); //可见就可序列化
        }

        /// <summary>
        /// 获取属性的可见性
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <returns>true可见，false不可见</returns>
        private bool IsPropertyBrowsable(string propertyName)
        {
            AttributeCollection attributes = TypeDescriptor.GetProperties(this)[propertyName].Attributes;
            BrowsableAttribute myAttribute = (BrowsableAttribute)attributes[typeof(BrowsableAttribute)];
            return myAttribute.Browsable;
        }
    }
}