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 SpecificationController : ESuiteControllerBase
{
    private readonly ISpecificationManager _specificationManager;

    /// <summary>
    /// Constructor for Specification Controller
    /// </summary>
    /// <param name="specificationManager"></param>
    public SpecificationController(ISpecificationManager specificationManager)
    {
        _specificationManager = specificationManager;
    }

    /// <summary>
    /// Gets all specifications
    /// </summary>
    /// <returns>Collection of all FormTemplates</returns>
    [Route("specifications")]
    [HttpGet]
    [AccessKey(SecurityAccess.ViewSpecification)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public async Task<IActionResult> GetSpecifications(
        [FromQuery] Paging paging,
        CancellationToken cancellationToken = default!
    )
    {
        var result = await _specificationManager.GetSpecifications(paging, cancellationToken);
        return Ok(result);
    }

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

    /// <summary>
    /// Gets the form template for a given print specification
    /// </summary>
    /// <param name="generalIdRef">IdRef of specification glossary which has the form template saved as a custom value</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [Route("getTemplateForPrintSpec")]
    [HttpGet]
    [AccessKey(SecurityAccess.ViewTemplateForPrintSpec)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetTemplateForPrintSpec(
        [FromQuery] GeneralIdRef generalIdRef,
        CancellationToken cancellationToken = default!
    )
    {
        var site = await _specificationManager.GetTemplateForPrintSpec(generalIdRef, cancellationToken);
        return Ok(site);
    }

    /// <summary>
    /// Create a new Specification. Linking it to the associated form instance
    /// </summary>
    /// <param name="create"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [Route("specification")]
    [HttpPost]
    [AccessKey(SecurityAccess.AddSpecification)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> CreateSpecification([FromBody] CreateSpecification create, CancellationToken cancellationToken = default!)
    {
        await _specificationManager.CreateSpecification(AuditUserDetails, create, true, cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Edit a specification
    /// </summary>
    /// <param name="edit"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [Route("specification")]
    [HttpPut]
    [AccessKey(SecurityAccess.EditSpecification)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> EditSpecification([FromBody] EditSpecification edit, CancellationToken cancellationToken = default!)
    {
        await _specificationManager.EditSpecification(AuditUserDetails, edit, true, cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Delete a specification
    /// </summary>
    /// <param name="generalIdRef"></param>
    /// <param name="cancellationToken"></param>
    [Route("specification")]
    [HttpDelete]
    [AccessKey(SecurityAccess.DeleteSpecification)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> DeleteSpecification(
        [FromBody] GeneralIdRef generalIdRef,
        CancellationToken cancellationToken = default!
    )
    {
        await _specificationManager.DeleteSpecification(AuditUserDetails, generalIdRef, true, cancellationToken);
        return Ok();
    }
}