namespace Books.E2E.Tests.Actions;

/// <summary>
/// BDD "Given" actions - setup and preconditions.
/// </summary>
public class GivenActions
{
    private readonly ActionContext _context;

    internal GivenActions(ActionContext context)
    {
        _context = context;
    }

    /// <summary>
    /// Performs real authentication through Keycloak OIDC login flow.
    /// Navigates to the app, gets redirected to Keycloak, logs in, and returns.
    /// </summary>
    public async Task<WhenActions> UserIsAuthenticated()
    {
        var config = _context.Configuration;

        Console.WriteLine($"[Given] Authenticating user {config.TestUserEmail} via Keycloak...");

        // Navigate to the frontend - this will redirect to Keycloak
        await _context.Page.GotoAsync(_context.FrontendBaseUrl);

        // Wait for Keycloak login page to load (look for the login form)
        var usernameField = _context.Page.Locator("#username, input[name='username'], input[name='email']");
        await usernameField.WaitForAsync(new() { Timeout = 15000 });

        // Fill in credentials
        await usernameField.FillAsync(config.TestUserEmail);

        var passwordField = _context.Page.Locator("#password, input[name='password']");
        await passwordField.FillAsync(config.TestUserPassword);

        // Click the login button
        var loginButton = _context.Page.Locator("#kc-login, button[type='submit'], input[type='submit']");
        await loginButton.ClickAsync();

        // Wait for redirect back to the app (wait for the frontend URL)
        await _context.Page.WaitForURLAsync(
            url => url.StartsWith(_context.FrontendBaseUrl),
            new() { Timeout = 15000 }
        );

        _context.IsAuthenticated = true;
        _context.UserId = config.TestUserEmail;

        Console.WriteLine($"[Given] User authenticated successfully as {config.TestUserEmail}");

        return new WhenActions(_context);
    }

    /// <summary>
    /// Ensures the user starts with no companies (clean slate).
    /// Note: This assumes the target environment has appropriate test data setup.
    /// </summary>
    public async Task<GivenActions> UserHasNoCompanies()
    {
        Console.WriteLine("[Given] User has no companies (assuming clean test environment)");
        await Task.CompletedTask;
        return this;
    }

    /// <summary>
    /// Chain to When actions after setup.
    /// </summary>
    public WhenActions When => new(_context);
}
