using System;
using System.Threading.Tasks;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using MyHN.Application;

namespace Api.Controllers
{
  [ApiController]
  [Route("api/comments")]
  public class CommentsController : ControllerBase
  {
    private readonly IMediator _bus;

    public CommentsController(IMediator bus)
    {
      _bus = bus;
    }

    /// <summary>
    /// Permet de poster un commentaire sur un lien.
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    [HttpPost]
    [Authorize]
    [ProducesResponseType(StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> CreateComment(CommentLinkCommand command)
    {
      var commentId = await _bus.Send(command);
      return Created($"comments/{commentId}", null);
    }

    /// <summary>
    /// Permet d'upvoter un commentaire.
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpPut("{id:guid}/upvote")]
    [Authorize]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> Upvote(Guid id)
    {
      await _bus.Send(new VoteForCommentCommand
      {
        CommentId = id,
        Direction = MyHN.Domain.VoteType.Up,
      });
      return NoContent();
    }

    /// <summary>
    /// Permet de downvoter un commentaire.
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpPut("{id:guid}/downvote")]
    [Authorize]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> Downvote(Guid id)
    {
      await _bus.Send(new VoteForCommentCommand
      {
        CommentId = id,
        Direction = MyHN.Domain.VoteType.Down,
      });
      return NoContent();
    }

    [HttpGet("me")]
    public IActionResult Me()
    {
      return Ok(new
      {
        UserId = User.Identity.Name,
        Authenticated = User.Identity.IsAuthenticated
      });
    }
  }
}