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>
/// This part of the API is responsible for allowing a user to interact with organisations.
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class OrganisationsController : ESuiteControllerBase
{
    private readonly IOrganisationsManager _organisationsManager;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="organisationsManager"></param>
    public OrganisationsController(IOrganisationsManager organisationsManager)
    {
        _organisationsManager = organisationsManager;
    }
    
    /// <summary>
    /// Returns a list of all the organisations in the system
    /// </summary>
    /// <remarks>This returns all the organisations in the system that are not soft deleted.</remarks>
    [Route("organisations")]
    [HttpGet]
    [AccessKey(SecurityAccess.ViewOrganisation)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public async Task<IActionResult> GetOrganisationsList([FromQuery] Paging paging, CancellationToken cancellationToken = default!)
    {
        var organisations = await _organisationsManager.GetOrganisationList(paging, cancellationToken);
        return Ok(organisations);
    }

    /// <summary>
    /// Reads an organisation
    /// </summary>
    /// <remarks>This willreturn the organisation with the specified id.</remarks>
    /// <param name="generalIdRef">Either the id or the Guid of the organisation</param>
    /// <param name="cancellationToken"></param>
    [Route("organisation")]
    [HttpGet]
    [AccessKey(SecurityAccess.ViewOrganisation)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetOrganisation(
        [FromQuery] GeneralIdRef generalIdRef,
        CancellationToken cancellationToken = default!
    )
    {
        var organisation = await _organisationsManager.GetOrganisation(generalIdRef, cancellationToken);
        return Ok(organisation);
    }

    /// <summary>
    /// Create a organisation
    /// </summary>
    /// <param name="createOrganisationDto">Contains the data required to create a organisation</param>
    /// <param name="cancellationToken"></param>
    [Route("organisation")]
    [HttpPost]
    [AccessKey(SecurityAccess.AddOrganisation)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> CreateOrganisation(
        [FromBody] CreateOrganisation createOrganisationDto,
        CancellationToken cancellationToken = default!
    )
    {
        await _organisationsManager.AddOrganisation(AuditUserDetails, createOrganisationDto, true, cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Edit a organisation
    /// </summary>
    /// <remarks>All the fields can be edited except the Id and Guid field</remarks>
    /// <param name="editOrganisationDto">Contains the details of the updated organisation</param>
    /// <param name="cancellationToken"></param>
    [Route("organisation")]
    [HttpPut]
    [AccessKey(SecurityAccess.EditOrganisation)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> EditOrganisation(EditOrganisation editOrganisationDto, CancellationToken cancellationToken = default!)
    {
        await _organisationsManager.EditOrganisation(AuditUserDetails, editOrganisationDto, true, cancellationToken);
        return Ok();
    }

    /// <summary>
    /// Deletes an organisation
    /// </summary>
    /// <remarks>This will perform a soft delete action. The organisation is not actually deleted.</remarks>
    /// <param name="generalIdRef">Either the id or the Guid of the organisation</param>
    /// <param name="cancellationToken"></param>
    [Route("organisation")]
    [HttpDelete]
    [AccessKey(SecurityAccess.DeleteOrganisation)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> DeleteOrganisation(
        GeneralIdRef generalIdRef,
        CancellationToken cancellationToken = default!
    )
    {
        await _organisationsManager.DeleteOrganisation(AuditUserDetails, generalIdRef, true, cancellationToken);
        return Ok();
    }
}