using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JiShe.CollectBus.Common.Attributes;
using JiShe.CollectBus.Enums;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Logging;

namespace JiShe.CollectBus.IotSystems.Devices
{
    public class Device : BasicAggregateRoot<Guid>
    {
        /// <summary>
        /// Device
        /// </summary>
        /// <param name="number"></param>
        /// <param name="firstOnlineTime"></param>
        /// <param name="lastOnlineTime"></param>
        /// <param name="clientId"></param>
        /// <param name="status"></param>
        public Device(string number, string clientId, DateTime firstOnlineTime, DateTime lastOnlineTime, DeviceStatus status)
        {
            Id = Guid.NewGuid();
            Number = number;
            FirstOnlineTime = firstOnlineTime;
            LastOnlineTime = lastOnlineTime;
            ClientId = clientId;
            Status = status;
        }

        /// <summary>
        /// 集中器编号，在集中器登录时解析获取，并会更新为当前TCP连接的最新ClientId
        /// </summary>
        [PartitionKey]
        public string Number { get; set; }

        /// <summary>
        /// 首次上线时间
        /// </summary>
        public DateTime FirstOnlineTime { get; set; }

        /// <summary>
        /// 最后上线时间
        /// </summary>
        public DateTime LastOnlineTime { get; set; }

        /// <summary>
        /// TCP客户端首次连接ID，在登录解析成功以后会被Number集中器编号覆盖
        /// </summary>
        public string ClientId { get; set; }

        /// <summary>
        /// TCP客户端断线时间，用于计算是否断线
        /// </summary>
        public DateTime? LastOfflineTime { get; set; }

        /// <summary>
        /// 设备状态
        /// </summary>
        [PartitionKey]
        public DeviceStatus Status { get; set; }

        /// <summary>
        /// 设备任务超时次数，超过一定次数则发出预警。
        /// </summary>
        public int TaskTimeOutCounts { get; set; } = 0;

        public void UpdateByLoginAndHeartbeat(string clientId)
        {
            LastOnlineTime = DateTime.Now;
            ClientId = clientId;
            Status = DeviceStatus.Online;
        }

        public void UpdateByLoginAndHeartbeat()
        {
            LastOnlineTime = DateTime.Now;
            Status = DeviceStatus.Online;
        }

        public void UpdateByOnClosed()
        {
            LastOfflineTime = DateTime.Now;
            Status = DeviceStatus.Offline;
        }
    }
}
