using global::Android.Content;
using global::Android.Views.InputMethods;

namespace DodoSSH.Client.Android.Platform;

/// <summary>
/// Puts the software keyboard away.
/// </summary>
/// <remarks>
/// <para>
/// <b>There is no Avalonia way to do this, and it is worth knowing why rather than assuming.</b>
/// <c>TopLevel.InputPane</c> reports the keyboard — its state and the rectangle it occludes, which is what
/// <c>PhoneShell</c> keeps the interface clear of — and offers nothing that closes it. The framework's model
/// is that the keyboard belongs to whatever has focus, so the supported way to dismiss one is to move focus
/// off the text box that raised it.
/// </para>
/// <para>
/// <b>That model does not reach the case this exists for.</b> The keyboard over a terminal was raised by the
/// <c>WebView</c>'s own text input, inside the page, by a native view Avalonia's focus manager does not own.
/// Clearing Avalonia's focus leaves it exactly where it is, because Avalonia never had it. So the request
/// goes to the platform that does own it.
/// </para>
/// <para>
/// <c>HideSoftInputFromWindow</c> needs a window token, and any attached view's will do — they all belong to
/// the same window. The decor view is the one guaranteed to exist for as long as the activity does.
/// </para>
/// <para>
/// Every step is allowed to be absent and none of them is an error: there is no activity while the app is
/// backgrounded, no input-method manager on a system image without one, and no keyboard up most of the time.
/// A method whose whole contract is "if a keyboard is showing, stop showing it" has nothing to report when
/// one is not.
/// </para>
/// </remarks>
internal static class SoftKeyboard
{
    public static void Hide()
    {
        if (PhoneEnvironment.CurrentActivity?.Window?.DecorView is not { } view)
        {
            return;
        }

        if (view.Context?.GetSystemService(Context.InputMethodService) is not InputMethodManager manager)
        {
            return;
        }

        manager.HideSoftInputFromWindow(view.WindowToken, HideSoftInputFlags.None);
    }
}
