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

namespace DodoSSH.Client.App.Views;

/// <summary>
/// The v5b in-screen tab row: one pill per open terminal, and the "+" that opens another — parameterised by
/// <see cref="TabCommand"/> so the terminal surface and the SFTP surface can each wire a click to a different
/// meaning over the same list. See the remark at the top of SessionTabRow.axaml.
/// </summary>
internal sealed partial class SessionTabRow : UserControl
{
    /// <summary>What a left click on a tab runs, with the tab itself as the command parameter.</summary>
    /// <remarks>
    /// A plain <see cref="ICommand"/> rather than a bound property read off the shell, because which command
    /// that is is the one thing this control cannot decide for itself — the terminal surface wants
    /// <c>SelectTabCommand</c> and the SFTP surface wants <c>SelectFilesHostCommand</c>, and only the caller
    /// in <c>MainWindow.axaml</c> knows which screen this instance is on.
    /// </remarks>
    internal static readonly StyledProperty<ICommand?> TabCommandProperty =
        AvaloniaProperty.Register<SessionTabRow, ICommand?>(nameof(TabCommand));

    public SessionTabRow() => InitializeComponent();

    internal ICommand? TabCommand
    {
        get => GetValue(TabCommandProperty);
        set => SetValue(TabCommandProperty, value);
    }

    /// <summary>
    /// Closes a tab on a middle click. See the identical remark on the strip this control replaced,
    /// <c>TerminalTabs.axaml.cs</c>, for why this is <c>PointerUpdateKind</c> rather than
    /// <c>IsMiddleButtonPressed</c>, why it fires on press rather than release, and why it is wired on the
    /// tab's own template root rather than on the row.
    /// </summary>
    /// <remarks>
    /// Not parameterised like <see cref="TabCommand"/>: closing a tab ends its shell regardless of which
    /// screen the middle click landed on, so both rows want the same answer — <c>CloseTabCommand</c>, read
    /// directly off this control's own <see cref="StyledElement.DataContext"/>, which is the shell on both.
    /// </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;
        }

        e.Handled = true;

        shell.CloseTabCommand.Execute(tab);
    }
}
