using Dalamud.Bindings.ImGui;
using Dalamud.Plugin.SelfTest;
using HellionChat.Themes;

namespace HellionChat.SelfTests;

// Validates the runtime theme-switch contract: polls ThemeRegistry.Active
// per frame until the slug moves away and back, then sanity-checks that
// the ABGR cache was recomputed on switch.
internal sealed class ThemeSwitchSelfTestStep : ISelfTestStep
{
    private readonly Plugin plugin;
    private string? initialSlug;
    private bool switchedAway;

    public ThemeSwitchSelfTestStep(Plugin plugin)
    {
        this.plugin = plugin;
    }

    public string Name => "Hellion Chat - Theme switch";

    public SelfTestStepResult RunStep()
    {
        var registry = this.plugin.ThemeRegistry;
        if (registry is null)
            return SelfTestStepResult.Fail;

        var active = registry.Active;
        if (active is null)
            return SelfTestStepResult.Fail;

        if (!HasPopulatedCache(active))
            return SelfTestStepResult.Fail;

        if (this.initialSlug is null)
        {
            this.initialSlug = active.Slug;
            ImGui.Text(
                $"Initial theme: \"{this.initialSlug}\". Open Settings -> Theme & Layout and pick a different theme."
            );
            return SelfTestStepResult.Waiting;
        }

        if (!this.switchedAway)
        {
            if (!string.Equals(active.Slug, this.initialSlug, StringComparison.OrdinalIgnoreCase))
            {
                this.switchedAway = true;
                return SelfTestStepResult.Waiting;
            }

            ImGui.Text($"Switch the active theme away from \"{this.initialSlug}\".");
            return SelfTestStepResult.Waiting;
        }

        if (!string.Equals(active.Slug, this.initialSlug, StringComparison.OrdinalIgnoreCase))
        {
            ImGui.Text($"Switch back to \"{this.initialSlug}\" to finish the test.");
            return SelfTestStepResult.Waiting;
        }

        return SelfTestStepResult.Pass;
    }

    public void CleanUp()
    {
        this.initialSlug = null;
        this.switchedAway = false;
    }

    // Any non-zero slot confirms the cache was recomputed — no reference
    // comparison since custom themes can share slot values with built-ins.
    private static bool HasPopulatedCache(Theme theme)
    {
        var cache = theme.AbgrCache;
        return (cache.Primary | cache.WindowBg | cache.TextPrimary | cache.Border) != 0u;
    }
}
