using LightBDD.Framework;
using LightBDD.Framework.Scenarios;
using PlanTempus.Components.Accounts.Create;
using PlanTempus.Components.Accounts.Exceptions;
using PlanTempus.Core.CommandQueries;
using Shouldly;

namespace PlanTempus.X.BDD.FeatureFixtures;

[TestClass]
[FeatureDescription(@"As a new user
I want to register with my email
So I can start using the system")]
public partial class AccountRegistrationSpecs : BddTestFixture
{
    protected CommandResponse _commandResponse;
    protected string _currentEmail;
    protected Exception _registrationError;

    public async Task Given_a_unique_email_address()
    {
        // Generate a unique email to ensure no account exists
        _currentEmail = $"{GetRandomWord()}_{Guid.NewGuid():N}@test.example.com";
        await Task.CompletedTask;
    }

    public async Task When_I_submit_registration_with_valid_credentials()
    {
        try
        {
            var command = new CreateAccountCommand
            {
                Email = _currentEmail,
                Password = "TestPassword123!",
                IsActive = true,
                CorrelationId = Guid.NewGuid()
            };

            _commandResponse = await CommandHandler.Handle(command);
        }
        catch (Exception ex)
        {
            _registrationError = ex;
        }
    }

    public async Task When_I_submit_registration_with_email(string email, string password)
    {
        try
        {
            var command = new CreateAccountCommand
            {
                Email = email,
                Password = password,
                IsActive = true,
                CorrelationId = Guid.NewGuid()
            };

            _commandResponse = await CommandHandler.Handle(command);
            _currentEmail = email;
        }
        catch (Exception ex)
        {
            _registrationError = ex;
        }
    }

    public async Task Then_the_account_should_be_created_successfully()
    {
        _registrationError.ShouldBeNull();
        _commandResponse.ShouldNotBeNull();
        _commandResponse.RequestId.ShouldNotBe(Guid.Empty);
        _commandResponse.CommandName.ShouldBe(nameof(CreateAccountCommand));

        await Task.CompletedTask;
    }

    public async Task Given_an_account_already_exists_with_email(string email)
    {
        // Create an account first to ensure it exists
        var command = new CreateAccountCommand
        {
            Email = email,
            Password = "ExistingPassword123!",
            IsActive = true,
            CorrelationId = Guid.NewGuid()
        };

        await CommandHandler.Handle(command);
        _currentEmail = email;
    }

    public async Task When_I_try_to_register_with_the_same_email()
    {
        try
        {
            var command = new CreateAccountCommand
            {
                Email = _currentEmail,
                Password = "AnotherPassword123!",
                IsActive = true,
                CorrelationId = Guid.NewGuid()
            };

            _commandResponse = await CommandHandler.Handle(command);
        }
        catch (Exception ex)
        {
            _registrationError = ex;
        }
    }

    public async Task Then_registration_should_fail_with_duplicate_email_error()
    {
        _registrationError.ShouldNotBeNull();
        _registrationError.ShouldBeOfType<EmailAlreadyRegistreredException>();

        await Task.CompletedTask;
    }
}
