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