using Grpc.Core;
using GEUTEBRUECK.GeViSoftSDKNET.ActionsWrapper;

namespace GeViScopeBridge.Utils
{
    /// <summary>
    /// Translates GeViScope SDK errors to gRPC status codes
    /// </summary>
    public static class ErrorTranslator
    {
        /// <summary>
        /// Convert GeViConnectResult to gRPC StatusCode
        /// </summary>
        public static StatusCode ToStatusCode(GeViConnectResult result)
        {
            return result switch
            {
                GeViConnectResult.connectOk => StatusCode.OK,
                GeViConnectResult.connectFailed => StatusCode.Unavailable,
                GeViConnectResult.connectTimeout => StatusCode.DeadlineExceeded,
                GeViConnectResult.connectInvalidCredentials => StatusCode.Unauthenticated,
                GeViConnectResult.connectPermissionDenied => StatusCode.PermissionDenied,
                _ => StatusCode.Unknown
            };
        }

        /// <summary>
        /// Get user-friendly error message for GeViConnectResult
        /// </summary>
        public static string GetErrorMessage(GeViConnectResult result)
        {
            return result switch
            {
                GeViConnectResult.connectOk => "Connection successful",
                GeViConnectResult.connectFailed => "Connection to GeViServer failed",
                GeViConnectResult.connectTimeout => "Connection timeout",
                GeViConnectResult.connectInvalidCredentials => "Invalid username or password",
                GeViConnectResult.connectPermissionDenied => "Permission denied",
                _ => $"Unknown connection error: {result}"
            };
        }

        /// <summary>
        /// Create gRPC RpcException from GeViConnectResult
        /// </summary>
        public static RpcException CreateRpcException(GeViConnectResult result)
        {
            var statusCode = ToStatusCode(result);
            var message = GetErrorMessage(result);
            return new RpcException(new Status(statusCode, message));
        }

        /// <summary>
        /// Create gRPC RpcException from generic exception
        /// </summary>
        public static RpcException CreateRpcException(Exception ex, string context)
        {
            var message = $"{context}: {ex.Message}";
            return new RpcException(new Status(StatusCode.Internal, message));
        }

        /// <summary>
        /// Map Windows error code to gRPC StatusCode
        /// </summary>
        public static StatusCode WindowsErrorToStatusCode(int errorCode)
        {
            return errorCode switch
            {
                0 => StatusCode.OK,
                5 => StatusCode.PermissionDenied,      // ERROR_ACCESS_DENIED
                53 => StatusCode.Unavailable,           // ERROR_BAD_NETPATH
                64 => StatusCode.Unavailable,           // ERROR_NETNAME_DELETED
                87 => StatusCode.InvalidArgument,       // ERROR_INVALID_PARAMETER
                1203 => StatusCode.PermissionDenied,    // ERROR_NO_NET_OR_BAD_PATH
                1231 => StatusCode.Unavailable,         // ERROR_NETWORK_UNREACHABLE
                _ => StatusCode.Unknown
            };
        }

        /// <summary>
        /// Get HTTP status code equivalent (for documentation)
        /// </summary>
        public static int ToHttpStatusCode(StatusCode statusCode)
        {
            return statusCode switch
            {
                StatusCode.OK => 200,
                StatusCode.InvalidArgument => 400,
                StatusCode.Unauthenticated => 401,
                StatusCode.PermissionDenied => 403,
                StatusCode.NotFound => 404,
                StatusCode.DeadlineExceeded => 504,
                StatusCode.Unavailable => 503,
                StatusCode.Internal => 500,
                _ => 500
            };
        }
    }
}
