using global::Android.Views;

using Avalonia.Controls;
using Avalonia.Markup.Xaml;

using DodoSSH.Client.Android.Platform;
using DodoSSH.Client.Shell.ViewModels;

namespace DodoSSH.Client.Android.Views;

/// <summary>The phone's single view. The desktop head's MainWindow, without the window.</summary>
internal sealed partial class PhoneShell : UserControl
{
    private MainWindowViewModel? shell;

    public PhoneShell()
    {
        AvaloniaXamlLoader.Load(this);

        DataContextChanged += (_, _) =>
        {
            if (shell is not null)
            {
                shell.PropertyChanged -= OnShellChanged;
            }

            shell = DataContext as MainWindowViewModel;

            if (shell is not null)
            {
                shell.PropertyChanged += OnShellChanged;
                ApplyScreenshotPolicy(shell.State);
            }
        };
    }

    private void OnShellChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (shell is not null && e.PropertyName is nameof(MainWindowViewModel.State))
        {
            ApplyScreenshotPolicy(shell.State);
        }
    }

    /// <summary>
    /// Blocks screenshots and screen recording while the recovery code is on screen.
    /// </summary>
    /// <remarks>
    /// <para>
    /// The recovery screen says screenshots are blocked, and this is what makes that true rather than a
    /// claim. <c>FLAG_SECURE</c> is a window flag — no control can set it — so it lives here, on the one
    /// object that has the activity.
    /// </para>
    /// <para>
    /// <b>It is worth being clear about what this buys.</b> It stops the obvious accident — a screenshot
    /// of the only copy of an unrecoverable code landing in a cloud photo library — and it excludes the
    /// screen from the recent-apps thumbnail, which is the part users never think about. It stops nothing
    /// determined: a second phone photographs the screen perfectly well. The code is meant to be written
    /// down, and this only pushes people away from the one place it must not be written down to.
    /// </para>
    /// <para>
    /// Lowered again afterwards rather than left on. Leaving it set would make the terminal unscreenshotable
    /// too, and a screenshot of a shell is a thing people legitimately want.
    /// </para>
    /// </remarks>
    private static void ApplyScreenshotPolicy(ShellState state)
    {
        if (PhoneEnvironment.CurrentActivity?.Window is not { } window)
        {
            return;
        }

        if (state is ShellState.ShowingRecoveryCode)
        {
            window.SetFlags(WindowManagerFlags.Secure, WindowManagerFlags.Secure);
        }
        else
        {
            window.ClearFlags(WindowManagerFlags.Secure);
        }
    }
}
