using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using Meezi.API.Models.Public;
using Meezi.API.Services;
using Meezi.Core.Interfaces;
using Meezi.Shared;

namespace Meezi.API.Controllers;

/// <summary>
/// Push-notification endpoints for the native (Capacitor + Pushe) app.
///
///   POST /api/public/push/register    — anonymous device registration
///   POST /api/public/push/unregister  — anonymous device removal
///   POST /api/push/broadcast          — authorized topic broadcast (marketing /
///                                        saved-café alerts)
/// </summary>
[ApiController]
public class PushController : ControllerBase
{
    private readonly IPushDeviceService _devices;
    private readonly IPushSender _sender;

    public PushController(IPushDeviceService devices, IPushSender sender)
    {
        _devices = devices;
        _sender = sender;
    }

    [HttpPost("api/public/push/register")]
    [AllowAnonymous]
    [EnableRateLimiting("public-read")]
    public async Task<IActionResult> Register(
        [FromBody] RegisterPushDeviceRequest request, CancellationToken ct)
    {
        if (string.IsNullOrWhiteSpace(request.Token))
            return BadRequest(new ApiResponse<object>(false, null,
                new ApiError("INVALID_TOKEN", "Device token is required.")));

        await _devices.RegisterAsync(request, ct);
        return Ok(new ApiResponse<object>(true, new { registered = true }));
    }

    [HttpPost("api/public/push/unregister")]
    [AllowAnonymous]
    [EnableRateLimiting("public-read")]
    public async Task<IActionResult> Unregister(
        [FromBody] UnregisterPushDeviceRequest request, CancellationToken ct)
    {
        await _devices.UnregisterAsync(request.Token, ct);
        return Ok(new ApiResponse<object>(true, new { unregistered = true }));
    }

    [HttpPost("api/push/broadcast")]
    [Authorize]
    public async Task<IActionResult> Broadcast(
        [FromBody] BroadcastPushRequest request, CancellationToken ct)
    {
        if (string.IsNullOrWhiteSpace(request.Topic))
            return BadRequest(new ApiResponse<object>(false, null,
                new ApiError("INVALID_TOPIC", "Topic is required.")));

        await _sender.SendToTopicAsync(request.Topic, request.Title, request.Body, request.DeepLink, ct);
        return Ok(new ApiResponse<object>(true, new { sent = true }));
    }
}
