using e_suite.API.Common;
using e_suite.API.Common.models;
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>
/// forms manager is responsible for managing custom forms within e-suite.
/// </summary>
[Route("api/[controller]")]
public class FormsController : ESuiteControllerBase
{
    private readonly IFormsManager _formsManager;

    /// <summary>
    /// Constructor for the FormsController
    /// Constructor for the FormsController
    /// </summary>
    /// <param name="formsManager"></param>
    public FormsController(IFormsManager formsManager)
    {
        _formsManager = formsManager;
    }

    /// <summary>
    /// Gets all FormTemplates with latest version
    /// </summary>
    /// <returns>Collection of all FormTemplates</returns>
    [Route("forms")]
    [HttpGet]
    [AccessKey(SecurityAccess.ViewFormTemplate)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public async Task<IActionResult> GetFormTemplates(
        [FromQuery] Paging paging,
        CancellationToken cancellationToken = default!
    )
    {
        var result = await _formsManager.GetFormTemplatesAsync(paging, cancellationToken);
        return Ok(result);
    }

    /// <summary>
    /// Get FormTemplate by supplying GeneralIdRef
    /// </summary>
    /// <param name="generalIdRef"></param>
    /// <param name="cancellationToken"></param>
    /// <returns>Returns the FormTemplate with the corresponding Id </returns>
    [Route("form")]
    [HttpGet]
    [AccessKey(SecurityAccess.ViewFormTemplate)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetFormTemplate(
        [FromQuery] GeneralIdRef generalIdRef,
        CancellationToken cancellationToken = default!
    )
    {
        var form = await _formsManager.GetFormTemplateAsync(generalIdRef, cancellationToken);
        return Ok(form);
    }

    /// <summary>
    /// Create FormTemplate 
    /// </summary>
    /// <param name="createFormTemplate"></param>
    /// <param name="cancellationToken"></param>
    [Route("form")]
    [HttpPost]
    [AccessKey(SecurityAccess.AddFormTemplate)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> CreateFormTemplate([FromBody] CreateFormTemplate createFormTemplate, CancellationToken cancellationToken = default!)
    {
        await _formsManager.CreateFormTemplateAsync(AuditUserDetails, createFormTemplate, cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Edit FormTemplate
    /// </summary>
    /// <param name="editFormTemplate"></param>
    /// <param name="cancellationToken"></param>
    [Route("form")]
    [HttpPut]
    [AccessKey(SecurityAccess.EditFormTemplate)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> EditFormTempalate([FromBody] EditFormTemplate editFormTemplate, CancellationToken cancellationToken = default!)
    {
        await _formsManager.EditFormTemplateAsync(AuditUserDetails, editFormTemplate, cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Delete a formTemplate with all of its versions by providing GeneralIdRef of the FormTemplate 
    /// </summary>
    /// <param name="generalIdRef"></param>
    /// <param name="cancellationToken"></param>
    [Route("form")]
    [HttpDelete]
    [AccessKey(SecurityAccess.DeleteFormTemplate)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> DeleteForm(
        [FromBody] GeneralIdRef generalIdRef,
        CancellationToken cancellationToken = default!
    )
    {
        await _formsManager.DeleteFormTemplateAsync(AuditUserDetails, generalIdRef, cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Get FormTemplate by supplying GeneralIdRef
    /// </summary>
    /// <param name="generalIdRef"></param>
    /// <param name="cancellationToken"></param>
    /// <returns>Returns the FormTemplate with the corresponding Id </returns>
    [Route("formInstance")]
    [HttpGet]
    [AccessKey(SecurityAccess.ViewFormInstance)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetFormInstance(
        [FromQuery] GeneralIdRef generalIdRef,
        CancellationToken cancellationToken = default!
    )
    {
        var form = await _formsManager.GetFormInstanceAsync(generalIdRef, cancellationToken);
        return Ok(form);
    }

    /// <summary>
    /// Create an instance of a form based on a given version of a template
    /// </summary>
    /// <param name="createFormInstance"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [Route("formInstance")]
    [HttpPost]
    [AccessKey(SecurityAccess.AddFormInstance)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> CreateFormInstance(
        [FromBody] CreateFormInstance createFormInstance,
        CancellationToken cancellationToken = default!
    )
    {
        var formInstanceGeneralIdRef =
            await _formsManager.CreateFormInstanceAsync(AuditUserDetails, createFormInstance, cancellationToken);
        return Ok(formInstanceGeneralIdRef);
    }

    /// <summary>
    /// Edit a Form Instance
    /// </summary>
    /// <param name="editFormInstance"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [Route("formInstance")]
    [HttpPut]
    [AccessKey(SecurityAccess.EditFormInstance)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> EditFormInstance(
        [FromBody] EditFormInstance editFormInstance,
        CancellationToken cancellationToken = default!
    )
    {
        await _formsManager.EditFormInstanceAsync(AuditUserDetails, editFormInstance, cancellationToken);
        return Ok();
    }
}
