using Nexus.Api.Http;
using Nexus.Api.Services;

namespace Nexus.Api.Controllers;

internal static class OpenClawContentReadEndpoint
{
    public static async Task<IResult> ExecuteAsync(Func<Task<IResult>> action)
    {
        try
        {
            return await action();
        }
        catch (OpenClawAgentConfigurationValidationException exception)
        {
            return Results.ValidationProblem(
                new Dictionary<string, string[]>
                {
                    [exception.Field] = [exception.Message]
                });
        }
        catch (OpenClawAgentConfigurationUnavailableException exception)
        {
            var status = exception.State switch
            {
                "forbidden" or "management_disabled" =>
                    StatusCodes.Status403Forbidden,
                "disconnected" => StatusCodes.Status503ServiceUnavailable,
                _ => StatusCodes.Status409Conflict
            };
            return NexusHttpResults.Problem(
                status,
                exception.Message,
                status switch
                {
                    StatusCodes.Status403Forbidden => NexusProblemCodes.Forbidden,
                    StatusCodes.Status503ServiceUnavailable => NexusProblemCodes.DependencyUnavailable,
                    _ => NexusProblemCodes.Conflict
                },
                extensions: new Dictionary<string, object?>
                {
                    ["method"] = exception.Method,
                    ["requiredScope"] = exception.RequiredScope,
                    ["state"] = exception.State
                });
        }
        catch (OpenClawAgentConfigurationVerificationException)
        {
            return NexusHttpResults.Problem(
                StatusCodes.Status502BadGateway,
                "OpenClaw-Antwort konnte nicht sicher verifiziert werden.",
                NexusProblemCodes.DependencyUnavailable,
                extensions: new Dictionary<string, object?>
                {
                    ["state"] = "verification_failed"
                });
        }
        catch (OpenClawGatewayRpcException exception)
        {
            var code = exception.Code.ToUpperInvariant();
            var status = code switch
            {
                "FORBIDDEN" or "AUTH_SCOPE_MISMATCH" =>
                    StatusCodes.Status403Forbidden,
                "METHOD_UNAVAILABLE" or "METHOD_NOT_FOUND"
                    or "NOT_IMPLEMENTED" =>
                    StatusCodes.Status409Conflict,
                "GATEWAY_DISCONNECTED" or "UNAVAILABLE" =>
                    StatusCodes.Status503ServiceUnavailable,
                "GATEWAY_TIMEOUT" or "TIMEOUT" =>
                    StatusCodes.Status504GatewayTimeout,
                _ => StatusCodes.Status502BadGateway
            };
            var problemCode = status switch
            {
                StatusCodes.Status403Forbidden => NexusProblemCodes.Forbidden,
                StatusCodes.Status409Conflict => NexusProblemCodes.UnsupportedCapability,
                StatusCodes.Status503ServiceUnavailable => NexusProblemCodes.DependencyUnavailable,
                StatusCodes.Status504GatewayTimeout => NexusProblemCodes.Timeout,
                _ => NexusProblemCodes.DependencyUnavailable
            };
            return NexusHttpResults.Problem(
                status,
                status switch
                {
                    StatusCodes.Status403Forbidden =>
                        "OpenClaw hat Nexus nicht die erforderliche Leseberechtigung gewährt.",
                    StatusCodes.Status409Conflict =>
                        "Die verbundene OpenClaw-Version unterstützt diese Leseoperation nicht.",
                    StatusCodes.Status503ServiceUnavailable =>
                        "OpenClaw Gateway ist nicht verfügbar.",
                    StatusCodes.Status504GatewayTimeout =>
                        "OpenClaw hat nicht rechtzeitig geantwortet.",
                    _ => "OpenClaw-Leseoperation ist fehlgeschlagen."
                },
                problemCode,
                extensions: new Dictionary<string, object?>
                {
                    ["state"] = code.ToLowerInvariant()
                });
        }
    }
}
