using Books.E2E.Tests.Actions;
using Microsoft.Playwright;

namespace Books.E2E.Tests.Infrastructure;

/// <summary>
/// Base class for all E2E tests.
/// Provides access to Playwright Page and Actions builder.
/// Tests run against pre-configured URLs (localhost or remote).
/// </summary>
[Collection(E2ETestCollection.Name)]
[Trait("Category", "E2E")]
public abstract class E2ETestBase : IAsyncLifetime
{
    protected readonly E2ETestFixture Fixture;
    protected readonly PlaywrightFixture PlaywrightFixture;

    private IBrowserContext? _browserContext;
    private IPage? _page;

    protected IPage Page => _page ?? throw new InvalidOperationException("Page not initialized. Did InitializeAsync complete?");
    protected ActionsBuilder Actions { get; private set; } = null!;
    protected E2EConfiguration Config => Fixture.Configuration;

    protected E2ETestBase(
        E2ETestFixture fixture,
        PlaywrightFixture playwrightFixture)
    {
        Fixture = fixture;
        PlaywrightFixture = playwrightFixture;
    }

    public virtual async Task InitializeAsync()
    {
        // Create a fresh browser context for test isolation
        _browserContext = await PlaywrightFixture.CreateContextAsync();
        _page = await _browserContext.NewPageAsync();

        // Setup the actions builder with context
        var context = new ActionContext
        {
            Page = Page,
            BrowserContext = _browserContext,
            ApiClient = Fixture.ApiClient,
            BackendBaseUrl = Config.BackendUrl,
            FrontendBaseUrl = Config.FrontendUrl,
            Configuration = Config
        };

        Actions = new ActionsBuilder(context);

        Console.WriteLine($"[E2ETestBase] Test initialized - Backend: {Config.BackendUrl}, Frontend: {Config.FrontendUrl}");
    }

    public virtual async Task DisposeAsync()
    {
        if (_page != null)
        {
            await _page.CloseAsync();
        }

        if (_browserContext != null)
        {
            await _browserContext.CloseAsync();
        }
    }
}
