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;
    private readonly IHelpPageRepository helpPageRepository;

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

    /// <summary>
    /// Загрузка файла справки
    /// </summary>
    /// <param name="key">Ключ страницы</param>
    /// <param name="idCategory">Id категории файла. Допустимое значение параметра: 20000</param>
    /// <param name="file">Файл справки</param>
    /// <param name="cancellationToken">Токен для отмены задачи</param>
    /// <returns></returns>
    [HttpPost]
    [Permission]
    [ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
    public async Task<IActionResult> UploadAsync(
        [Required] string key,
        [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(key,
            idCategory,
            file.FileName,
            fileStream,
            cancellationToken);

        return Ok(helpPageId);
    }

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

        if (!file.HasValue)
            return NoContent();
        
        return File(file.Value.stream, "application/pdf", file.Value.fileName);
    }
}