#nullable enable
using UnityEngine;

namespace IGP.UnitySDK.Models
{
    /// <summary>
    /// IGP API 错误码常量
    /// 与后端 internal/handler/errors.go 保持一致
    /// </summary>
    public static class IGPErrorCodes
    {
        // HTTP 状态码
        public const int HTTP_OK = 200;
        public const int HTTP_BAD_REQUEST = 400;
        public const int HTTP_UNAUTHORIZED = 401;
        public const int HTTP_FORBIDDEN = 403;
        public const int HTTP_NOT_FOUND = 404;
        public const int HTTP_CONFLICT = 409;
        public const int HTTP_TOO_MANY_REQUESTS = 429;

        // 业务错误码
        public const string ERR_INVALID_INPUT = "INVALID_INPUT";
        public const string ERR_ROOM_NOT_FOUND = "ROOM_NOT_FOUND";
        public const string ERR_PLAYER_NOT_FOUND = "PLAYER_NOT_FOUND";
        public const string ERR_ROOM_FULL = "ROOM_FULL";
        public const string ERR_TOO_MANY_ROOMS = "TOO_MANY_ROOMS";
        public const string ERR_UNAUTHORIZED = "UNAUTHORIZED";
        public const string ERR_FORBIDDEN = "FORBIDDEN";
        public const string ERR_PLAYER_ALREADY_IN_ROOM = "PLAYER_ALREADY_IN_ROOM";
        public const string ERR_PLAYER_NOT_IN_ROOM = "PLAYER_NOT_IN_ROOM";
        public const string ERR_DESKTOP_SESSION_REQUIRED = "DESKTOP_SESSION_REQUIRED";
        public const string ERR_DESKTOP_USER_CONTEXT_REQUIRED = "DESKTOP_USER_CONTEXT_REQUIRED";
        public const string ERR_ROOM_CONTEXT_REQUIRED = "ROOM_CONTEXT_REQUIRED";
        public const string ERR_APP_ID_REQUIRED = "APP_ID_REQUIRED";
        public const string ERR_APP_ID_MISMATCH = "APP_ID_MISMATCH";
        public const string ERR_EXECUTABLE_PATH_REQUIRED = "EXECUTABLE_PATH_REQUIRED";
        public const string ERR_EXECUTABLE_PATH_NOT_ALLOWED = "EXECUTABLE_PATH_NOT_ALLOWED";
        public const string ERR_DESKTOP_SESSION_CAPABILITY_MISSING = "DESKTOP_SESSION_CAPABILITY_MISSING";
        public const string ERR_DESKTOP_PROTOCOL_INCOMPATIBLE = "DESKTOP_PROTOCOL_INCOMPATIBLE";
        public const string ERR_AUTHORIZATION_FAILED = "AUTHORIZATION_FAILED";
        public const string ERR_AUTHORIZATION_PIPE_REQUIRED = "AUTHORIZATION_PIPE_REQUIRED";

        // WebSocket 错误码
        public const int WS_ERR_MISSING_PARAMS = 1000;
        public const int WS_ERR_INVALID_TOKEN = 1001;
        public const int WS_ERR_ROOM_NOT_FOUND = 1002;
        public const int WS_ERR_PLAYER_NOT_IN_ROOM = 1003;
        public const int WS_ERR_MESSAGE_FORMAT_ERROR = 1004;

        // 错误分类（category），与 GameMaker bridge 对齐。
        // 上层可以据此决定：validation 不重试；authorization 走授权刷新；
        // channel 走 desktop session 自愈；runtime 兜底告警。
        public const string CATEGORY_VALIDATION = "validation";
        public const string CATEGORY_AUTHORIZATION = "authorization";
        public const string CATEGORY_CHANNEL = "channel";
        public const string CATEGORY_RUNTIME = "runtime";

        /// <summary>
        /// 根据错误码推断分类，当 desktop session 未携带 category 字段时使用。
        /// </summary>
        public static string ResolveCategory(string? errorCode)
        {
            if (string.IsNullOrWhiteSpace(errorCode))
            {
                return CATEGORY_RUNTIME;
            }

            switch (errorCode)
            {
                case ERR_APP_ID_REQUIRED:
                case ERR_APP_ID_MISMATCH:
                case ERR_EXECUTABLE_PATH_REQUIRED:
                case ERR_EXECUTABLE_PATH_NOT_ALLOWED:
                case ERR_DESKTOP_PROTOCOL_INCOMPATIBLE:
                case ERR_INVALID_INPUT:
                    return CATEGORY_VALIDATION;

                case ERR_AUTHORIZATION_FAILED:
                case ERR_AUTHORIZATION_PIPE_REQUIRED:
                case ERR_UNAUTHORIZED:
                case ERR_FORBIDDEN:
                    return CATEGORY_AUTHORIZATION;

                case ERR_DESKTOP_SESSION_REQUIRED:
                case ERR_DESKTOP_USER_CONTEXT_REQUIRED:
                case ERR_DESKTOP_SESSION_CAPABILITY_MISSING:
                case "DESKTOP_SESSION_BRIDGE_ERROR":
                    return CATEGORY_CHANNEL;

                default:
                    return CATEGORY_RUNTIME;
            }
        }

