using LightBDD.Framework;
using LightBDD.Framework.Scenarios;
using LightBDD.MsTest3;
using PlanTempus.X.Services;
using Shouldly;

namespace PlanTempus.X.BDD.FeatureFixtures;

[TestClass]
[FeatureDescription(@"As a system administrator
I want to ensure account security is maintained
So users' data remains protected")]
public partial class AccountSecuritySpecs : FeatureFixture
{
	IAccountService _accountService;
	IEmailService _emailService;
	IOrganizationService _organizationService;
	IAuthService _authService;

	protected Account _currentAccount;
	protected DateTime? _lockoutEnd;
	protected bool _isLocked;
	protected bool _loginSuccessful;

	public async Task Given_account_exists(string email)
	{
		_currentAccount = await _accountService.GetAccountByEmailAsync(email);
		if (_currentAccount == null)
		{
			_currentAccount = await _accountService.CreateAccountAsync(email, "TestPassword123!");
		}
	}

	public async Task When_I_attempt_5_failed_logins_within_5_minutes()
	{
		for (var i = 0; i < 5; i++)
		{
			try
			{
				await _authService.AttemptLoginAsync(_currentAccount.Email, "WrongPassword");
			}
			catch
			{
				// Expected exception with wrong password
			}
		}
	}

	public async Task Then_the_account_should_be_locked()
	{
		_currentAccount = _accountService.GetAccountByEmail(_currentAccount.Email);
		_isLocked = _currentAccount.IsLocked;
		_isLocked.ShouldBeTrue();

        await Task.CompletedTask;
    }

    public async Task And_lockout_end_should_be_set()
	{
		_lockoutEnd = _currentAccount.LockoutEnd;
		_lockoutEnd.ShouldNotBeNull();
		_lockoutEnd.Value.ShouldBeGreaterThan(DateTime.UtcNow);

        await Task.CompletedTask;
    }

    public async Task And_subsequent_login_attempts_should_fail_until_lockout_end()
	{
		try
		{
			_loginSuccessful = await _authService.AttemptLoginAsync(_currentAccount.Email, _currentAccount.Password);
		}
		catch
		{
			_loginSuccessful = false;
		}

		_loginSuccessful.ShouldBeFalse();
	}
}
