using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using VigilCare.ClinicalContracts.Sync;

[ApiController]
[Produces("application/json")]
public class GatewaysController : ControllerBase
{
    private readonly IGatewayRegistryService _gateways;

    public GatewaysController(IGatewayRegistryService gateways) => _gateways = gateways;

    [HttpPost("api/v1/sites/{siteId:guid}/gateways")]
    [Authorize]
    [AuthorizePermission(ClinicalPermissions.UsersAdmin)]
    [ProducesResponseType(typeof(ApiResponse<WardGatewayResponse>), StatusCodes.Status201Created)]
    public async Task<IActionResult> Register(Guid siteId, [FromBody] RegisterGatewayRequest req)
    {
        var gateway = await _gateways.RegisterAsync(siteId, req);
        return StatusCode(201, ApiResponse<WardGatewayResponse>.Created(MapGateway(gateway)));
    }

    [HttpGet("api/v1/sites/{siteId:guid}/gateways")]
    [Authorize]
    [AuthorizePermission(ClinicalPermissions.UsersAdmin)]
    public async Task<IActionResult> ListBySite(Guid siteId, [FromQuery] string? department)
    {
        var gateways = await _gateways.ListBySiteAsync(siteId, department);
        return Ok(ApiResponse<List<WardGatewayResponse>>.Ok(gateways.Select(MapGateway).ToList()));
    }

    [HttpGet("api/v1/gateways/{gatewayId:guid}")]
    [Authorize]
    [AuthorizePermission(ClinicalPermissions.UsersAdmin)]
    public async Task<IActionResult> Get(Guid gatewayId)
    {
        var gateway = await _gateways.GetByIdAsync(gatewayId);
        return Ok(ApiResponse<WardGatewayResponse>.Ok(MapGateway(gateway)));
    }

    [HttpPatch("api/v1/gateways/{gatewayId:guid}/heartbeat")]
    [Authorize(AuthenticationSchemes = GatewayApiKeyAuthenticationHandler.SchemeName)]
    public async Task<IActionResult> Heartbeat(Guid gatewayId, [FromBody] GatewayHeartbeatRequest req)
    {
        var authGatewayId = User.FindFirstValue("gateway_id");
        var gateway = await _gateways.RecordHeartbeatAsync(gatewayId, req, authGatewayId);
        return Ok(ApiResponse<WardGatewayResponse>.Ok(MapGateway(gateway)));
    }

    private static WardGatewayResponse MapGateway(WardGateway g) =>
        new(g.Id, g.SiteId, g.GatewayCode, g.Department,
            g.Status.ToDbString(), g.ReportedBufferDepth,
            g.LastHeartbeatAt, g.LastSyncAt);
}