//------------------------------------------------------------------------------
//  此代码版权声明为全文件覆盖，如有原作者特别声明，会在下方手动补充
//  此代码版权（除特别声明外的代码）归作者本人Diego所有
//  源代码使用协议遵循本仓库的开源协议及附加协议
//  Gitee源代码仓库：https://gitee.com/diego2098/ThingsGateway
//  Github源代码仓库：https://github.com/kimdiego2098/ThingsGateway
//  使用文档：https://thingsgateway.cn/
//  QQ群：605534569
//------------------------------------------------------------------------------

using BootstrapBlazor.Components;

using Riok.Mapperly.Abstractions;

using System.Collections.Concurrent;
using System.ComponentModel.DataAnnotations;

namespace ThingsGateway.Gateway.Application;

/// <summary>
/// 设备变量表
/// </summary>
#if !Management
[OrmTable("variable", TableDescription = "设备变量表")]
[Tenant(SqlOrmConst.DB_Custom)]
[OrmIndex("index_device", nameof(Variable.DeviceId), OrderByType.Asc)]
[OrmIndex("unique_deviceid_variable_name", nameof(Variable.Name), OrderByType.Asc, nameof(Variable.DeviceId), OrderByType.Asc, true)]
#endif
public class Variable : PrimaryKeyEntity, IValidatableObject
{
    /// <summary>
    /// 主键Id
    /// </summary>
    [OrmColumn(ColumnDescription = "Id", IsPrimaryKey = true)]
    [AutoGenerateColumn(Visible = false, IsVisibleWhenEdit = false, IsVisibleWhenAdd = false, Sortable = true, DefaultSort = true, DefaultSortOrder = SortOrder.Asc)]
    [System.ComponentModel.DataAnnotations.Key]
    public override long Id { get; set; }

    /// <summary>
    /// 导入验证专用
    /// </summary>
    [System.Text.Json.Serialization.JsonIgnore]
    [Newtonsoft.Json.JsonIgnore]
    internal long Row;
    private long deviceId;
    private int? arrayLength;

    private ProtectTypeEnum protectType = ProtectTypeEnum.ReadWrite;
    private DataTypeEnum dataType = DataTypeEnum.Int16;

    /// <summary>
    /// 导入验证专用
    /// </summary>
    [System.Text.Json.Serialization.JsonIgnore]
    [Newtonsoft.Json.JsonIgnore]
    internal bool IsUp;
    private bool enable = true;
    public bool DynamicVariable;
    private bool rpcWriteEnable = true;
    private bool saveValue = false;
    private bool businessGroupUpdateTrigger = true;
    private bool rpcWriteCheck;

    private object _value;
    private string name;
    private string collectGroup = string.Empty;
    private string businessGroup;
    private string description;
    private string unit;
    private string intervalTime;
    private string registerAddress;
    private string otherMethod;
    private string readExpressions;
    private string writeExpressions;

    private Dictionary<long, Dictionary<string, string>>? variablePropertys;
    private string remark1;
    private string remark2;
    private string remark3;
    private string remark4;
    private string remark5;

    [System.Text.Json.Serialization.JsonIgnore]
    [Newtonsoft.Json.JsonIgnore]
    [MapperIgnore]
    public ValidateForm AlarmPropertysValidateForm;

    /// <summary>
    /// 变量额外属性Json
    /// </summary>
    [System.Text.Json.Serialization.JsonIgnore]
    [Newtonsoft.Json.JsonIgnore]
    [MapperIgnore]
    public NonBlockingDictionary<long, ModelValueValidateForm>? VariablePropertyModels;

    /// <summary>
    /// 设备
    /// </summary>
    [OrmColumn(ColumnDescription = "设备")]
    [AutoGenerateColumn(Visible = true, Order = 1, Filterable = false, Sortable = false)]
    [IgnoreExcel]
    [Required]
    [NotNull]
    [MinValue(1)]
    public virtual long DeviceId { get => deviceId; set => deviceId = value; }

