using e_suite.API.Common;
using e_suite.Utilities.Pagination;
using eSuite.API.security;
using eSuite.API.Utilities;
using eSuite.Core.Miscellaneous;
using eSuite.Core.Security;
using Microsoft.AspNetCore.Mvc;

namespace eSuite.API.Controllers;

/// <summary>
/// User manage is responsible for managing users within e-suite.
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class WorkflowTemplateController : ESuiteControllerBase
{
    private readonly IWorkflowTemplateManager _workflowTemplateManager;

    public WorkflowTemplateController(IWorkflowTemplateManager workflowTemplateManager)
    {
        _workflowTemplateManager = workflowTemplateManager;
    }
    
    /// <summary>
    /// Get a list of workflow templates
    /// </summary>
    /// <param name="paging"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    [Route("templates")]
    [AccessKey(SecurityAccess.ViewWorkflowTemplates)]
    [HttpGet]
    public async Task<IActionResult> GetWorkflowTemplates(
        [FromQuery] Paging paging,
        CancellationToken cancellationToken = default!
    )
    {
        var result = await _workflowTemplateManager.GetWorkflowTemplatesAsync(paging, cancellationToken);
        return Ok(result);
    }

    /// <summary>
    /// Use this to deactivate a template
    /// </summary>
    /// <param name="email"></param>
    /// <param name="cancellationToken"></param>
    [Route("template")]
    [HttpDelete]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ProblemDetails))]
    [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
    [AccessKey(SecurityAccess.DeleteWorkflowTemplate)]
    public async Task<IActionResult> DeleteWorkflowTemplate(
        [FromBody] GeneralIdRef templateId,
        CancellationToken cancellationToken = default!
    )
    {
        await _workflowTemplateManager.DeleteTemplate(AuditUserDetails, templateId, cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Get a list of workflow templates
    /// </summary>
    /// <param name="paging"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    [Route("templateVersions")]
    [AccessKey(SecurityAccess.ViewWorkflowTemplates)]
    [HttpGet]
    public async Task<IActionResult> GetWorkflowTemplateVersions(
        [FromQuery] Paging paging,
        CancellationToken cancellationToken = default!
    )
    {
        var result = await _workflowTemplateManager.GetWorkflowTemplateVersionsAsync(paging, cancellationToken);
        return Ok(result);
    }

    /// <summary>
    /// Get the details of specific template
    /// </summary>
    /// <param name="generalIdRef"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [Route("templateVersion")]
    [HttpGet]
    [AccessKey(SecurityAccess.ViewWorkflowTemplates)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetWorkflowTemplateVersion(
        [FromQuery] GeneralIdRef generalIdRef,
        CancellationToken cancellationToken = default!
    )
    {
        var result = await _workflowTemplateManager.GetWorkflowTemplateAsync(generalIdRef, cancellationToken);
        return Ok(result);
    }

    /// <summary>
    /// Edit a Workflow Template
    /// </summary>
    /// <param name="user"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [Route("templateVersion")]
    [HttpPut]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [AccessKey(SecurityAccess.EditWorkflowTemplate)]
    public async Task<IActionResult> EditTemplateVersion(
        GetWorkflowTemplateVersion template,
        CancellationToken cancellationToken = default!
    )
    {
        await _workflowTemplateManager.EditTemplateVersion(AuditUserDetails, template, cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Patching is useful when you only want to update a few fields of the user rather than the whole object.
    /// </summary>
    /// <param name="user"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [Route("templateVersion")]
    [HttpPatch]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [AccessKey(SecurityAccess.EditWorkflowTemplate)]
    public async Task<IActionResult> PatchWorkflowTemplateVersion(
        [FromQuery] IGeneralIdRef templateId,
        [FromBody] PatchWorkflowTemplateVersion patchTemplate,
        CancellationToken cancellationToken = default!
    )
    {
        await _workflowTemplateManager.PatchTemplateVersion(AuditUserDetails, templateId, patchTemplate,
            cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Create a new workflow template
    /// </summary>
    /// <remarks>Create a new user for e-suite.  The minimum information needed is the email address, which forms the account user name.  Once created the user will get an e-mail asking them to confirm the account.</remarks>
    /// <param name="userRegistration">Contains the details that need to be supplied to create the user.</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [Route("templateVersion")]
    [HttpPost]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
    [AccessKey(SecurityAccess.AddWorkflowTemplate)]
    public async Task<IActionResult> CreateWorkflowTemplateVersion(
        [FromBody] CreateWorkflowTemplateVersion template,
        CancellationToken cancellationToken = default!
    )
    {
        await _workflowTemplateManager.PostTemplateVersion(AuditUserDetails, template, cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Use this to deactivate a template
    /// </summary>
    /// <param name="email"></param>
    /// <param name="cancellationToken"></param>
    [Route("templateVersion")]
    [HttpDelete]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ProblemDetails))]
    [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
    [AccessKey(SecurityAccess.DeleteWorkflowTemplate)]
    public async Task<IActionResult> DeleteWorkflowTemplateVersion(
        [FromBody] GeneralIdRef templateId,
        CancellationToken cancellationToken = default!
    )
    {
        await _workflowTemplateManager.DeleteTemplateVersion(AuditUserDetails, templateId, cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Returns a list of Task Metadata
    /// </summary>
    /// <param name="cancellationToken"></param>
    [Route("taskMetadata")]
    [HttpGet]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ProblemDetails))]
    [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
    [AccessKey(SecurityAccess.Everyone)]
    public async Task<IActionResult> GetAllowedTaskMetadataList(
        [FromQuery] string? taskType,
        CancellationToken cancellationToken = default!
    )
    {
        var result = await _workflowTemplateManager.GetAllowedTaskMetadataList(taskType, cancellationToken);
        return Ok(result);
    }
}