using AsbCloudApp.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Repositories;
using Microsoft.AspNetCore.Authorization;
using System.Net;

namespace AsbCloudWebApi.Controllers;

/// <summary>
/// Справки по страницам
/// </summary>
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class HelpPageController : ControllerBase
{
    private readonly IHelpPageService helpPageService;
    private readonly IUserRepository userRepository;

    public HelpPageController(IHelpPageService helpPageService,
        IUserRepository userRepository)
    {
        this.helpPageService = helpPageService;
        this.userRepository = userRepository;
    }

    /// <summary>
    /// Загрузка файла справки
    /// </summary>
    /// <param name="urlPage">Url страницы</param>
    /// <param name="idCategory">Id категории файла</param>
    /// <param name="file">Файл справки</param>
    /// <param name="cancellationToken">Токен для отмены задачи</param>
    /// <returns></returns>
    [HttpPost]
    [Permission]
    [ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
    public async Task<IActionResult> UploadAsync(
        string urlPage,
        [Range(minimum: 20000, maximum: 20000, ErrorMessage = "Категория файла недопустима. Допустимые: 20000")]
        int idCategory,
        [Required] IFormFile file,
        CancellationToken cancellationToken)
    {
        int? idUser = User.GetUserId();
        
        if(!idUser.HasValue)
            return Forbid();
        
        if (!userRepository.HasPermission(idUser.Value, $"HelpPage.edit"))
            return Forbid();

        using var fileStream = file.OpenReadStream();

        int helpPageId = await helpPageService.AddOrUpdateAsync(urlPage,
            idCategory,
            file.FileName,
            fileStream,
            cancellationToken);

        return Ok(helpPageId);
    }

    /// <summary>
    /// Получение файла справки
    /// </summary>
    /// <param name="urlPage">Url страницы</param>
    /// <param name="idCategory">Id категории файла</param>
    /// <param name="cancellationToken">Токен для отмены задачи</param>
    /// <returns></returns>
    [HttpGet]
    [Route("{urlPage}/{idCategory}")]
    [ProducesResponseType(typeof(PhysicalFileResult), (int)HttpStatusCode.OK)]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    public async Task<IActionResult> GetFileAsync(string urlPage, 
        int idCategory, 
        CancellationToken cancellationToken)
    {
        var file = await helpPageService.GetFileStreamAsync(urlPage,
            idCategory,
            cancellationToken);

        using var fileStream = file.stream;
        
        var memoryStream = new MemoryStream();
        await fileStream.CopyToAsync(memoryStream,
            cancellationToken);
        memoryStream.Position = 0;
        
        return File(memoryStream, "application/octet-stream", file.fileName);
    }
}