using Insight.Domain.Models;
using Insight.Infrastructure.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Insight.Api.Controllers
{
    [ApiController, Route("api/token", Order = 0)]
    public class TokenController : ControllerBase
    {
        private readonly TokenService _tokenService;

        public TokenController(TokenService tokenService)
        {
            _tokenService = tokenService;
        }

        /// <remarks>
        /// Access Token Request
        /// </remarks>
        [HttpPost, AllowAnonymous]
        public async Task<IActionResult> Authentication([FromBody] TokenRequest request)
        {
            try
            {
                var result = await _tokenService.GetAsync(request.Username, request.Password, request.Code, HttpContext.Connection.RemoteIpAddress).ConfigureAwait(false);
                return Ok(result);
            }
            catch (UnauthorizedAccessException ex)
            {
                return Unauthorized(ex.Message);
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

        /// <remarks>
        /// Refresh Token Request
        /// </remarks>
        [HttpPost("refresh"), AllowAnonymous]
        public async Task<IActionResult> Refresh([FromBody] TokenRefreshRequest request)
        {
            if (string.IsNullOrWhiteSpace(request.Token)) return BadRequest("Refresh Token Required");

            try
            {
                var result = await _tokenService.RefreshAsync(request.Token, HttpContext.Connection.RemoteIpAddress).ConfigureAwait(false);
                return Ok(result);
            }
            catch (UnauthorizedAccessException ex)
            {
                return Unauthorized(ex.Message);
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

        /// <remarks>
        /// Revoke Token Request
        /// </remarks>
        [HttpPost("revoke"), AllowAnonymous]
        public async Task<IActionResult> Revoke([FromBody] TokenRevokeRequest request)
        {
            if (string.IsNullOrWhiteSpace(request.Token)) return BadRequest("Refresh Token Required");

            try
            {
                await _tokenService.RevokeAsync(request.Token, request.Reason ?? "revoked by user", HttpContext.Connection.RemoteIpAddress).ConfigureAwait(false);
                return Ok();
            }
            catch (UnauthorizedAccessException ex)
            {
                return Unauthorized(ex.Message);
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }
    }
}