using GerbilManagerWebAPI.Models;
using GerbilManagerWebAPI.Push;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.EntityFrameworkCore;
namespace GerbilManagerWebAPI.Endpoints
{
///
/// WEB-PUSH: PWA-Benachrichtigungen für die Züchterin.
/// GET /push/vapid-public-key -> öffentlicher VAPID-Schlüssel (für das Abonnieren im Browser).
/// POST /push/subscribe -> Browser-Abo speichern (idempotent über die Endpoint-URL).
/// POST /push/unsubscribe -> Abo entfernen.
/// Das eigentliche Senden passiert über (z. B. wenn die KI eine
/// Rückfrage stellt oder ein Ticket löst — gesteuert über das notify-Flag auf PUT /feedback).
///
public static class PushEndpoints
{
public record PushSubscriptionInput(string Endpoint, string P256dh, string Auth);
public record PushUnsubscribeInput(string Endpoint);
public static IEndpointRouteBuilder MapPushEndpoints(this IEndpointRouteBuilder app)
{
var group = app.MapGroup("/push").WithTags("Push");
group.MapGet("/vapid-public-key", (PushNotifier push) =>
TypedResults.Ok(new { publicKey = push.PublicKey, enabled = push.Enabled }));
group.MapPost("/subscribe", async Task>> (
PushSubscriptionInput input, ApplicationContext db) =>
{
if (string.IsNullOrWhiteSpace(input.Endpoint)
|| string.IsNullOrWhiteSpace(input.P256dh)
|| string.IsNullOrWhiteSpace(input.Auth))
return TypedResults.BadRequest("Endpoint, P256dh und Auth sind erforderlich.");
var existing = await db.WebPushSubscriptions
.FirstOrDefaultAsync(s => s.Endpoint == input.Endpoint);
if (existing is null)
{
db.WebPushSubscriptions.Add(new WebPushSubscription
{
Id = Guid.NewGuid(),
Endpoint = input.Endpoint,
P256dh = input.P256dh,
Auth = input.Auth,
CreatedAt = DateTimeOffset.UtcNow,
});
}
else
{
existing.P256dh = input.P256dh;
existing.Auth = input.Auth;
}
await db.SaveChangesAsync();
return TypedResults.Ok();
});
group.MapPost("/unsubscribe", async (PushUnsubscribeInput input, ApplicationContext db) =>
{
var subs = await db.WebPushSubscriptions
.Where(s => s.Endpoint == input.Endpoint)
.ToListAsync();
if (subs.Count > 0)
{
db.WebPushSubscriptions.RemoveRange(subs);
await db.SaveChangesAsync();
}
return TypedResults.NoContent();
});
return app;
}
}
}