#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member

namespace TerminalGuiFluentTesting;

public partial class GuiTestContext
{
    /// <summary>
    ///     Adds the given <paramref name="v"/> to the current top level view
    ///     and performs layout.
    /// </summary>
    /// <param name="v"></param>
    /// <returns></returns>
    public GuiTestContext Add (View v)
    {
        WaitIteration (() =>
                       {
                           Toplevel top = Application.Current ?? throw new ("Top was null so could not add view");
                           top.Add (v);
                           top.Layout ();
                           _lastView = v;
                       });

        return this;
    }

    private View? _lastView;

    /// <summary>
    ///     The last view added (e.g. with <see cref="Add"/>) or the root/current top.
    /// </summary>
    public View LastView => _lastView ?? Application.Current ?? throw new ("Could not determine which view to add to");

    private T Find<T> (Func<T, bool> evaluator) where T : View
    {
        Toplevel? t = Application.Current;

        if (t == null)
        {
            Fail ("Application.Current was null when attempting to find view");
        }

        T? f = FindRecursive (t!, evaluator);

        if (f == null)
        {
            Fail ("Failed to tab to a view which matched the Type and evaluator constraints in any SubViews of top");
        }

        return f!;
    }

    private T? FindRecursive<T> (View current, Func<T, bool> evaluator) where T : View
    {
        foreach (View subview in current.SubViews)
        {
            if (subview is T match && evaluator (match))
            {
                return match;
            }

            // Recursive call
            T? result = FindRecursive (subview, evaluator);

            if (result != null)
            {
                return result;
            }
        }

        return null;
    }
}
