using Microsoft.Playwright.NUnit;
using NUnit.Framework;

namespace Tests.Specs;

[Parallelizable(ParallelScope.Self)]
[FixtureLifeCycle(LifeCycle.SingleInstance)]
public class BuildCalculatorTests : PageTest
{
    private Website _website = null!;

    [SetUp]
    public void CreateWebsite()
    {
        _website = new Website(Page);
    }

    [Test]
    public async Task AddEntitiesViaKeyboardQWE()
    {
        var calc = _website.BuildCalculatorPage;
        await calc.GotoAsync();

        await calc.Filter.SelectFactionAsync("Q'Rath");
        await calc.Filter.SelectImmortalAsync("Orzum");

        await calc.Hotkeys.ClickKeyAsync("TAB");

        var keyMap = new Dictionary<string, string> { ["Q"] = "q", ["W"] = "w", ["E"] = "e", ["TAB"] = "Tab" };

        foreach (var key in new[] { "Q", "W", "E", "TAB" })
        {
            var entityNames = await calc.Hotkeys.GetEntityNamesOnKeyAsync(key);
            if (entityNames.Count == 0) continue;

            await Page.Keyboard.PressAsync(keyMap[key]);

            var viewName = await calc.EntityView.GetEntityNameAsync();
            Assert.That(viewName, Is.Not.Null.And.Not.Empty);
            Assert.That(entityNames, Does.Contain(viewName));
        }
    }

    [Test]
    public async Task AddEntitiesViaHotkeysClickTABQWE()
    {
        var calc = _website.BuildCalculatorPage;
        await calc.GotoAsync();

        await calc.Filter.SelectFactionAsync("Q'Rath");
        await calc.Filter.SelectImmortalAsync("Orzum");

        foreach (var key in new[] { "TAB", "Q", "W", "E" })
        {
            var entityNames = await calc.Hotkeys.GetEntityNamesOnKeyAsync(key);
            if (entityNames.Count == 0) continue;

            await calc.Hotkeys.ClickKeyAsync(key);

            var viewName = await calc.EntityView.GetEntityNameAsync();
            Assert.That(viewName, Is.Not.Null.And.Not.Empty);
            Assert.That(entityNames, Does.Contain(viewName));
        }
    }

    [Test]
    public async Task AddAcropolisViaQVerifyEntityViewAndTimelineThenClear()
    {
        var calc = _website.BuildCalculatorPage;
        await calc.GotoAsync();

        await calc.Filter.SelectFactionAsync("Q'Rath");
        await calc.Filter.SelectImmortalAsync("Orzum");

        Assert.That(await calc.Timeline.ContainsEntityAsync("Acropolis"), Is.False);

        await calc.Hotkeys.ClickKeyAsync("Q");

        Assert.That(await calc.EntityView.GetEntityNameAsync(), Is.EqualTo("Acropolis"));
        Assert.That(await calc.Timeline.ContainsEntityAsync("Acropolis"), Is.True);

        await calc.ClickClearBuildOrderAsync();
        await Task.Delay(1000);

        Assert.That(await calc.Timeline.ContainsEntityAsync("Acropolis"), Is.False);
        Assert.That(await calc.EntityView.GetEntityNameAsync(), Is.Null);
    }

    [Test]
    public async Task MissingRequirementsToastWhenBuildingSoulFoundryWithoutLegionHall()
    {
        var calc = _website.BuildCalculatorPage;
        await calc.GotoAsync();

        await calc.Filter.SelectFactionAsync("Q'Rath");
        await calc.Filter.SelectImmortalAsync("Orzum");

        await calc.Hotkeys.ClickKeyAsync("E");
        var hasToast = await calc.Toast.HasToastContainingAsync("Missing Requirements");
        Assert.That(hasToast, Is.True);
    }

    [Test]
    public async Task NotEnoughEtherToastWhenBuildingSoulFoundryAfterLegionHall()
    {
        var calc = _website.BuildCalculatorPage;
        await calc.GotoAsync();

        await calc.Filter.SelectFactionAsync("Q'Rath");
        await calc.Filter.SelectImmortalAsync("Orzum");

        await calc.Hotkeys.ClickKeyAsync("W");
        await calc.Hotkeys.ClickKeyAsync("E");

        var hasToast = await calc.Toast.HasToastContainingAsync("Not Enough Ether");
        Assert.That(hasToast, Is.True);
    }
}