using Tiku.Api.Middleware;
using Tiku.Api.Controllers;
using Tiku.Application.Auth;
using Tiku.Application.Security;

namespace Tiku.Api.Modules.System.Auth.Errors;

internal sealed class AuthExceptionProblemDetailsMapper : ExceptionProblemDetailsMapper
{
    public override IReadOnlyCollection<Type> HandledExceptionTypes { get; } =
    [
        typeof(AuthorizationSecurityUnavailableException), typeof(AuthException), typeof(OwnerActivationException),
        typeof(BrowserOriginException), typeof(FeatureAccessException)
    ];

    public override bool TryMap(Exception exception, out ExceptionProblemDetailsMapping mapping)
    {
        return exception switch
        {
            AuthorizationSecurityUnavailableException => Mapped(exception, StatusCodes.Status503ServiceUnavailable,
                "auth_security_unavailable", out mapping),
            AuthException auth => Mapped(auth, AuthStatus(auth.Code), auth.Code, out mapping),
            OwnerActivationException activation => Mapped(activation,
                activation.Code == "owner_activation_consumed"
                    ? StatusCodes.Status409Conflict
                    : StatusCodes.Status400BadRequest, activation.Code, out mapping),
            BrowserOriginException => Mapped(exception, StatusCodes.Status403Forbidden, "browser_origin_rejected",
                out mapping),
            FeatureAccessException feature => Mapped(feature,
                feature.Code == "feature_quota_exhausted"
                    ? StatusCodes.Status409Conflict
                    : StatusCodes.Status403Forbidden, feature.Code, out mapping),
            _ => NotMapped(out mapping)
        };
    }

    private static int AuthStatus(string code)
    {
        return code switch
        {
            "tenant_access_denied" => StatusCodes.Status403Forbidden,
            "auth_session_not_found" => StatusCodes.Status404NotFound,
            "current_auth_session_cannot_be_revoked" => StatusCodes.Status409Conflict,
            "sms_rate_limited" => StatusCodes.Status429TooManyRequests,
            "auth_provider_not_configured" or "auth_security_unavailable" =>
                StatusCodes.Status503ServiceUnavailable,
            "session_revoked" => StatusCodes.Status401Unauthorized,
            _ => StatusCodes.Status401Unauthorized
        };
    }
}
