using adas_core.Application.Services.Interfaces;
using adas_core.Authentication.Attributes;
using adas_core.Domain.Enums;
using adas_core.Logging;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using WebPush;

namespace adas_core.Controllers;

[Route("send-alerts")]
[ApiController]
public class SendAlertController : ControllerBase
{
    private readonly ISendAlertService _sendAlertService;

    public SendAlertController(ISendAlertService sendAlertService)
    {
        LogExecutionContext.TrySetTraceIdentifier(Guid.NewGuid().ToString(), true);

        _sendAlertService = sendAlertService;
    }

    public static List<PushSubscription> Subscriptions { get; set; } = [];

    /// <summary>
    /// Retrieves the list of error queues from the alert service.
    /// </summary>
    /// <returns>An <see cref="IActionResult"/> containing the error queues returned by the service.</returns>
    [HttpGet("rabbit")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthAdmin)]
    public async Task<IActionResult> GetErrorQueues()
    {
        var errorQueues = await _sendAlertService.GetQueues();
        return Ok(errorQueues);
    }

    /// <summary>
    /// Retrieves performance metrics for the alert system.
    /// Requires the AuthAdmin role; the performance data is fetched from the send alert service and returned in an HTTP 200 OK response.
    /// </summary>
    /// <returns>An <see cref="IActionResult"/> containing the performance data returned by the service.</returns>
    [HttpGet("performance")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthAdmin)]
    public IActionResult GetPerformance()
    {
        var performance = _sendAlertService.GetPerformance();
        return Ok(performance);
    }

    /// <summary>
    /// Retrieves the list of configured API clients. Restricted to users with the AuthAdmin role.
    /// </summary>
    /// <returns>An <see cref="IActionResult"/> containing the collection of API clients returned by the send alert service.</returns>
    [HttpGet("api-clients")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthAdmin)]
    public async Task<IActionResult> GetApiClients()
    {
        var clients = await _sendAlertService.GetApiClients();
        return Ok(clients);
    }

    /// <summary>
    /// Registers a new web push subscription for push notifications by adding the provided subscription to the internal subscriptions store.
    /// </summary>
    /// <param name="sub">The push subscription payload received from the client, containing the endpoint and cryptographic keys required for delivering web push notifications.</param>
    /// <returns>An <see cref="IActionResult"/> containing an HTTP 200 OK response with a confirmation message indicating the subscription was accepted.</returns>
    [HttpPost("web-subscribe")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthAdmin)]
    public IActionResult WebSubscribe([FromBody] PushSubscription sub)
    {
        Subscriptions.Add(sub);
        return Ok("correct subscription");
    }

    /// <summary>
    /// Handles web push notification unsubscription for an authenticated admin user. Removes the matching subscription from the store when its endpoint is found; otherwise returns a failure message while still responding with a successful HTTP status.
    /// </summary>
    /// <param name="sub">The push subscription to remove, identified by its endpoint.</param>
    /// <returns>An <see cref="IActionResult"/> containing a success message when the subscription is removed, or a failure message when no matching subscription is found.</returns>
    [HttpPost("web-unsubscribe")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthAdmin)]
    public IActionResult WebUnSubscribe([FromBody] PushSubscription sub)
    {
        var item = Subscriptions.FirstOrDefault(s => s.Endpoint == sub.Endpoint);
        if (item != null)
        {
            Subscriptions.Remove(item);
            return Ok("subscripcion correcta");
        }

        return Ok("failed subscription");
    }

    /// <summary>
    /// Broadcasts a push notification to the subscription identified by the given endpoint. Requires the caller to have the AuthAdmin role, and returns NotFound when no matching subscription exists.
    /// </summary>
    /// <param name="sub">The endpoint identifier of the push subscription that will receive the notification.</param>
    /// <param name="message">The payload to send, serialized to JSON before transmission.</param>
    /// <returns>An <see cref="IActionResult"/> that returns NotFound if the subscription is not found, or Ok when the notification is sent successfully.</returns>
    [HttpPost("broadcast/{sub}")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthAdmin)]
    public IActionResult Broadcast(string sub, [FromBody] object message)
    {
        var vapidDetails = new VapidDetails("mailto:example@example.com",
            "BJk9MGeoFy4npXPA6PQIgZYW5oxhiiBm_t2pB08FiotYQ4UvSaibG3T946Oqrc_nP17tdONbx0O4k9dWnt16TMM",
            "21YckusFRv00z1nOTpLZK1NlMXSZxZECnpwbsaKTjOE");

        var client = new WebPushClient();
        var serializedMessage = JsonConvert.SerializeObject(message);
        var pushSubscription = Subscriptions.FirstOrDefault(s => s.Endpoint == sub);

        if (pushSubscription == null)
            return NotFound("Subscription not found");

        client.SendNotification(pushSubscription, serializedMessage, vapidDetails);

        return Ok("correct subscription");
    }
}