using AsbCloudApp.Data;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace AsbCloudWebApi.Controllers;

/// <summary>
/// контроллер по работе с faq-вопросами
/// </summary>
[Route("api/faq")]
[ApiController]
[Authorize]
public class FaqController : ControllerBase
{
    private readonly IFaqRepository faqRepository;

    public FaqController(IFaqRepository faqRepository)
    {
        this.faqRepository = faqRepository;
    }

    /// <summary>
    /// получение списка faq-вопросов
    /// </summary>
    /// <param name="request"></param>
    /// <param name="token"></param>
    /// <returns></returns>
    [HttpGet]
    [ProducesResponseType(typeof(IEnumerable<FaqDto>), (int)System.Net.HttpStatusCode.OK)]
    public async Task<IActionResult> GetFilteredAsync(
        [FromQuery] FaqRequest request,
        CancellationToken token)
    {
        var result = await faqRepository.GetFilteredAsync(request, token).ConfigureAwait(false);
        return Ok(result);
    }

    /// <summary>
    /// добавление нового вопроса
    /// </summary>
    /// <param name="faqDto">вопрос</param>
    /// <param name="token"></param>
    /// <returns></returns>
    [HttpPost]
    [ProducesResponseType(typeof(FaqDto), (int)System.Net.HttpStatusCode.OK)]
    public async Task<IActionResult> InsertAsync(
            [FromBody] FaqDto faqDto,
            CancellationToken token)
    {
        faqDto.IdAuthorQuestion = User.GetUserId()!.Value;

        var result = await faqRepository.InsertAsync(faqDto, token)
            .ConfigureAwait(false);

        return Ok(result);
    }

    [HttpPut]
    [Permission]
    [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
    public async Task<IActionResult> UpdateAsync([FromBody] FaqDto faqDto, CancellationToken token)
    {
        faqDto.IdAuthorAnswer = User.GetUserId()!.Value;

        var result = await faqRepository.UpdateAsync(faqDto, token)
            .ConfigureAwait(false);
        return Ok(result);
    }

    /// <summary>
    /// Объединение 2 вопросов в один
    /// </summary>
    /// <param name="sourceId1"></param>
    /// <param name="sourceId2"></param>        
    /// <param name="mergeQuestions">настройка, объединять ли текст 2-х вопросов в один или нет</param>
    /// <param name="token"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentInvalidException"></exception>
    [HttpPost("merge")]
    [Permission]
    [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
    public async Task<IActionResult> MergeAsync(
        [FromQuery] int sourceId1,
        [FromQuery] int sourceId2,
        [FromQuery] bool mergeQuestions,
        CancellationToken token)
    {
        var result = await faqRepository.MergeAsync(sourceId1, sourceId2, mergeQuestions, token)
            .ConfigureAwait(false);
        return Ok(result);
    }

    /// <summary>
    /// Помечает вопрос как удаленный
    /// </summary>
    /// <param name="id">id вопроса</param>
    /// <param name="token">Токен отмены задачи</param>
    /// <returns>Количество удаленных из БД строк</returns>
    [HttpPut("{id}")]
    [Permission]
    [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
    public async Task<IActionResult> MarkAsDeletedAsync(int id, CancellationToken token)
    {
        var result = await faqRepository.MarkAsDeletedAsync(id, token)
            .ConfigureAwait(false);

        return Ok(result);
    }

    /// <summary>
    /// Удаление вопроса
    /// </summary>
    /// <param name="id">id вопроса</param>
    /// <param name="token">Токен отмены задачи</param>
    /// <returns>Количество удаленных из БД строк</returns>
    [HttpDelete("{id}")]
    [Permission]
    [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
    public async Task<IActionResult> DeleteAsync(int id, CancellationToken token)
    {
        var result = await faqRepository.DeleteAsync(id, token)
            .ConfigureAwait(false);

        return Ok(result);
    }
}