using System.Threading.Tasks;
using DiplomovaPrace.Contracts.Customer.LoginAccounts;
using DiplomovaPrace.Contracts.Customer.Security.InputModels;
using DiplomovaPrace.Facades.Customer.Account;
using DiplomovaPrace.Services.Security;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace DiplomovaPrace.Web.Server.Controllers
{
	[Route("api/account")]
	public class AccountController : ControllerBase
	{
		private readonly IAccountFacade accountFacade;
		private readonly ISecurityService securityService;

		public AccountController(IAccountFacade accountFacade, ISecurityService securityService)
		{
			this.accountFacade = accountFacade;
			this.securityService = securityService;
		}

		[AllowAnonymous]
		[HttpPost("authenticate")]
		public async Task<IActionResult> AuthenticateUserAsync([FromBody] LoginAccountIM inputModel)
		{
			string token = await securityService.AuthenticateUserAsync(inputModel).ConfigureAwait(false);

			if (token == null)
			{
				return BadRequest();
			}

			return Ok(token);
		}

		[HttpPost("changePassword")]
		[Authorize(Roles = "Uživatel")]
		public async Task<IActionResult> ChangePasswordAsync([FromBody] PasswordChangeIM inputModel)
		{
			inputModel.UserID = int.Parse(User.Identity.Name);

			if (await securityService.ChangeUserPasswordAsync(inputModel))
			{
				return Ok();
			}

			return BadRequest();
		}

		[HttpGet("getUserDetails")]
		[Authorize(Roles = "Uživatel")]
		public async Task<UserDetailsDto> GetUserDetailsAsync()
		{
			int userID = int.Parse(User.Identity.Name);

			return await accountFacade.GetUserDetailsAsync(userID);
		}

		[AllowAnonymous]
		[HttpPost("recoverPassword")]
		public async Task<IActionResult> RecoverPasswordAsync([FromBody] PasswordRecoveryIM inputModel)
		{
			await securityService.RecoverPasswordAsync(inputModel).ConfigureAwait(false);

			return Ok();
		}

		[AllowAnonymous]
		[HttpPost("validatePasswordResetToken")]
		public async Task<IActionResult> ValidatePasswordResetTokenAsync([FromBody] Contracts.Security.InputModels.PasswordResetTokenIM inputModel)
		{
			Contracts.Security.ViewModels.TokenValidationResult result = await securityService.ValidatePasswordResetTokenAsync(inputModel).ConfigureAwait(false);

			if (result.IsValid)
			{
				return Ok();
			}

			return BadRequest();
		}

		[AllowAnonymous]
		[HttpPost("resetPassword")]
		public async Task ResetPasswordAsync([FromBody] Contracts.Security.InputModels.PasswordResetIM inputModel)
		{
			await securityService.PasswordResetAsync(inputModel).ConfigureAwait(false);
		}

		[AllowAnonymous]
		[HttpPost("registerUser")]
		public async Task<IActionResult> RegisterUserAsync([FromBody] RegisterUserIM inputModel)
		{
			if (await securityService.RegisterUserAsync(inputModel))
			{
				return Ok();
			}

			return BadRequest();
		}

		[HttpGet("refreshJwt")]
		public async Task<IActionResult> RefreshJwtTokenAsync()
		{
			string token = await securityService.RefreshJwtTokenAsync(int.Parse(User.Identity.Name)).ConfigureAwait(false);

			if (token == null)
			{
				return Forbid();
			}

			return Ok(token);
		}

		[HttpPost("updateUserDetails")]
		[Authorize(Roles = "Uživatel")]
		public async Task<IActionResult> UpdateUserDetailsAsync([FromBody] UserDetailsDto inputModel)
		{
			//int userID = int.Parse(User.Identity.Name);

			if (int.TryParse(User.Identity.Name, out int userId) && await accountFacade.UpdateUserDetailsAsync(userId, inputModel))
			{
				return Ok();
			}

			return BadRequest();
		}
	}
}
