using Avalonia;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using PSCHelpdesk.Shared.Menu;

namespace PSCHelpdesk.Views;

public class ContentDisplay : TemplatedControl
{
    public static AvaloniaProperty SelectedItemProperty =
        AvaloniaProperty.Register<ContentDisplay, Item>(
            nameof(SelectedItem),
            inherits: true,
            defaultBindingMode: BindingMode.TwoWay);
    
    public static AvaloniaProperty SelectedOptionProperty =
        AvaloniaProperty.Register<ContentDisplay, Item>(
            nameof(SelectedOption),
            inherits: true,
            defaultBindingMode: BindingMode.TwoWay);
    
    public static AvaloniaProperty DisplayContentProperty =
        AvaloniaProperty.Register<ContentDisplay, object>(
            nameof(SelectedOption),
            inherits: true,
            defaultBindingMode: BindingMode.TwoWay);
    
    public static DirectProperty<ContentDisplay, object> SelectedContentProperty =
        AvaloniaProperty.RegisterDirect<ContentDisplay, object>(
            nameof(SelectedContent),
            (hm) => hm.SelectedContent);
    
    public Item SelectedItem
    {
        get => (Item)this.GetValue(SelectedItemProperty);
        set
        {
            this.SetValue(SelectedItemProperty, value);
            this.SetValue(SelectedOptionProperty, null);
            SelectionChanged(
                avaloniaObject: this,
                done: true,
                isOption: false);
        }
    }

    public Item SelectedOption
    {
        get => (Item)this.GetValue(SelectedOptionProperty);
        set
        {
            this.SetValue(SelectedOptionProperty, value);
            this.SetValue(SelectedItemProperty, null);
            SelectionChanged(
                avaloniaObject: this,
                done: true,
                isOption: true);
        }
    }
    
    public object DisplayContent
    {
        get => this.GetValue(DisplayContentProperty);
        set
        {
            this.SetValue(DisplayContentProperty, value);
        }
    }
    
    public object SelectedContent
    {
        get
        {
            return this.SelectedItem?.CommandParameter ?? this.SelectedOption?.CommandParameter;
        }
    }

    public static void SelectionChanged(AvaloniaObject avaloniaObject, bool done, bool isOption)
    {
        if (avaloniaObject is ContentDisplay contentDisplay && done)
        {
            if (isOption && contentDisplay.SelectedOption != null)
            {
                avaloniaObject.SetValue(SelectedItemProperty, null);
            }
            else if (!isOption && contentDisplay.SelectedItem != null)
            {
                avaloniaObject.SetValue(SelectedOptionProperty, null);
            }

            contentDisplay.RaisePropertyChanged<object>(SelectedContentProperty, null, contentDisplay.SelectedContent);
        }
    }
}