using GerbilManagerWebAPI.Models;
using GerbilManagerWebAPI.Push;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.EntityFrameworkCore;

namespace GerbilManagerWebAPI.Endpoints
{
    /// <summary>
    /// 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 <see cref="PushNotifier"/> (z. B. wenn die KI eine
    /// Rückfrage stellt oder ein Ticket löst — gesteuert über das notify-Flag auf PUT /feedback).
    /// </summary>
    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<Results<Ok, BadRequest<string>>> (
                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;
        }
    }
}