    /// <summary>
    /// 变量名称
    /// </summary>
    [OrmColumn(ColumnDescription = "变量名称", IsNullable = false)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true, Order = 1)]
    [Required]
    public virtual string Name { get => name; set => name = value; }

    /// <summary>
    /// 采集组
    /// </summary>
    [OrmColumn(ColumnDescription = "采集组", IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true, Order = 1)]
    public virtual string CollectGroup { get => collectGroup; set => collectGroup = value; }
    /// <summary>
    /// 分组名称
    /// </summary>
    [OrmColumn(ColumnDescription = "分组名称", IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true, Order = 1)]
    public virtual string BusinessGroup { get => businessGroup; set => businessGroup = value; }

    /// <summary>
    /// 分组上传触发变量
    /// </summary>
    [OrmColumn(ColumnDescription = "分组上传触发变量", IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true, Order = 1)]
    public virtual bool BusinessGroupUpdateTrigger { get => businessGroupUpdateTrigger; set => businessGroupUpdateTrigger = value; }

    /// <summary>
    /// 写入后再次读取检查值是否一致
    /// </summary>
    [OrmColumn(ColumnDescription = "写入后再次读取检查值是否一致", IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true, Order = 1)]
    public virtual bool RpcWriteCheck { get => rpcWriteCheck; set => rpcWriteCheck = value; }

    /// <summary>
    /// 描述
    /// </summary>
    [OrmColumn(ColumnDescription = "描述", Length = 200, IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true, Order = 2)]
    public string Description { get => description; set => description = value; }

    /// <summary>
    /// 单位
    /// </summary>
    [OrmColumn(ColumnDescription = "单位", Length = 200, IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true, Order = 3)]
    public virtual string Unit { get => unit; set => unit = value; }

    /// <summary>
    /// 间隔时间
    /// </summary>
    [OrmColumn(ColumnDescription = "间隔时间", IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
    public virtual string IntervalTime { get => intervalTime; set => intervalTime = value; }

    /// <summary>
    /// 变量地址，可能带有额外的信息，比如<see cref="DataFormatEnum"/> ，以;分割
    /// </summary>
    [OrmColumn(ColumnDescription = "变量地址", Length = 200, IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
    public string RegisterAddress { get => registerAddress; set => registerAddress = value; }

    /// <summary>
    /// 数组长度
    /// </summary>
    [OrmColumn(ColumnDescription = "数组长度", IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
    public int? ArrayLength { get => arrayLength; set => arrayLength = value; }

    /// <summary>
    /// 其他方法，若不为空，此时RegisterAddress为方法参数
    /// </summary>
    [OrmColumn(ColumnDescription = "特殊方法", Length = 200, IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
    public string OtherMethod { get => otherMethod; set => otherMethod = value; }

    /// <summary>
    /// 使能
    /// </summary>
    [OrmColumn(ColumnDescription = "使能")]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
    public virtual bool Enable { get => enable; set => enable = value; }
    /// <summary>
    /// 读写权限
    /// </summary>
    [OrmColumn(ColumnDescription = "读写权限", IsNullable = false)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
    public virtual ProtectTypeEnum ProtectType { get => protectType; set => protectType = value; }
    /// <summary>
    /// 数据类型
    /// </summary>
    [OrmColumn(ColumnDescription = "数据类型")]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
    public virtual DataTypeEnum DataType { get => dataType; set => dataType = value; }
    /// <summary>
    /// 读取表达式
    /// </summary>
    [OrmColumn(ColumnDescription = "读取表达式", Length = 1000, IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
    public virtual string ReadExpressions { get => readExpressions; set => readExpressions = value; }

    /// <summary>
    /// 写入表达式
    /// </summary>
    [OrmColumn(ColumnDescription = "写入表达式", Length = 1000, IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
    public virtual string WriteExpressions { get => writeExpressions; set => writeExpressions = value; }

    /// <summary>
    /// 是否允许远程Rpc写入
    /// </summary>
    [OrmColumn(ColumnDescription = "远程写入", IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
    public virtual bool RpcWriteEnable { get => rpcWriteEnable; set => rpcWriteEnable = value; }
    /// <summary>
    /// 初始值
    /// </summary>
    [OrmColumn(IsJson = true, ColumnDataType = StaticConfig.CodeFirst_BigString, ColumnDescription = "初始值", IsNullable = true)]
    [AutoGenerateColumn(Ignore = true)]
    public object InitValue
    {
        get
        {
            return _value;
        }
        set
        {
            if (value != null)
                _value = value?.ToString()?.GetJsonNodeFromString();
            else
                _value = null;
        }
    }

    /// <summary>
    /// 保存初始值
    /// </summary>
    [OrmColumn(ColumnDescription = "保存初始值", IsNullable = true)]
    [AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
    public virtual bool SaveValue { get => saveValue; set => saveValue = value; }
    /// <summary>
    /// 变量额外属性Json
    /// </summary>
    [OrmColumn(IsJson = true, ColumnDataType = StaticConfig.CodeFirst_BigString, ColumnDescription = "变量属性Json", IsNullable = true)]
    [IgnoreExcel]
    [AutoGenerateColumn(Ignore = true)]
    public Dictionary<long, Dictionary<string, string>>? VariablePropertys { get => variablePropertys; set => variablePropertys = value; }


    /// <summary>
    /// 变量报警属性Json
    /// </summary>
    [OrmColumn(IsJson = true, ColumnDataType = StaticConfig.CodeFirst_BigString, ColumnDescription = "报警属性Json", IsNullable = true)]
    [IgnoreExcel]
    [AutoGenerateColumn(Ignore = true)]
    public AlarmPropertys? AlarmPropertys { get; set; }


    #region 备用字段

    /// <summary>
    /// 自定义
    /// </summary>
    [OrmColumn(ColumnDescription = "自定义1", Length = 200, IsNullable = true)]
    [AutoGenerateColumn(Visible = false, Filterable = true, Sortable = true)]
    public string Remark1 { get => remark1; set => remark1 = value; }

    /// <summary>
    /// 自定义
    /// </summary>
    [OrmColumn(ColumnDescription = "自定义2", Length = 200, IsNullable = true)]
    [AutoGenerateColumn(Visible = false, Filterable = true, Sortable = true)]
    public string Remark2 { get => remark2; set => remark2 = value; }

    /// <summary>
    /// 自定义
    /// </summary>
    [OrmColumn(ColumnDescription = "自定义3", Length = 200, IsNullable = true)]
    [AutoGenerateColumn(Visible = false, Filterable = true, Sortable = true)]
    public string Remark3 { get => remark3; set => remark3 = value; }

    /// <summary>
    /// 自定义
    /// </summary>
    [OrmColumn(ColumnDescription = "自定义4", Length = 200, IsNullable = true)]
    [AutoGenerateColumn(Visible = false, Filterable = true, Sortable = true)]
    public string Remark4 { get => remark4; set => remark4 = value; }

    /// <summary>
    /// 自定义
    /// </summary>
    [OrmColumn(ColumnDescription = "自定义5", Length = 200, IsNullable = true)]
    [AutoGenerateColumn(Visible = false, Filterable = true, Sortable = true)]
    public string Remark5 { get => remark5; set => remark5 = value; }

    #endregion 备用字段

    public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (string.IsNullOrEmpty(RegisterAddress) && string.IsNullOrEmpty(OtherMethod))
        {
            yield return new ValidationResult("Both RegisterAddress and OtherMethod cannot be empty or null.", new[] { nameof(OtherMethod), nameof(RegisterAddress) });
        }
    }
}
