using IWS5.Api.OptionsSetup;
using IWS5.Core.DTO;
using IWS5.Core.Models;
using IWS5.Core.Models.Request;
using IWS5.Core.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;

namespace IWS5.Api.Controllers;
/// <summary>
/// Controller for handling notes.
/// </summary>
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class NoteController: ControllerBase
{
    private readonly INoteService _noteService;
    private readonly ILogger<NoteController> _logger;

    public NoteController(INoteService noteService, ILogger<NoteController> logger)
    {
        _noteService = noteService;
        _logger = logger;
    }
    /// <summary>
    /// Retrieves notes for a given work item reference ID.
    /// </summary>
    /// <param name="workItemReferenceId">The ID of the work item reference.</param>
    /// <returns>A list of Notes.</returns>
    /// <response code="200">Returns the list of all allowed Notes.</response>
    /// <response code="400">If the work item reference ID is invalid.</response>
    /// <response code="401">If the user is unauthorized.</response>
    /// <response code="409">If notes are locked for the user.</response>
    /// <response code="500">If there is an internal server error.</response>
    [HttpGet("{workItemReferenceId:int}")]
    [SwaggerOperation(Summary = "Retrieves folder fields for a given work item reference ID.")]
    [ProducesResponseType(typeof(Response<NoteListDTO>), 200)]
    [ProducesResponseType(400)]
    [ProducesResponseType(401)]
    [ProducesResponseType(409)]
    [ProducesResponseType(500)]
    public async Task<IActionResult> GetNotes([FromRoute] int workItemReferenceId)
    {
        try
        {
            var userName = JwtTokenHelper.GetUserName(HttpContext, _logger, out var actionResult);

            if (string.IsNullOrEmpty(userName))
            {
                return actionResult;
            }

            var response = await _noteService.GetNotes(new NotesRequest(userName, workItemReferenceId));
            return Ok(response);
        }
        catch (InvalidOperationException ex)
        {
            return Conflict(new { error = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An error occurred while retrieving notes for WorkItemReferenceId {WorkItemReferenceId}", workItemReferenceId);
            return BadRequest("An error occurred while deleting document.");
        }
    }

    /// <summary>
    /// Adds a note to a work item.
    /// </summary>
    /// <param name="noteRequest"></param>
    /// <returns>Note that was added</returns>
    /// <response code="200">If the note was succesfully added</response>
    /// <response code="400">If the request is invalid.</response>
    /// <response code="401">If the user is unauthorized.</response>
    /// <response code="403">If the user lacks necessary rights.</response>
    /// <response code="409">If the note addition is locked for user.</response>
    /// <response code="500">If there is an internal server error.</response>
    [HttpPost("add")]
    [SwaggerOperation(Summary = "Retrieves folder fields for a given work item reference ID.")]
    [ProducesResponseType(typeof(Response<NoteListItem>), 200)]
    [ProducesResponseType(400)]
    [ProducesResponseType(401)]
    [ProducesResponseType(403)]
    [ProducesResponseType(409)]
    [ProducesResponseType(500)]
    public async Task<IActionResult> AddNote([FromBody] CreateNoteRequestItem noteRequest)
    {
        try
        {
            var userName = JwtTokenHelper.GetUserName(HttpContext, _logger, out var actionResult);
            var response = await _noteService.AddNote(new CreateNoteRequest(userName, noteRequest));
            return Ok(response);
        }
        catch (InvalidOperationException ex)
        {
            return Conflict(new { error = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An error occurred while adding note for WorkItemReferenceId {WorkItemReferenceId}", noteRequest.WorkItemId);
            return BadRequest("An error occurred while adding note.");
        }
    }
}
