using System.ComponentModel.DataAnnotations;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace AsbCloudWebApi.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class ManualController : ControllerBase
{
   private readonly IManualCatalogService manualCatalogService;

   public ManualController(IManualCatalogService manualCatalogService)
   {
      this.manualCatalogService = manualCatalogService;
   }

   /// <summary>
   /// Сохранение файла
   /// </summary>
   /// <param name="idDirectory">Id директории</param>
   /// <param name="file">Загружаемый файл</param>
   /// <param name="cancellationToken"></param>
   /// <returns></returns>
   [HttpPost]
   [Permission]
   [ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
   [ProducesResponseType(StatusCodes.Status400BadRequest)]
   [ProducesResponseType(StatusCodes.Status403Forbidden)]
   public async Task<IActionResult> SaveFileAsync(int idDirectory,
      [Required] IFormFile file,
      CancellationToken cancellationToken)
   {
      var idUser = User.GetUserId();
      
      if(!idUser.HasValue)
         throw new ForbidException("Не удается вас опознать");
      
      using var fileStream = file.OpenReadStream();

      var id = await manualCatalogService.SaveFileAsync(idDirectory, idUser.Value, file.FileName, fileStream, cancellationToken);

      return Ok(id);
   }

   /// <summary>
   /// Получение файла
   /// </summary>
   /// <param name="id">Id инструкции</param>
   /// <param name="cancellationToken"></param>
   /// <returns></returns>
   [HttpGet("{id:int}")]
   [Permission]
   [ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")]
   [ProducesResponseType(StatusCodes.Status204NoContent)]
   [ProducesResponseType(StatusCodes.Status403Forbidden)]
   public async Task<IActionResult> GetFileAsync(int id, CancellationToken cancellationToken)
   {
      var file = await manualCatalogService.GetFileAsync(id, cancellationToken);

      if (!file.HasValue)
         return NoContent();

      return File(file.Value.stream, "application/octet-stream", file.Value.fileName);
   }

   /// <summary>
   /// Удаление файла
   /// </summary>
   /// <param name="id">Id инструкции</param>
   /// <param name="cancellationToken"></param>
   /// <returns></returns>
   [HttpDelete]
   [Permission]
   [ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
   [ProducesResponseType(StatusCodes.Status403Forbidden)]
   public async Task<IActionResult> DeleteFileAsync(int id, CancellationToken cancellationToken)
   {
      return Ok(await manualCatalogService.DeleteFileAsync(id, cancellationToken));
   }
}