using Asp.Versioning;
using Core.Blueprint.Application.UsesCases.BlobStorage.Input;
using Core.Blueprint.Application.UsesCases.BlobStorage.Ports;
using Core.Blueprint.Application.UsesCases.KeyVault.Input;
using Lib.Architecture.BuildingBlocks;
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 BlobStorageController : ControllerBase
    {
        private readonly IComponentHandler uploadBlobHandler;
        private readonly IComponentHandler getBlobListHandler;
        private readonly IComponentHandler downloadBlobHandler;
        private readonly IComponentHandler deleteBlobHandler;
        private readonly IStoragePort port;
        /// 
        /// Handles all services and business rules related to .
        /// 
        public BlobStorageController(
            IComponentHandler uploadBlobHandler,
            IComponentHandler getBlobListHandler,
            IComponentHandler downloadBlobHandler,
            IComponentHandler deleteBlobHandler,
            IStoragePort port
            )
        {
            this.uploadBlobHandler = uploadBlobHandler;
            this.getBlobListHandler = getBlobListHandler;
            this.downloadBlobHandler = downloadBlobHandler;
            this.deleteBlobHandler = deleteBlobHandler;
            this.port = port;
        }
        /// 
        /// Uploads a new blob.
        /// 
        [HttpPost("UploadBlob")]
        [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)]
        public async Task UploadBlobAsync([FromBody] UploadBlobRequest newBlob, CancellationToken cancellationToken = default)
        {
            await uploadBlobHandler.ExecuteAsync(newBlob, cancellationToken).ConfigureAwait(false);
            return port.ViewModel;
        }
        /// 
        /// Gets all blobs into the container.
        /// 
        [HttpGet]
        [Route("GetBlobList")]
        [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)]
        public async Task GetBlobList([FromQuery] string? prefix, CancellationToken cancellationToken)
        {
            await getBlobListHandler.ExecuteAsync(new GetBlobListRequest { Prefix = prefix }, cancellationToken).ConfigureAwait(false);
            return port.ViewModel;
        }
        /// 
        /// Downloads a blob by name.
        /// 
        [HttpPost("DownloadBlob")]
        [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)]
        public async Task DownloadBlobAsync([FromBody] DownloadBlobRequest request, CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrEmpty(request.BlobName)) { return BadRequest("Invalid blob name"); }
            await downloadBlobHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
            return port.ViewModel;
        }
        /// 
        /// Deletes a blob by name.
        /// 
        [HttpDelete]
        [Route("DeleteBlob")]
        [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)]
        public async Task DeleteBlobAsync([FromBody] DeleteBlobRequest request,
                                                                     CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(request.BlobName)) { return BadRequest("Invalid blob name"); }
            await deleteBlobHandler.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
            return port.ViewModel;
        }
    }
}