using IWS5.Api.Helpers;
using IWS5.Api.OptionsSetup;
using IWS5.Core.DTO;
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 managing folder fields.
/// </summary>
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class FolderFieldController(IFolderFieldService folderFieldService, ILogger<FolderFieldController> logger)
    : ControllerBase
{
    /// <summary>
    /// Retrieves folder fields for a given work item reference ID.
    /// </summary>
    /// <param name="workItemReferenceId">The ID of the work item reference.</param>
    /// <returns>A list of folder fields.</returns>
    /// <response code="200">Returns the list of folder fields.</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 folder fields information is locked for the user.</response>
    /// <response code="500">If there is an internal server error.</response>
    [HttpGet]
    [SwaggerOperation(Summary = "Retrieves folder fields for a given work item reference ID.")]
    [ProducesResponseType(typeof(FolderFieldListDTO), 200)]
    [ProducesResponseType(400)]
    [ProducesResponseType(401)]
    [ProducesResponseType(409)]
    [ProducesResponseType(500)]
    public async Task<IActionResult> GetFolderFieldsByWorkItemReference([FromQuery] int workItemReferenceId)
    {
        logger.LogInformation(
            "Received request to retrieve folder fields for workItemReferenceId {WorkItemReferenceId}",
            workItemReferenceId);

        var userName = JwtTokenHelper.GetUserName(HttpContext, logger, out var actionResult);

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

        logger.LogInformation("User {UserName} is attempting to retrieve folder fields for workItemReferenceId {WorkItemReferenceId}",
            userName, workItemReferenceId);
        
        var result = await folderFieldService.ListFolderFieldItems(new FolderFieldRequest(userName, workItemReferenceId));
        logger.LogInformation(
            "Successfully retrieved folder fields for user {UserName} and workItemReferenceId {WorkItemReferenceId}",
            userName, workItemReferenceId);
        
        var response = ResponseMapper<FolderFieldListDTO>.MapServiceResponse(result);
        return response;
    }

    /// <summary>
    /// Retrieves folder fields for a given process ID.
    /// </summary>
    /// <param name="processId">The ID of the process.</param>
    /// <returns>A list of folder fields.</returns>
    /// <response code="200">Returns the list of folder fields.</response>
    /// <response code="400">If the process ID is invalid.</response>
    /// <response code="401">If the user is unauthorized.</response>
    /// <response code="500">If there is an internal server error.</response>
    [SwaggerOperation(Summary = "Retrieves folder fields for a given process ID.")]
    [ProducesResponseType(typeof(List<FolderFieldItem>), 200)]
    [ProducesResponseType(400)]
    [ProducesResponseType(401)]
    [ProducesResponseType(500)]
    [HttpGet("process/{processId}")]
    public async Task<IActionResult> GetFolderFieldsByProcess([FromRoute] int processId)
    {
        logger.LogInformation(
            "Received request to retrieve folder fields for process {processId}",
            processId);

        var userName = JwtTokenHelper.GetUserName(HttpContext, logger, out var actionResult);

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

        var result = await folderFieldService.ListFolderFieldItems(new FolderFieldsByProcessIdRequest(userName, processId));
        var response = ResponseMapper<List<FolderFieldItem>>.MapServiceResponse(result);
        return response;
    }

    /// <summary>
    /// Updates list of values of a field instance.
    /// </summary>
    /// <param name="request">The request containing the field instance ID, instance type, and new value for each field updated and workItemId for workItem that was changed.</param>
    /// <returns>An IActionResult indicating the result of the operation.</returns>
    /// <response code="200">If the field instance values was successfully updated.</response>
    /// <response code="400">If the request is invalid.</response>
    /// <response code="401">If the user is unauthorized.</response>
    /// <response code="409">If folder fields editing is locked for the user.</response>
    /// <response code="500">If there is an internal server error.</response>
    [HttpPut("update-values")]
    [SwaggerOperation(Summary = "Updates list of values of a field instance.")]
    [ProducesResponseType(200)]
    [ProducesResponseType(400)]
    [ProducesResponseType(401)]
    [ProducesResponseType(409)]
    [ProducesResponseType(500)]
    public async Task<IActionResult> UpdateFieldListOfValues([FromBody] UpdateFieldListOfValuesRequest request)
    {
        var userName = JwtTokenHelper.GetUserName(HttpContext, logger, out var actionResult);

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

        var result = await folderFieldService.UpdateFieldListOfValues(userName, request);
        var response = ResponseMapper<String>.MapServiceResponse(result);
        return response;
    }
}