using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using DodoSSH.Client.Shell.ViewModels;

namespace DodoSSH.Client.App.Views;

/// <summary>The tab strip, above every screen.</summary>
internal sealed partial class TerminalTabs : UserControl
{
    public TerminalTabs() => InitializeComponent();

    /// <summary>
    /// Closes a tab on a middle click.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Wired on the tab's own template root, which is the whole answer to "and not on the strip itself".
    /// A middle press on the background, on the sentence, or on the button that opens a connection reaches
    /// no handler at all, because there is none there to reach. Nothing has to test what was clicked.
    /// </para>
    /// <para>
    /// <b><c>PointerUpdateKind</c>, not <c>IsMiddleButtonPressed</c>.</b> The latter reports button
    /// <em>state</em>: it is equally true for a left press made while the middle button happens to be held,
    /// and for every press during a middle drag. The question here is which button caused this press, and
    /// that is the one thing only <c>PointerUpdateKind</c> answers.
    /// </para>
    /// <para>
    /// On press rather than on release, which is what every browser and every terminal does. Matching a
    /// release to its press would need capture tracking, to buy the ability to change your mind about a
    /// middle click — a gesture nobody makes by accident and nobody aborts.
    /// </para>
    /// </remarks>
    private void OnTabPointerPressed(object? sender, PointerPressedEventArgs e)
    {
        if (sender is not Visual { DataContext: TerminalTabViewModel tab }
            || DataContext is not MainWindowViewModel shell)
        {
            return;
        }

        if (e.GetCurrentPoint((Visual)sender).Properties.PointerUpdateKind
            is not PointerUpdateKind.MiddleButtonPressed)
        {
            return;
        }

        // Handled, so the strip's ScrollViewer does not also take this as the start of a pan.
        e.Handled = true;

        // Fire-and-forget, as the host sidebar's double-tap connect is: CloseTabCommand is asynchronous —
        // it waits for the workspace to tear the session down — and an event handler has nowhere to await
        // it. Its failures are the workspace's to report, not this strip's.
        shell.CloseTabCommand.Execute(tab);
    }
}
