using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using WpfColor = System.Windows.Media.Color;

namespace Noctalk.UI.Components.Buttons_left_area;

public sealed class Noctalk_left_area_button : System.Windows.Controls.Button
{
    private static readonly Brush Background_normal = new SolidColorBrush(WpfColor.FromRgb(7, 15, 27));
    private static readonly Brush Background_hover = new SolidColorBrush(WpfColor.FromRgb(10, 42, 68));
    private static readonly Brush Background_down = new SolidColorBrush(WpfColor.FromRgb(4, 20, 34));
    private static readonly Brush Background_red_normal = new SolidColorBrush(WpfColor.FromRgb(54, 10, 18));
    private static readonly Brush Background_red_hover = new SolidColorBrush(WpfColor.FromRgb(84, 17, 28));
    private static readonly Brush Background_red_down = new SolidColorBrush(WpfColor.FromRgb(42, 6, 14));
    private static readonly Brush Border_normal = new SolidColorBrush(WpfColor.FromRgb(18, 62, 93));
    private static readonly Brush Border_red_normal = new SolidColorBrush(WpfColor.FromRgb(18, 62, 93));
    private static readonly Brush Border_red = new SolidColorBrush(WpfColor.FromRgb(178, 50, 72));
    private static readonly Brush Text_normal = new SolidColorBrush(WpfColor.FromRgb(73, 217, 255));
    private static readonly Brush Text_red = new SolidColorBrush(WpfColor.FromRgb(255, 138, 154));
    private static readonly Brush Fill_blue_normal = new SolidColorBrush(WpfColor.FromRgb(20, 107, 147));
    private static readonly Brush Fill_blue_hover = new SolidColorBrush(WpfColor.FromRgb(39, 145, 190));
    private static readonly Brush Fill_blue_down = new SolidColorBrush(WpfColor.FromRgb(11, 76, 113));
    private static readonly Brush Fill_blue_border_normal = new SolidColorBrush(WpfColor.FromRgb(11, 76, 113));
    private static readonly Brush Fill_blue_border_hover = new SolidColorBrush(WpfColor.FromRgb(20, 107, 147));
    private static readonly Brush Fill_blue_border_down = new SolidColorBrush(WpfColor.FromRgb(4, 50, 82));
    private static readonly Brush Fill_red_normal = new SolidColorBrush(WpfColor.FromRgb(178, 50, 72));
    private static readonly Brush Fill_red_hover = new SolidColorBrush(WpfColor.FromRgb(216, 78, 99));
    private static readonly Brush Fill_red_down = new SolidColorBrush(WpfColor.FromRgb(125, 27, 45));
    private static readonly Brush Fill_red_border_normal = new SolidColorBrush(WpfColor.FromRgb(125, 27, 45));
    private static readonly Brush Fill_red_border_hover = new SolidColorBrush(WpfColor.FromRgb(178, 50, 72));
    private static readonly Brush Fill_red_border_down = new SolidColorBrush(WpfColor.FromRgb(80, 14, 28));
    private static readonly Brush Text_reversed = new SolidColorBrush(WpfColor.FromRgb(5, 9, 18));

    public static readonly DependencyProperty ModeProperty = DependencyProperty.Register(
        nameof(Mode),
        typeof(Noctalk_left_area_button_mode),
        typeof(Noctalk_left_area_button),
        new PropertyMetadata(Noctalk_left_area_button_mode.Square, UI__left_area_button__property_changed));

    public static readonly DependencyProperty IconProperty = DependencyProperty.Register(
        nameof(Icon),
        typeof(Noctalk_left_area_button_icon),
        typeof(Noctalk_left_area_button),
        new PropertyMetadata(Noctalk_left_area_button_icon.None, UI__left_area_button__property_changed));

    public static readonly DependencyProperty ColorProperty = DependencyProperty.Register(
        nameof(Color),
        typeof(Noctalk_left_area_button_color),
        typeof(Noctalk_left_area_button),
        new PropertyMetadata(Noctalk_left_area_button_color.Blue_O__Blue_O, UI__left_area_button__property_changed));

    public Noctalk_left_area_button_mode Mode
    {
        get => (Noctalk_left_area_button_mode)GetValue(ModeProperty);
        set => SetValue(ModeProperty, value);
    }

    public Noctalk_left_area_button_icon Icon
    {
        get => (Noctalk_left_area_button_icon)GetValue(IconProperty);
        set => SetValue(IconProperty, value);
    }

    public Noctalk_left_area_button_color Color
    {
        get => (Noctalk_left_area_button_color)GetValue(ColorProperty);
        set => SetValue(ColorProperty, value);
    }

    public Noctalk_left_area_button()
    {
        Cursor = System.Windows.Input.Cursors.Hand;
        Template = UI__left_area_button__create_template();
        UI__left_area_button__apply_visual_state();
    }

    private static void UI__left_area_button__property_changed(DependencyObject Dependency_object, DependencyPropertyChangedEventArgs Event_args)
    {
        if (Dependency_object is Noctalk_left_area_button button)
        {
            button.UI__left_area_button__apply_visual_state();
        }
    }

