using System.ComponentModel;
using System.Runtime.CompilerServices;

/// <summary>
/// 代表一个网络摄像头的模型，用于在 UI 上显示和监控其状态。
/// 实现了 <see cref="INotifyPropertyChanged"/> 接口，当属性值改变时可以通知视图进行更新。
/// </summary>
public class WebApiCameraModel : INotifyPropertyChanged
{
    #region --- INotifyPropertyChanged 实现 ---

    /// <summary>
    /// 当属性值更改时发生。
    /// </summary>
    public event PropertyChangedEventHandler? PropertyChanged;

    /// <summary>
    /// 引发 <see cref="PropertyChanged"/> 事件。
    /// </summary>
    /// <param name="propertyName">已更改的属性名称。如果未提供，则使用调用方成员的名称。</param>
    protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    /// <summary>
    /// 设置属性值的通用方法。只有当值发生变化时，才会更新字段并通知属性更改。
    /// </summary>
    /// <typeparam name="T">属性的类型。</typeparam>
    /// <param name="field">对存储属性值的字段的引用。</param>
    /// <param name="value">属性的新值。</param>
    /// <param name="propertyName">属性的名称。</param>
    /// <returns>如果值已更改，则返回 <c>true</c>；否则返回 <c>false</c>。</returns>
    protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
    {
        if (Equals(field, value))
        {
            return false;
        }

        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    #endregion

    #region --- 摄像头属性 ---

    private int _id;
    /// <summary>
    /// 获取或设置摄像头的唯一标识符。
    /// </summary>
    public int Id
    {
        get => _id;
        set => SetProperty(ref _id, value);
    }

    private string _name = string.Empty;
    /// <summary>
    /// 获取或设置摄像头的自定义名称。
    /// </summary>
    public string Name
    {
        get => _name;
        set => SetProperty(ref _name, value);
    }

    private string _ipAddress = string.Empty;
    /// <summary>
    /// 获取或设置摄像头的 IP 地址。
    /// </summary>
    public string IpAddress
    {
        get => _ipAddress;
        set => SetProperty(ref _ipAddress, value);
    }

    private string _brand = string.Empty;
    /// <summary>
    /// 获取或设置摄像头的品牌。
    /// </summary>
    public string Brand
    {
        get => _brand;
        set => SetProperty(ref _brand, value);
    }

    private string _status = string.Empty;
    /// <summary>
    /// 获取或设置摄像头的综合状态描述（例如："在线", "离线", "连接中"）。
    /// </summary>
    public string Status
    {
        get => _status;
        set => SetProperty(ref _status, value);
    }

    private bool _isOnline;
    /// <summary>
    /// 获取或设置一个值，该值指示摄像头的逻辑连接状态（API 是否可达）。
    /// </summary>
    public bool IsOnline
    {
        get => _isOnline;
        set => SetProperty(ref _isOnline, value);
    }

    private bool _isPhysicalOnline;
    /// <summary>
    /// 获取或设置一个值，该值指示摄像头的物理连接状态（例如：通过 ICMP ping 检测）。
    /// </summary>
    public bool IsPhysicalOnline
    {
        get => _isPhysicalOnline;
        set => SetProperty(ref _isPhysicalOnline, value);
    }

    private bool _isRunning;
    /// <summary>
    /// 获取或设置一个值，该值指示摄像头的流媒体服务是否正在运行。
    /// </summary>
    public bool IsRunning
    {
        get => _isRunning;
        set => SetProperty(ref _isRunning, value);
    }

    private int _width;
    /// <summary>
    /// 获取或设置摄像头视频流的宽度（分辨率）。
    /// </summary>
    public int Width
    {
        get => _width;
        set => SetProperty(ref _width, value);
    }

    private int _height;
    /// <summary>
    /// 获取或设置摄像头视频流的高度（分辨率）。
    /// </summary>
    public int Height
    {
        get => _height;
        set => SetProperty(ref _height, value);
    }

    private int _realFps;
    /// <summary>
    /// 获取或设置摄像头当前的实际帧率（FPS）。
    /// </summary>
    public int RealFps
    {
        get => _realFps;
        set => SetProperty(ref _realFps, value);
    }

    private long _totalFrames;
    /// <summary>
    /// 获取或设置自启动以来收到的总帧数。
    /// </summary>
    public long TotalFrames
    {
        get => _totalFrames;
        set => SetProperty(ref _totalFrames, value);
    }

    private int _streamType;
    /// <summary>
    /// 获取或设置视频流的类型（例如：0 = 主码流, 1 = 子码流）。
    /// </summary>
    public int StreamType
    {
        get => _streamType;
        set => SetProperty(ref _streamType, value);
    }

    #endregion
}