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

namespace AsbCloudWebApi.Controllers;

/// <summary>
/// Контроллер настроек для пользователя
/// </summary>
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class UserSettingsController : ControllerBase
{
    private readonly IUserSettingsRepository service;

    public UserSettingsController(IUserSettingsRepository service)
    {
        this.service = service;
    }

    /// <summary>
    /// Получить настройки
    /// </summary>
    /// <param name="key"></param>
    /// <param name="token"></param>
    /// <returns></returns>
    [HttpGet("{key}")]
    [ProducesResponseType(typeof(object), (int)System.Net.HttpStatusCode.OK)]
    [Produces("application/json")]
    public virtual async Task<IActionResult> GetAsync(
        [StringLength(255, MinimumLength = 1, ErrorMessage = "The key value cannot less then 1 character and greater then 255. ")]
        string key, 
        CancellationToken token)
    {
        var userId = User.GetUserId();
        if (userId is null)
            return Forbid();

        var result = await service.GetOrDefaultAsync((int)userId, key, token).ConfigureAwait(false);
        var actionResult = new JsonResult(result);
        actionResult.ContentType = "application/json";
        return actionResult;
    }

    /// <summary>
    /// записать новые или обновить старые
    /// </summary>
    /// <param name="key"></param>
    /// <param name="value"></param>
    /// <param name="token"></param>
    /// <returns></returns>
    [HttpPut("{key}")]
    [ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
    public virtual async Task<ActionResult<int>> UpsertAsync(string key, [FromBody] System.Text.Json.JsonDocument value, CancellationToken token)
    {
        var userId = User.GetUserId();
        if (userId is null)
            return Forbid();

        var result = await service.UpsertAsync((int)userId, key, value, token).ConfigureAwait(false);
        if (result < 0)
            return this.ValidationBadRequest(nameof(key), "not found");

        return Ok(result);
    }

    /// <summary>
    /// Удалить настройки пользователя по ключу
    /// </summary>
    /// <param name="key"></param>
    /// <param name="token"></param>
    /// <returns></returns>
    [HttpDelete("{key}")]
    [ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
    public virtual async Task<ActionResult<int>> DeleteAsync(string key, CancellationToken token)
    {
        var userId = User.GetUserId();
        if (userId is null)
            return Forbid();

        var result = await service.DeleteAsync((int)userId, key, token).ConfigureAwait(false);
        if (result < 0)
            return this.ValidationBadRequest(nameof(key), "not found");

        return Ok(result);
    }

    /// <summary>
    /// Удалить ВСЕ настройки пользователя. Для админки.
    /// </summary>
    /// <param name="idUser"></param>
    /// <param name="token"></param>
    /// <returns></returns>
    [HttpDelete("/api/admin/user/{idUser}/settings")]
    [Permission]
    public virtual async Task<ActionResult<int>> DeleteAllAsync(int idUser, CancellationToken token)
    {
        var result = await service.DeleteAsync(idUser, token).ConfigureAwait(false);
        
        return Ok(result);
    }
}