#nullable enable

namespace IGP.UnitySDK.Models
{
    public static class IGPErrorCodes
    {
        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_UNAUTHORIZED = "UNAUTHORIZED";
        public const string ERR_FORBIDDEN = "FORBIDDEN";
        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_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";
        public const string ERR_DIRECT_SESSION_REQUIRED = "DIRECT_SESSION_REQUIRED";
        public const string ERR_USER_SESSION_REQUIRED = "USER_SESSION_REQUIRED";
        public const string ERR_DIRECT_REFRESH_UNAVAILABLE = "DIRECT_REFRESH_UNAVAILABLE";
        public const string ERR_DIRECT_REQUEST_TIMEOUT = "DIRECT_REQUEST_TIMEOUT";
        public const string ERR_DIRECT_REQUEST_FAILED = "DIRECT_REQUEST_FAILED";
        public const string ERR_DIRECT_PROTOCOL = "DIRECT_PROTOCOL_ERROR";
        public const string ERR_DIRECT_API_URL_INVALID = "DIRECT_API_URL_INVALID";
        public const string ERR_DIRECT_PLATFORM_UNSUPPORTED = "DIRECT_PLATFORM_UNSUPPORTED";
        public const string ERR_ACCOUNT_CONTEXT_CONFLICT = "ACCOUNT_CONTEXT_CONFLICT";

        public const string CATEGORY_VALIDATION = "validation";
        public const string CATEGORY_AUTHORIZATION = "authorization";
        public const string CATEGORY_CHANNEL = "channel";
        public const string CATEGORY_RUNTIME = "runtime";

        public static string ResolveCategory(string? errorCode)
        {
            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:
                case ERR_DIRECT_API_URL_INVALID:
                case ERR_DIRECT_PLATFORM_UNSUPPORTED:
                    return CATEGORY_VALIDATION;
                case ERR_AUTHORIZATION_FAILED:
                case ERR_AUTHORIZATION_PIPE_REQUIRED:
                case ERR_UNAUTHORIZED:
                case ERR_FORBIDDEN:
                case ERR_DIRECT_SESSION_REQUIRED:
                case ERR_USER_SESSION_REQUIRED:
                case ERR_DIRECT_REFRESH_UNAVAILABLE:
                case ERR_ACCOUNT_CONTEXT_CONFLICT:
                    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;
            }
        }

        public static bool IsValidationError(string? errorCode) =>
            ResolveCategory(errorCode) == CATEGORY_VALIDATION;

        public static bool IsDesktopChannelError(string? errorCode) =>
            ResolveCategory(errorCode) == CATEGORY_CHANNEL;

        public static bool IsAuthorizationError(string? errorCode) =>
            ResolveCategory(errorCode) == CATEGORY_AUTHORIZATION;

        public static int GetHTTPErrorCode(string errorCode)
        {
            switch (errorCode)
            {
                case ERR_UNAUTHORIZED: return HTTP_UNAUTHORIZED;
                case ERR_FORBIDDEN:
                case ERR_APP_ID_MISMATCH:
                case ERR_EXECUTABLE_PATH_NOT_ALLOWED:
                    return HTTP_FORBIDDEN;
                default: return HTTP_BAD_REQUEST;
            }
        }

        public static string GetErrorMessage(string errorCode)
        {
            switch (errorCode)
            {
                case ERR_INVALID_INPUT: return "Invalid request";
                case ERR_UNAUTHORIZED: return "Unauthorized";
                case ERR_FORBIDDEN: return "Forbidden";
                case ERR_DESKTOP_SESSION_REQUIRED: return "Desktop session is required";
                case ERR_DESKTOP_USER_CONTEXT_REQUIRED: return "Desktop user context is required";
                case ERR_APP_ID_REQUIRED: return "App Id is required";
                case ERR_APP_ID_MISMATCH: return "App Id does not match";
                case ERR_EXECUTABLE_PATH_REQUIRED: return "Executable path is required";
                case ERR_EXECUTABLE_PATH_NOT_ALLOWED: return "Executable path is not allowed";
                case ERR_DESKTOP_SESSION_CAPABILITY_MISSING: return "Desktop capability is unavailable";
                case ERR_DESKTOP_PROTOCOL_INCOMPATIBLE: return "Desktop protocol is incompatible";
                case ERR_AUTHORIZATION_FAILED: return "Authorization failed";
                case ERR_AUTHORIZATION_PIPE_REQUIRED: return "Authorization pipe is required";
                case ERR_DIRECT_SESSION_REQUIRED: return "Direct user sign-in is required";
                case ERR_USER_SESSION_REQUIRED: return "A signed-in user session is required";
                case ERR_DIRECT_REFRESH_UNAVAILABLE: return "Direct user session cannot be refreshed";
                case ERR_DIRECT_REQUEST_TIMEOUT: return "Direct API request timed out";
                case ERR_DIRECT_REQUEST_FAILED: return "Direct API request failed";
                case ERR_DIRECT_PROTOCOL: return "Direct API response is invalid";
                case ERR_DIRECT_API_URL_INVALID: return "Direct API URL is invalid";
                case ERR_DIRECT_PLATFORM_UNSUPPORTED: return "Direct API is unsupported on this platform";
                case ERR_ACCOUNT_CONTEXT_CONFLICT: return "Desktop and direct user contexts do not match";
                default: return "Unknown error";
            }
        }
    }
}
