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));
	}
}