    private void UI__left_area_button__apply_visual_state()
    {
        Width = Mode == Noctalk_left_area_button_mode.Square ? 42 : double.NaN;
        Height = Mode == Noctalk_left_area_button_mode.Square ? 42 : 42;
        HorizontalAlignment = Mode == Noctalk_left_area_button_mode.Square ? HorizontalAlignment.Left : HorizontalAlignment.Stretch;
        Margin = Mode == Noctalk_left_area_button_mode.Square ? new Thickness(0, 0, 6, 0) : new Thickness(6, 0, 6, 6);
        Padding = Mode == Noctalk_left_area_button_mode.Square ? new Thickness(0) : new Thickness(12, 0, 12, 0);
        BorderThickness = new Thickness(1);
        Left_area_button_visual_spec visualSpec = UI__left_area_button__get_visual_spec(false);
        Background = visualSpec.Background_normal;
        BorderBrush = visualSpec.Border;
        Foreground = visualSpec.Foreground;
        Content = Mode == Noctalk_left_area_button_mode.Square
            ? Noctalk_left_area_button_icon_factory.Create(Icon, Foreground)
            : Content;
    }

    private static ControlTemplate UI__left_area_button__create_template()
    {
        FrameworkElementFactory border = new(typeof(Border));
        border.Name = "ButtonBorder";
        border.SetValue(Border.BackgroundProperty, new TemplateBindingExtension(BackgroundProperty));
        border.SetValue(Border.BorderBrushProperty, new TemplateBindingExtension(BorderBrushProperty));
        border.SetValue(Border.BorderThicknessProperty, new TemplateBindingExtension(BorderThicknessProperty));
        border.SetValue(Border.PaddingProperty, new TemplateBindingExtension(PaddingProperty));

        FrameworkElementFactory content = new(typeof(ContentPresenter));
        content.SetValue(ContentPresenter.HorizontalAlignmentProperty, HorizontalAlignment.Center);
        content.SetValue(ContentPresenter.VerticalAlignmentProperty, VerticalAlignment.Center);
        content.SetValue(ContentPresenter.RecognizesAccessKeyProperty, true);
        border.AppendChild(content);

        ControlTemplate template = new(typeof(System.Windows.Controls.Button)) { VisualTree = border };

        MultiTrigger hoverTrigger = new();
        hoverTrigger.Conditions.Add(new Condition(IsMouseOverProperty, true));
        hoverTrigger.Conditions.Add(new Condition(ColorProperty, Noctalk_left_area_button_color.Blue_O__Blue_O));
        hoverTrigger.Setters.Add(new Setter(Border.BackgroundProperty, Background_hover, "ButtonBorder"));
        template.Triggers.Add(hoverTrigger);

        MultiTrigger redHoverTrigger = new();
        redHoverTrigger.Conditions.Add(new Condition(IsMouseOverProperty, true));
        redHoverTrigger.Conditions.Add(new Condition(ColorProperty, Noctalk_left_area_button_color.Red_O__Red_O));
        redHoverTrigger.Setters.Add(new Setter(Border.BackgroundProperty, Background_red_hover, "ButtonBorder"));
        redHoverTrigger.Setters.Add(new Setter(Border.BorderBrushProperty, Border_red, "ButtonBorder"));
        template.Triggers.Add(redHoverTrigger);

        MultiTrigger blueReverseHoverTrigger = new();
        blueReverseHoverTrigger.Conditions.Add(new Condition(IsMouseOverProperty, true));
        blueReverseHoverTrigger.Conditions.Add(new Condition(ColorProperty, Noctalk_left_area_button_color.Blue_R__Blue_R));
        blueReverseHoverTrigger.Setters.Add(new Setter(Border.BackgroundProperty, Fill_blue_hover, "ButtonBorder"));
        blueReverseHoverTrigger.Setters.Add(new Setter(Border.BorderBrushProperty, Fill_blue_border_hover, "ButtonBorder"));
        template.Triggers.Add(blueReverseHoverTrigger);

        MultiTrigger redReverseHoverTrigger = new();
        redReverseHoverTrigger.Conditions.Add(new Condition(IsMouseOverProperty, true));
        redReverseHoverTrigger.Conditions.Add(new Condition(ColorProperty, Noctalk_left_area_button_color.Red_R__Red_R));
        redReverseHoverTrigger.Setters.Add(new Setter(Border.BackgroundProperty, Fill_red_hover, "ButtonBorder"));
        redReverseHoverTrigger.Setters.Add(new Setter(Border.BorderBrushProperty, Fill_red_border_hover, "ButtonBorder"));
        template.Triggers.Add(redReverseHoverTrigger);

        MultiTrigger blueToRedHoverTrigger = new();
        blueToRedHoverTrigger.Conditions.Add(new Condition(IsMouseOverProperty, true));
        blueToRedHoverTrigger.Conditions.Add(new Condition(ColorProperty, Noctalk_left_area_button_color.Blue_O__Red_O));
        blueToRedHoverTrigger.Setters.Add(new Setter(Border.BackgroundProperty, Background_red_hover, "ButtonBorder"));
        blueToRedHoverTrigger.Setters.Add(new Setter(Border.BorderBrushProperty, Border_red, "ButtonBorder"));
        template.Triggers.Add(blueToRedHoverTrigger);

        MultiTrigger pressedTrigger = new();
        pressedTrigger.Conditions.Add(new Condition(IsPressedProperty, true));
        pressedTrigger.Conditions.Add(new Condition(ColorProperty, Noctalk_left_area_button_color.Blue_O__Blue_O));
        pressedTrigger.Setters.Add(new Setter(Border.BackgroundProperty, Background_down, "ButtonBorder"));
        template.Triggers.Add(pressedTrigger);

        MultiTrigger redPressedTrigger = new();
        redPressedTrigger.Conditions.Add(new Condition(IsPressedProperty, true));
        redPressedTrigger.Conditions.Add(new Condition(ColorProperty, Noctalk_left_area_button_color.Red_O__Red_O));
        redPressedTrigger.Setters.Add(new Setter(Border.BackgroundProperty, Background_red_down, "ButtonBorder"));
        redPressedTrigger.Setters.Add(new Setter(Border.BorderBrushProperty, Border_red, "ButtonBorder"));
        template.Triggers.Add(redPressedTrigger);

        MultiTrigger blueReversePressedTrigger = new();
        blueReversePressedTrigger.Conditions.Add(new Condition(IsPressedProperty, true));
        blueReversePressedTrigger.Conditions.Add(new Condition(ColorProperty, Noctalk_left_area_button_color.Blue_R__Blue_R));
        blueReversePressedTrigger.Setters.Add(new Setter(Border.BackgroundProperty, Fill_blue_down, "ButtonBorder"));
        blueReversePressedTrigger.Setters.Add(new Setter(Border.BorderBrushProperty, Fill_blue_border_down, "ButtonBorder"));
        template.Triggers.Add(blueReversePressedTrigger);

        MultiTrigger redReversePressedTrigger = new();
        redReversePressedTrigger.Conditions.Add(new Condition(IsPressedProperty, true));
        redReversePressedTrigger.Conditions.Add(new Condition(ColorProperty, Noctalk_left_area_button_color.Red_R__Red_R));
        redReversePressedTrigger.Setters.Add(new Setter(Border.BackgroundProperty, Fill_red_down, "ButtonBorder"));
        redReversePressedTrigger.Setters.Add(new Setter(Border.BorderBrushProperty, Fill_red_border_down, "ButtonBorder"));
        template.Triggers.Add(redReversePressedTrigger);

        MultiTrigger blueToRedPressedTrigger = new();
        blueToRedPressedTrigger.Conditions.Add(new Condition(IsPressedProperty, true));
        blueToRedPressedTrigger.Conditions.Add(new Condition(ColorProperty, Noctalk_left_area_button_color.Blue_O__Red_O));
        blueToRedPressedTrigger.Setters.Add(new Setter(Border.BackgroundProperty, Background_red_down, "ButtonBorder"));
        blueToRedPressedTrigger.Setters.Add(new Setter(Border.BorderBrushProperty, Border_red, "ButtonBorder"));
        template.Triggers.Add(blueToRedPressedTrigger);

        return template;
    }

