using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Markup;

namespace Sonex.Client.Controls;

[ContentProperty(Name = nameof(Child))]
public sealed partial class ToolBarGroup : UserControl
{
    public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(
        nameof(Title),
        typeof(string),
        typeof(ToolBarGroup),
        new PropertyMetadata(string.Empty));

    public static readonly DependencyProperty ChildProperty = DependencyProperty.Register(
        nameof(Child),
        typeof(UIElement),
        typeof(ToolBarGroup),
        new PropertyMetadata(null, OnChildChanged));

    public static readonly DependencyProperty IsCompactProperty = DependencyProperty.Register(
        nameof(IsCompact),
        typeof(bool),
        typeof(ToolBarGroup),
        new PropertyMetadata(false, OnIsCompactChanged));

    private bool _isFlyoutOpen;

    public ToolBarGroup()
    {
        InitializeComponent();
        Loaded += ToolBarGroup_Loaded;
    }

    public string Title
    {
        get => (string)GetValue(TitleProperty);
        set => SetValue(TitleProperty, value);
    }

    public UIElement? Child
    {
        get => (UIElement?)GetValue(ChildProperty);
        set => SetValue(ChildProperty, value);
    }

    public bool IsCompact
    {
        get => (bool)GetValue(IsCompactProperty);
        set => SetValue(IsCompactProperty, value);
    }

    private static void OnChildChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is not ToolBarGroup group)
        {
            return;
        }

        if (group._isFlyoutOpen)
        {
            group._CompactFlyout?.Hide();
            return;
        }

        group.ApplyChildContent();
    }

    private static void OnIsCompactChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is ToolBarGroup group)
        {
            group.ApplyCompactMode();
        }
    }

    private void ToolBarGroup_Loaded(object sender, RoutedEventArgs e)
    {
        ApplyChildContent();
        ApplyCompactMode();
    }

    private void ApplyChildContent()
    {
        if (_InlineContentPresenter == null || _isFlyoutOpen)
        {
            return;
        }

        _InlineContentPresenter.Content = Child;
    }

    private void ApplyCompactMode()
    {
        if (_ExpandedRoot == null || _CompactRoot == null)
        {
            return;
        }

        _ExpandedRoot.Visibility = IsCompact ? Visibility.Collapsed : Visibility.Visible;
        _CompactRoot.Visibility = IsCompact ? Visibility.Visible : Visibility.Collapsed;

        if (!IsCompact)
        {
            MoveFlyoutContentBackToInline();
        }
    }

    private void CompactButton_Click(object sender, RoutedEventArgs e)
    {
        if (!IsCompact || Child == null || _CompactFlyout == null || _CompactButton == null)
        {
            return;
        }

        _isFlyoutOpen = true;
        if (_InlineContentPresenter != null)
        {
            _InlineContentPresenter.Content = null;
        }

        if (_FlyoutContentPresenter != null)
        {
            _FlyoutContentPresenter.Content = Child;
        }

        _CompactFlyout.ShowAt(_CompactButton);
    }

    private void CompactFlyout_Closed(object sender, object e)
    {
        MoveFlyoutContentBackToInline();
    }

    private void MoveFlyoutContentBackToInline()
    {
        if (_FlyoutContentPresenter?.Content is UIElement movedElement)
        {
            _FlyoutContentPresenter.Content = null;
            _InlineContentPresenter.Content = movedElement;
        }
        else if (_InlineContentPresenter != null && _InlineContentPresenter.Content == null)
        {
            _InlineContentPresenter.Content = Child;
        }

        _isFlyoutOpen = false;
    }
}
