namespace SHH.CameraSdk;

/// <summary>
/// 增强型设备元数据中心 (V3.3.1 修复版)
/// 核心职责：
/// <para>1. 封装设备的硬件参数、通道能力、功能集，提供能力自发现</para>
/// <para>2. 支持元数据同步与差异对比，指导上层模块执行差异化处理</para>
/// <para>3. 存储运维指标与 SDK 原生句柄，支撑故障诊断与性能调优</para>
/// 设计特性：只读优先，通过版本号标记同步状态，避免并发修改冲突
/// </summary>
public class DeviceMetadata
{
    #region --- 1. 设备级身份信息 (Identity) ---

    /// <summary> 设备型号名称（如 DS-2CD3T47G2-LIU） </summary>
    public string ModelName { get; init; } = "Unknown";

    /// <summary> 设备唯一序列号（全局唯一，用于设备溯源） </summary>
    public string SerialNumber { get; init; } = string.Empty;

    /// <summary> 固件/系统版本号（用于判断 SDK 兼容性） </summary>
    public string FirmwareVersion { get; init; } = string.Empty;

    /// <summary> 所属厂商/品牌（决定驱动适配逻辑） </summary>
    public DeviceBrand Brand { get; init; } = DeviceBrand.Unknown;

    /// <summary> 元数据版本号（本地刷新计数，每次同步自增） </summary>
    public long Version { get; private set; }

    /// <summary> 最后同步时间（标记元数据的最新有效时刻） </summary>
    public DateTime LastSyncedAt { get; private set; }

    #endregion

    #region --- 2. 级联能力模型 (Cascaded Capabilities) ---

    private readonly ReadOnlyCollection<ChannelMetadata> _channels;

    /// <summary> 通道元数据集合（只读，防止外部篡改） </summary>
    public ReadOnlyCollection<ChannelMetadata> Channels
    {
        get => _channels;
        init => _channels = value ?? new ReadOnlyCollection<ChannelMetadata>(new List<ChannelMetadata>());
    }

    /// <summary> 设备总通道数量（IPC 通常为 1，NVR 为接入路数） </summary>
    public int ChannelCount => Channels.Count;

    /// <summary> 索引器：通过通道号快速获取对应通道的能力描述 </summary>
    /// <param name="channelIndex">物理通道号</param>
    /// <returns>通道元数据 / 不存在则返回 null</returns>
    public ChannelMetadata? this[int channelIndex] =>
        Channels.FirstOrDefault(c => c.ChannelIndex == channelIndex);

    #endregion

    #region --- 3. 运维指标与非托管句柄 ---

    /// <summary> 设备实时健康度字典（如 CPU 使用率、温度、内存占用等） </summary>
    public Dictionary<string, object> HealthMetrics { get; init; } = new();

    /// <summary>
    /// 厂商 SDK 原始句柄/结构体快照
    /// <para>注意事项：</para>
    /// <para>1. 标记 [JsonIgnore] 防止序列化非托管指针导致程序崩溃</para>
    /// <para>2. 仅用于驱动层与 SDK 交互，上层业务禁止直接操作</para>
    /// </summary>
    [JsonIgnore]
    public object? NativeHandle { get; init; }

    /// <summary> 厂商扩展标签（如设备位置、安装时间、责任人等自定义信息） </summary>
    public Dictionary<string, string> Tags { get; init; } = new();

    #endregion

    #region --- 4. 构造与同步 (Constructor & Sync) ---

    /// <summary>
    /// 默认构造函数（用于 BaseVideoSource 初始状态，无通道数据）
    /// </summary>
    public DeviceMetadata() : this(Enumerable.Empty<ChannelMetadata>()) { }

    /// <summary>
    /// 完整构造函数（初始化通道元数据集合）
    /// </summary>
    /// <param name="channels">通道元数据列表</param>
    public DeviceMetadata(IEnumerable<ChannelMetadata> channels)
    {
        // 转换为只读集合，确保通道数据不可变
        _channels = new ReadOnlyCollection<ChannelMetadata>(channels?.ToList() ?? new List<ChannelMetadata>());
        // 标记初始同步状态
        MarkSynced();
    }

    /// <summary>
    /// 标记元数据同步完成
    /// <para>作用：更新版本号与同步时间，用于差异对比的基准判断</para>
    /// </summary>
    public void MarkSynced()
    {
        Version++;
        LastSyncedAt = DateTime.Now;
    }

    #endregion

    #region --- 5. 业务逻辑辅助方法 (Business Helpers) ---

    /// <summary>
    /// 校验动态流配置的合法性（基于设备能力）
    /// </summary>
    /// <param name="options">待校验的动态配置项</param>
    /// <param name="errorMessage">校验失败时的详细原因</param>
    /// <returns>合法返回 true，非法返回 false</returns>
    public bool ValidateOptions(DynamicStreamOptions options, out string errorMessage)
    {
        errorMessage = string.Empty;
        if (options == null) return true;

        // 示例校验规则：云台控制权限校验
        if (options.VendorExtensions?.ContainsKey("PtzAction") == true
            && !Channels.Any(c => c.SupportPtz))
        {
            errorMessage = "该设备物理硬件不支持云台控制功能";
            return false;
        }

        // 可扩展其他校验规则：如分辨率合法性、码流类型支持性等
        return true;
    }

    /// <summary>
    /// 元数据差异比对逻辑（用于 BaseVideoSource.RefreshMetadataAsync 方法）
    /// </summary>
    /// <param name="other">最新拉取的设备元数据</param>
    /// <returns>元数据差异描述符</returns>
    public MetadataDiff CompareWith(DeviceMetadata other)
    {
        // 入参防护：对比对象为空则返回无差异
        if (other == null) return MetadataDiff.None;

        return new MetadataDiff
        {
            // 1. 基础信息变更：任意通道名称变化则标记
            NameChanged = this.Channels.Any(c =>
            {
                var targetChannel = other[c.ChannelIndex];
                return targetChannel != null && targetChannel.Name != c.Name;
            }),

            // 2. 能力集变更：PTZ/音频/AI 功能支持状态变化则标记
            CapabilityChanged = this.Channels.Any(c =>
            {
                var targetChannel = other[c.ChannelIndex];
                if (targetChannel == null) return false;

                return targetChannel.SupportPtz != c.SupportPtz
                       || targetChannel.SupportAudioIn != c.SupportAudioIn
                       || targetChannel.SupportAiAnalysis != c.SupportAiAnalysis;
            }),

            // 3. 致命变更：品牌不一致或通道数量变化（设备更换/替换场景）
            IsMajorChange = this.Brand != other.Brand || this.ChannelCount != other.ChannelCount,

            // 4. 分辨率配置变更：任意通道的分辨率档位数量变化则标记
            ResolutionProfilesChanged = this.Channels.Any(c =>
            {
                var targetChannel = other[c.ChannelIndex];
                return targetChannel != null
                       && targetChannel.SupportedResolutions.Count != c.SupportedResolutions.Count;
            })
        };
    }

    #endregion
}