    private Left_area_button_visual_spec UI__left_area_button__get_visual_spec(bool Use_hover_part)
    {
        Left_area_button_color_part colorPart = Color switch
        {
            Noctalk_left_area_button_color.Red_O__Red_O => Left_area_button_color_part.Red_O,
            Noctalk_left_area_button_color.Blue_R__Blue_R => Left_area_button_color_part.Blue_R,
            Noctalk_left_area_button_color.Red_R__Red_R => Left_area_button_color_part.Red_R,
            Noctalk_left_area_button_color.Blue_O__Red_O when Use_hover_part => Left_area_button_color_part.Red_O,
            _ => Left_area_button_color_part.Blue_O
        };

        return colorPart switch
        {
            Left_area_button_color_part.Red_O => new Left_area_button_visual_spec(Background_red_normal, Background_red_hover, Background_red_down, Border_red, Text_red),
            Left_area_button_color_part.Blue_R => new Left_area_button_visual_spec(Fill_blue_normal, Fill_blue_hover, Fill_blue_down, Fill_blue_border_normal, Text_reversed),
            Left_area_button_color_part.Red_R => new Left_area_button_visual_spec(Fill_red_normal, Fill_red_hover, Fill_red_down, Fill_red_border_normal, Text_reversed),
            _ => new Left_area_button_visual_spec(Background_normal, Background_hover, Background_down, Border_normal, Text_normal)
        };
    }

    private enum Left_area_button_color_part
    {
        Blue_O,
        Red_O,
        Blue_R,
        Red_R
    }

    private readonly record struct Left_area_button_visual_spec(Brush Background_normal, Brush Background_hover, Brush Background_down, Brush Border, Brush Foreground);
}
