using IWS5.Api.Enum;
using IWS5.Api.OptionsSetup;
using IWS5.Core.DTO;
using IWS5.Core.Models;
using IWS5.Core.Models.Request;
using IWS5.Core.Models.Request.Process;
using IWS5.Core.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;

namespace IWS5.Api.Controllers;

[Authorize(Roles = nameof(UserGroups.PDAdminGroup))]
[Route("api/[controller]")]
[ApiController]
public class RightsController(IRightsService rightsService, ILogger<QueueController> logger) : ControllerBase
{
    /// <summary>
    /// Gets the process rights for a specific process and group.
    /// </summary>
    /// <param name="processId">The ID of the process.</param>
    /// <param name="groupGuid">The GUID of the group.</param>
    /// <returns>A list of process rights.</returns>
    /// <response code="200">Returns the list of process rights</response>
    /// <response code="401">If the token is invalid or missing</response>
    /// <response code="500">If an error occurs while retrieving the process</response>
    [HttpGet("process")]
    [SwaggerOperation(Summary = "Gets the process rights", Description = "Gets the process rights for a specific process and group.")]
    [SwaggerResponse(200, "Returns the list of process rights", typeof(Response<ProcessPermissionsDTO>))]
    [SwaggerResponse(401, "If the token is invalid or missing")]
    [SwaggerResponse(500, "If an error occurs while retrieving the process rights")]
    public async Task<IActionResult> GetProcessRights([FromQuery] int processId, [FromQuery] Guid groupGuid)
    {
        var userName = JwtTokenHelper.GetUserName(HttpContext, logger, out var actionResult);

        if (string.IsNullOrEmpty(userName))
        {
            return actionResult;
        }
        
        logger.LogInformation("User {UserName} is attempting to get rights", userName);
        var currentRights = await rightsService.ListProcessRights(new ListProcessRightsRequest(userName, processId, groupGuid));
        return Ok(currentRights);
    }

    /// <summary>
    /// Gets the queue rights for a specific queue and group.
    /// </summary>
    /// <param name="queueName">The ID of the queue.</param>
    /// <param name="groupGuid">The GUID of the group.</param>
    /// <returns>A list of queue rights.</returns>
    /// <response code="200">Returns the list of queue rights</response>
    /// <response code="401">If the token is invalid or missing</response>
    /// <response code="500">If an error occurs while retrieving the queue rights</response>
    [HttpGet("queue")]
    [SwaggerOperation(Summary = "Gets the queue rights", Description = "Gets the queue rights for a specific queue and group.")]
    [SwaggerResponse(200, "Returns the list of queue rights", typeof(Response<QueuePermissionDTO>))]
    [SwaggerResponse(401, "If the token is invalid or missing")]
    [SwaggerResponse(500, "If an error occurs while retrieving the queue rights")]
    public async Task<IActionResult> GetQueuesRights([FromQuery] int queueId, [FromQuery] Guid groupGuid)
    {
        var userName = JwtTokenHelper.GetUserName(HttpContext, logger, out var actionResult);

        if (string.IsNullOrEmpty(userName))
        {
            return actionResult;
        }
        
        var queuesRights = await rightsService.ListQueuesRights(new ListQueuesRightsRequest(userName, queueId, groupGuid));
        return Ok(queuesRights);
    }

    /// <summary>
    /// Inserts rights based on the provided request.
    /// </summary>
    /// <param name="request">The <see cref="UpdateRightRequest"/> containing the rights to be inserted.</param>
    /// <returns>A result indicating the result of the operation.</returns>
    /// <response code="200">If the rights were successfully inserted.</response>
    /// <response code="401">If the token is invalid or missing.</response>
    /// <response code="500">If an error occurs while inserting the rights.</response>
    [HttpPost]
    [SwaggerOperation(Summary = "Inserts rights", Description = "Inserts rights based on the provided request.")]
    [SwaggerResponse(200, "If the rights were successfully inserted.")]
    [SwaggerResponse(401, "If the token is invalid or missing.")]
    [SwaggerResponse(500, "If an error occurs while inserting the rights.")]
    public async Task<IActionResult> InsertRights([FromBody] RightRequest request)
    {
        var userName = JwtTokenHelper.GetUserName(HttpContext, logger, out var actionResult);

        if (string.IsNullOrEmpty(userName))
        {
            return actionResult;
        }
        
        try
        {
            logger.LogInformation("User {UserName} is attempting to insert rights", userName);
            await rightsService.UpdateRights(new UpdateRightRequest(userName, request));
            return Ok();
        }
        catch (Exception ex)
        {
            // Log any errors that occur during queue retrieval
            logger.LogError(ex, "An error occurred while inserting rights for user {UserName}", userName);
            return StatusCode(500, "An error occurred while inserting rights." + ex.Message);
        }
    }
}
