namespace SHH.CameraSdk;

/// <summary>
/// [海康] 错误码映射器 (V3.3.1 修复版)
/// <para>职责：将海康原始错误码映射为系统统一标准枚举，实现跨厂家故障语义归一化。</para>
/// <para>协作：为 HikVideoSource.ReportError 提供标准化故障信息，支撑协调器自愈决策。</para>
/// </summary>
public static class HikErrorMapper
{
    #region --- 静态映射资源 (Static Mapping Resources) ---

    /// <summary>
    /// 海康原始错误码 → 系统标准错误码 映射表（只读，初始化后不可修改）
    /// </summary>
    private static readonly ReadOnlyDictionary<uint, CameraErrorCode> _codeMap;

    /// <summary>
    /// 海康原始错误码 → 中文描述 映射表（只读，初始化后不可修改）
    /// </summary>
    private static readonly ReadOnlyDictionary<uint, string> _descMap;

    /// <summary>
    /// 静态构造函数：初始化错误码映射表（程序启动时仅执行一次）
    /// </summary>
    static HikErrorMapper()
    {
        // 1. 初始化：海康原始错误码 → 系统标准错误码 映射
        var codeDict = new Dictionary<uint, CameraErrorCode>
        {
            { 0, CameraErrorCode.Success },
            
            // --- 基础环境相关错误 ---
            { 3, CameraErrorCode.SdkNotInitialized },     // SDK未初始化 (对应 Bug S)
            { 41, CameraErrorCode.LocalResourceError },    // 资源分配错误 (对应 Bug R)
            { 121, CameraErrorCode.ComponentVersionMismatch }, // 动态库版本不匹配
            
            // --- 网络通信相关错误 ---
            { 7, CameraErrorCode.NetworkUnreachable },     // 连接设备失败（设备离线/网络不通）
            { 10, CameraErrorCode.Timeout },               // 发送数据超时
            { 11, CameraErrorCode.NetworkRecvError },      // 接收数据超时
            { 73, CameraErrorCode.SocketError },           // Socket创建失败
            
            // --- 身份认证相关错误 ---
            { 1, CameraErrorCode.InvalidCredentials },     // 用户名或密码错误
            { 2, CameraErrorCode.AccessDenied },           // 权限不足
            { 47, CameraErrorCode.UserNotExist },          // 用户不存在
            { 153, CameraErrorCode.AccountLocked },        // 用户名被锁定
            
            // --- 设备资源相关错误 ---
            { 4, CameraErrorCode.InvalidChannel },         // 通道号错误
            { 5, CameraErrorCode.MaxConnectionsReached },  // 设备连接数超过最大限制 (对应 Bug W 幽灵登录后果)
            { 23, CameraErrorCode.NotSupported },          // 设备不支持该功能
            
            // --- 预览与播放相关错误 ---
            { 18, CameraErrorCode.ChannelException },      // 设备通道处于错误状态
            { 51, CameraErrorCode.PlayerSdkFailed },       // 调用播放库Player失败
            { 105, CameraErrorCode.StreamTypeNotSupport }  // 输入码流封装格式不支持
        };
        _codeMap = new ReadOnlyDictionary<uint, CameraErrorCode>(codeDict);

        // 2. 初始化：海康原始错误码 → 中文描述 映射
        var descDict = new Dictionary<uint, string>
        {
            { 0, "没有错误" },
            { 1, "用户名或密码错误" },
            { 2, "权限不足" },
            { 3, "SDK未初始化" },
            { 4, "通道号错误" },
            { 5, "设备连接数超过最大" },
            { 7, "连接设备失败(设备离线或网络不通)" },
            { 9, "从设备接收数据失败" },
            { 10, "向设备发送数据失败(超时)" },
            { 11, "从设备接收数据失败(超时)" },
            { 17, "参数错误" },
            { 18, "设备通道处于错误状态" },
            { 23, "设备不支持该功能" },
            { 24, "设备忙" },
            { 41, "SDK资源分配错误(内存不足)" },
            { 43, "缓冲区已满" },
            { 47, "用户不存在" },
            { 51, "调用播放库Player失败" },
            { 52, "登录设备用户数达到最大" },
            { 55, "IP地址不匹配" },
            { 56, "MAC地址不匹配" },
            { 73, "Socket创建失败" },
            { 105, "输入码流封装格式不支持" },
            { 121, "动态库版本不匹配" },
            { 153, "用户名被锁定" },
        };
        _descMap = new ReadOnlyDictionary<uint, string>(descDict);
    }

    #endregion

    #region --- 核心映射方法 (Core Mapping Methods) ---

    /// <summary>
    /// 将海康原始错误码转换为系统统一标准错误码
    /// </summary>
    /// <param name="hikErrorCode">海康 SDK 返回的原始错误码</param>
    /// <returns>系统标准错误码（未匹配到时返回 CameraErrorCode.Unknown）</returns>
    public static CameraErrorCode Map(uint hikErrorCode)
    {
        // 尝试从映射表获取，未找到则返回未知错误
        return _codeMap.TryGetValue(hikErrorCode, out var code) ? code : CameraErrorCode.Unknown;
    }

    /// <summary>
    /// 获取海康原始错误码的中文描述（含原始错误码）
    /// </summary>
    /// <param name="hikErrorCode">海康 SDK 返回的原始错误码</param>
    /// <returns>中文错误描述（格式：描述 (Code:原始错误码)）</returns>
    public static string GetRawDescription(uint hikErrorCode)
    {
        if (_descMap.TryGetValue(hikErrorCode, out var desc))
        {
            return $"{desc} (Code:{hikErrorCode})";
        }
        // 未匹配到的错误码，返回默认描述
        return $"未知海康错误 (Code:{hikErrorCode})";
    }

    #endregion
}