using e_suite.API.Common;
using e_suite.API.Common.models;
using eSuite.API.security;
using eSuite.API.SingleSignOn;
using eSuite.API.Utilities;
using eSuite.Core.Security;
using Microsoft.AspNetCore.Mvc;
using Moq;

namespace eSuite.API.Controllers;

/// <summary>
/// This part of the API is responsible for allowing a user to edit their own profile
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class ProfileController : ESuiteControllerBase
{
    private readonly IUserManager _userManager;
    private readonly ICookieManager _cookieManager;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="userManager"></param>
    public ProfileController(IUserManager userManager, ICookieManager cookieManager)
    {
        _userManager = userManager;
        _cookieManager = cookieManager;
    }

    /// <summary>
    /// Returns the general details of your profile
    /// </summary>
    /// <remarks>This returns all the general information for your profile, e-mail, twofactor authentication key (used for setting up TFA), when your name and when the account was created.</remarks>
    /// <returns></returns>
    [Route("myProfile")]
    [HttpGet]
    [AccessKey(SecurityAccess.Everyone)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetMyProfile(CancellationToken cancellationToken = default!)
    {
        var profile = await _userManager.GetProfile(User.Email(), cancellationToken);
        return Ok(profile);
    }

    /// <summary>
    /// Use this method to update your own profile.
    /// </summary>
    /// <param name="userProfile"></param>
    /// <param name="cancellationToken"></param>
    [Route("myProfile")]
    [HttpPut]
    [AccessKey(SecurityAccess.Everyone)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ProblemDetails))]
    [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
    public async Task<IActionResult> EditMyProfile(
        [FromBody] UpdatedUserProfile userProfile,
        CancellationToken cancellationToken = default!
    )
    {
        await _userManager.UpdateProfile(AuditUserDetails, User.Email(), userProfile, 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="patch"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [Route("myProfile")]
    [HttpPatch]
    [AccessKey(SecurityAccess.Everyone)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> PatchMyProfile(
        [FromBody] PatchUserProfile patchUserProfile,
        CancellationToken cancellationToken = default!
    )
    {
        var loginResponse = await _userManager.PatchProfile(AuditUserDetails, User.Email(), patchUserProfile, cancellationToken);
        
        await _cookieManager.CreateSessionCookie(Response, loginResponse);
        return Ok();
    }
}