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>
/// Methods for interacting with Domains
/// </summary>
[Route("api/[controller]")]
public class DomainController : ESuiteControllerBase
{
    private readonly IDomainManager _domainManager;

    /// <summary>
    /// Constructor for the Domain Controller
    /// </summary>
    /// <param name="domainManager"></param>
    public DomainController(IDomainManager domainManager)
    {
        _domainManager = domainManager;
    }

    /// <summary>
    /// Get list of all domains
    /// </summary>
    /// <param name="paging"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [Route("domains")]
    [HttpGet]
    [AccessKey(SecurityAccess.ViewDomain)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public async Task<IActionResult> GetDomains(
        [FromQuery] Paging paging,
        CancellationToken cancellationToken = default!
    )
    {
        var result = await _domainManager.GetDomainsAsync(paging, cancellationToken);
        return Ok(result);
    }

    /// <summary>
    /// Get details of domain
    /// </summary>
    /// <param name="generalIdRef"></param>
    /// <param name="cancellationToken"></param>
    /// <returns>Returns the FormTemplate with the corresponding Id </returns>
    [Route("domain")]
    [HttpGet]
    [AccessKey(SecurityAccess.ViewDomain)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetDomain(
        [FromQuery] GeneralIdRef generalIdRef,
        CancellationToken cancellationToken = default!
    )
    {
        var form = await _domainManager.GetDomainAsync(generalIdRef, cancellationToken);
        return Ok(form);
    }

    /// <summary>
    /// Create Domain
    /// </summary>
    /// <param name="createDomain"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [Route("domain")]
    [HttpPost]
    [AccessKey(SecurityAccess.AddDomain)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> CreateDomain(
        [FromBody] CreateDomain createDomain,
        CancellationToken cancellationToken = default!
    )
    {
        await _domainManager.CreateDomainAsync(AuditUserDetails, createDomain, cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Edit domain
    /// </summary>
    /// <param name="editFormTemplate"></param>
    /// <param name="cancellationToken"></param>
    [Route("domain")]
    [HttpPut]
    [AccessKey(SecurityAccess.EditDomain)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> EditDomain(
        [FromBody] EditDomain editFormTemplate,
        CancellationToken cancellationToken = default!
    )
    {
        await _domainManager.EditDomainAsync(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("domain")]
    [HttpDelete]
    [AccessKey(SecurityAccess.DeleteDomain)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> DeleteDomain(
        [FromBody] GeneralIdRef generalIdRef,
        CancellationToken cancellationToken = default!
    )
    {
        await _domainManager.DeleteDomainAsync(AuditUserDetails, generalIdRef, cancellationToken);
        return Ok();
    }
}