using Asp.Versioning;
using Core.Cerberos.Adapters;
using Core.Cerberos.Adapters.Attributes;
using Core.Cerberos.Adapters.Common.Constants;
using Core.Cerberos.Application.UseCases.Permissions.Input;
using Core.Cerberos.Application.UseCases.Permissions.Ports;
using Lib.Architecture.BuildingBlocks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Core.Cerberos.Service.API.Controllers
{
    /// 
    /// Handles all services and business rules related to .
    /// 
    [ApiVersion("1.0")]
    [Route("api/v{api-version:apiVersion}/[controller]")]
    [Produces("application/json")]
    [ApiController]
    public class PermissionController : ControllerBase
    {
        private readonly IComponentHandler getPermissionHandler;
        private readonly IComponentHandler getAllPermissionsHandler;
        private readonly IComponentHandler getAllPermissionsByListHandler;
        private readonly IComponentHandler createPermissionHandler;
        private readonly IComponentHandler updatePermissionHandler;
        private readonly IComponentHandler changePermissionStatusHandler;
        private readonly IPermissionPort port;
        /// 
        /// Handles all services and business rules related to .
        /// 
        public PermissionController(
            IComponentHandler getPermissionHandler,
            IComponentHandler getAllPermissionsHandler,
            IComponentHandler getAllPermissionsByListHandler,
            IComponentHandler createPermissionHandler,
            IComponentHandler updatePermissionHandler,
            IComponentHandler changePermissionStatusHandler,
            IPermissionPort port
            )
        {
            this.createPermissionHandler = createPermissionHandler;
            this.updatePermissionHandler = updatePermissionHandler;
            this.changePermissionStatusHandler = changePermissionStatusHandler;
            this.getAllPermissionsHandler = getAllPermissionsHandler;
            this.getPermissionHandler = getPermissionHandler;
            this.getAllPermissionsByListHandler = getAllPermissionsByListHandler;
            this.port = port;
        }
        /// 
        /// Gets all the permissions.
        /// 
        [HttpGet("GetAll")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        [ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
        [ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [Authorize(AuthenticationSchemes = Schemes.HeathScheme)]
        [Permission("PermissionManagement.Read, RoleManagement.Read")]
        public async Task GetAllPermissionsAsync(CancellationToken cancellationToken)
        {
            await getAllPermissionsHandler.ExecuteAsync(new GetAllPermissionsRequest { }, cancellationToken).ConfigureAwait(false);
            return port.ViewModel;
        }
        /// 
        /// Gets all the permissions by permission identifiers.
        /// 
        /// The request containing the list of permission identifiers.
        /// Cancellation token for the asynchronous operation.
        /// The  representing the result of the service call.
        /// The permissions found.
        /// No content if no permissions are found.
        /// Bad request if the permission identifiers are missing or invalid.
        /// Unauthorized if the user is not authenticated.
        /// Precondition failed if the request does not meet expected conditions.
        /// Unprocessable entity if the request cannot be processed.
        /// Internal server error if an unexpected error occurs.
        [HttpPost]
        [Route(Routes.GetPermissionList)]
        [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        [ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
        [ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        [Authorize(AuthenticationSchemes = Schemes.HeathScheme)]
        [Permission("PermissionManagement.Read")]
        public async Task GetAllPermissionsByListAsync([FromBody] GetAllPermissionsByListRequest request, CancellationToken cancellationToken)
        {
            if (request == null || request.Permissions == null || !request.Permissions.Any())
            {
                return BadRequest("Permission identifiers are required.");
            }
            await getAllPermissionsByListHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
            return port.ViewModel;
        }
        /// 
        /// Gets the permission by identifier.
        /// 
        [HttpPost]
        [Route("GetById")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        [ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
        [ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        [Authorize(AuthenticationSchemes = Schemes.HeathScheme)]
        [Permission("PermissionManagement.Read")]
        public async Task GetPermissionById([FromBody] GetPermissionRequest request, CancellationToken cancellationToken)
        {
            if (request.Id == null || !request.Id.Any())
            {
                return BadRequest("Invalid Permission Id");
            }
            await getPermissionHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
            return port.ViewModel;
        }
        /// 
        /// Creates a new permission.
        /// 
        [HttpPost("Create")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        [ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
        [ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [Authorize(AuthenticationSchemes = Schemes.HeathScheme)]
        [Permission("PermissionManagement.Write")]
        public async Task CreatePermissionAsync([FromBody] CreatePermissionRequest newPermission, CancellationToken cancellationToken = default)
        {
            await createPermissionHandler.ExecuteAsync(newPermission, cancellationToken).ConfigureAwait(false);
            return port.ViewModel;
        }
        /// 
        /// Updates a full permission by identifier.
        /// 
        [HttpPut("Update")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        [ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
        [ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [Authorize(AuthenticationSchemes = Schemes.HeathScheme)]
        [Permission("PermissionManagement.Write")]
        public async Task UpdatePermissionAsync([FromBody] UpdatePermissionRequest request, CancellationToken cancellationToken = default)
        {
            await updatePermissionHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
            return port.ViewModel;
        }
        /// 
        /// Changes the status of the permission.
        /// 
        [HttpPatch]
        [Route("ChangeStatus")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        [ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
        [ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        [Authorize(AuthenticationSchemes = Schemes.HeathScheme)]
        [Permission("PermissionManagement.Write")]
        public async Task ChangePermissionStatusAsync([FromBody] ChangePermissionStatusRequest request,
                                                                     CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(request.Id)) { return BadRequest("Invalid permission identifier"); }
            await changePermissionStatusHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
            return port.ViewModel;
        }
    }
}