        /// <summary>
        /// 是否属于无需重试的参数/配置错误。上层拿到这类错误应停止自愈并把问题抛给用户。
        /// </summary>
        public static bool IsValidationError(string? errorCode)
        {
            return ResolveCategory(errorCode) == CATEGORY_VALIDATION;
        }

        /// <summary>
        /// 是否属于 desktop session 通道问题，适合触发自动重连/重试。
        /// </summary>
        public static bool IsDesktopChannelError(string? errorCode)
        {
            return ResolveCategory(errorCode) == CATEGORY_CHANNEL;
        }

        /// <summary>
        /// 是否属于授权问题，适合走“重新请求授权”而不是“重新 attach”。
        /// </summary>
        public static bool IsAuthorizationError(string? errorCode)
        {
            return ResolveCategory(errorCode) == CATEGORY_AUTHORIZATION;
        }

        /// <summary>
        /// 获取错误码对应的 HTTP 状态码
        /// </summary>
        public static int GetHTTPErrorCode(string errorCode)
        {
            switch (errorCode)
            {
                case "INVALID_INPUT":
                    return HTTP_BAD_REQUEST;
                case "ROOM_NOT_FOUND":
                case "PLAYER_NOT_FOUND":
                    return HTTP_NOT_FOUND;
                case "ROOM_FULL":
                    return HTTP_CONFLICT;
                case "TOO_MANY_ROOMS":
                    return HTTP_TOO_MANY_REQUESTS;
                case "UNAUTHORIZED":
                    return HTTP_UNAUTHORIZED;
                case "FORBIDDEN":
                    return HTTP_FORBIDDEN;
                case "PLAYER_ALREADY_IN_ROOM":
                case "PLAYER_NOT_IN_ROOM":
                    return HTTP_CONFLICT;
                case "APP_ID_REQUIRED":
                case "EXECUTABLE_PATH_REQUIRED":
                    return HTTP_BAD_REQUEST;
                case "APP_ID_MISMATCH":
                case "EXECUTABLE_PATH_NOT_ALLOWED":
                    return HTTP_FORBIDDEN;
                default:
                    return HTTP_BAD_REQUEST;
            }
        }

        /// <summary>
        /// 获取错误描述（中文）
        /// </summary>
        public static string GetErrorMessage(string errorCode)
        {
            switch (errorCode)
            {
                case "INVALID_INPUT":
                    return "请求参数无效";
                case "ROOM_NOT_FOUND":
                    return "房间不存在";
                case "PLAYER_NOT_FOUND":
                    return "玩家不存在";
                case "ROOM_FULL":
                    return "房间已满";
                case "TOO_MANY_ROOMS":
                    return "房间数量达到上限";
                case "UNAUTHORIZED":
                    return "未授权";
                case "FORBIDDEN":
                    return "权限不足";
                case "PLAYER_ALREADY_IN_ROOM":
                    return "玩家已在房间中";
                case "PLAYER_NOT_IN_ROOM":
                    return "玩家不在房间中";
                case "DESKTOP_SESSION_REQUIRED":
                    return "需要先连接桌面会话";
                case "DESKTOP_USER_CONTEXT_REQUIRED":
                    return "桌面端当前没有可用的登录用户";
                case "ROOM_CONTEXT_REQUIRED":
                    return "当前能力需要房间上下文";
                case "APP_ID_REQUIRED":
                    return "缺少应用 ID";
                case "APP_ID_MISMATCH":
                    return "应用 ID 不匹配";
                case "EXECUTABLE_PATH_REQUIRED":
                    return "缺少可执行文件路径";
                case "EXECUTABLE_PATH_NOT_ALLOWED":
                    return "当前可执行文件路径不被允许";
                case "DESKTOP_SESSION_CAPABILITY_MISSING":
                    return "当前桌面会话不支持该能力";
                case "DESKTOP_PROTOCOL_INCOMPATIBLE":
                    return "desktop 版本过旧，请升级 desktop";
                case "AUTHORIZATION_FAILED":
                    return "授权验证失败";
                case "AUTHORIZATION_PIPE_REQUIRED":
                    return "缺少授权验证管道";
                default:
                    return "未知错误";
            }
        }
    }
}
