using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using MainShell.Common.View;
using MainShell.Common.ViewModel;

namespace MainShell.Common
{
    public static class MwMessageBoxGlyphs
    {
        public const string None = "\uE686";
        public const string Information = "\uE625";
        public const string Warning = "\uE7BD";
        public const string Error = "\uE76C";
        public const string Question = "\uE686";
    }

    public sealed class MwMessageBoxButtonText
    {
        public string Ok { get; set; } = "确定";
        public string Cancel { get; set; } = "取消";
        public string Yes { get; set; } = "是";
        public string No { get; set; } = "否";
        public string Retry { get; set; } = "重试";
        public string Abort { get; set; } = "终止";
        public string Ignore { get; set; } = "忽略";

        public static MwMessageBoxButtonText CreateDefault()
        {
            return new MwMessageBoxButtonText();
        }
    }

    public sealed class MwMessageBoxButtonDefinition
    {
        public string Text { get; set; }

        public MessageBoxResult Result { get; set; }

        public bool IsDefault { get; set; }

        public bool IsCancel { get; set; }

        public bool IsPrimary { get; set; }

        public Style ButtonStyle { get; set; }
    }

    public sealed class MwMessageBoxIconTheme
    {
        public string NoneGlyph { get; set; } = MwMessageBoxGlyphs.None;

        public string InformationGlyph { get; set; } = MwMessageBoxGlyphs.Information;

        public string WarningGlyph { get; set; } = MwMessageBoxGlyphs.Warning;

        public string ErrorGlyph { get; set; } = MwMessageBoxGlyphs.Error;

        public string QuestionGlyph { get; set; } = MwMessageBoxGlyphs.Question;

        public static MwMessageBoxIconTheme CreateDefault()
        {
            return new MwMessageBoxIconTheme();
        }
    }

    public sealed class MwMessageBoxColorPalette
    {
        public MwMessageBoxColorPalette()
        {
        }

        public MwMessageBoxColorPalette(string accentColor, string iconBackgroundColor, string iconForegroundColor)
        {
            AccentColor = accentColor;
            IconBackgroundColor = iconBackgroundColor;
            IconForegroundColor = iconForegroundColor;
        }

        public string AccentColor { get; set; }

        public string IconBackgroundColor { get; set; }

        public string IconForegroundColor { get; set; }
    }

    public sealed class MwMessageBoxButtonColorTheme
    {
        public MwMessageBoxButtonColorTheme()
        {
        }

        public MwMessageBoxButtonColorTheme(string backgroundColor, string hoverBackgroundColor, string pressedBackgroundColor, string borderColor, string foregroundColor)
        {
            BackgroundColor = backgroundColor;
            HoverBackgroundColor = hoverBackgroundColor;
            PressedBackgroundColor = pressedBackgroundColor;
            BorderColor = borderColor;
            ForegroundColor = foregroundColor;
        }

        public string BackgroundColor { get; set; }

        public string HoverBackgroundColor { get; set; }

        public string PressedBackgroundColor { get; set; }

        public string BorderColor { get; set; }

        public string ForegroundColor { get; set; }
    }

    public sealed class MwMessageBoxVisualTheme
    {
        public MwMessageBoxColorPalette NonePalette { get; set; } = new MwMessageBoxColorPalette("#9CA3AF", "#F3F4F6", "#6B7280");

        public MwMessageBoxColorPalette InformationPalette { get; set; } = new MwMessageBoxColorPalette("#38BDF8", "#E0F2FE", "#0284C7");

        public MwMessageBoxColorPalette WarningPalette { get; set; } = new MwMessageBoxColorPalette("#F59E0B", "#FEF3C7", "#D97706");

        public MwMessageBoxColorPalette ErrorPalette { get; set; } = new MwMessageBoxColorPalette("#EF4444", "#FEE2E2", "#DC2626");

        public MwMessageBoxColorPalette QuestionPalette { get; set; } = new MwMessageBoxColorPalette("#3B82F6", "#DBEAFE", "#2563EB");

        public MwMessageBoxButtonColorTheme PrimaryButtonTheme { get; set; } = new MwMessageBoxButtonColorTheme("#0E6AE8", "#0B5AD0", "#094BAC", "#0E6AE8", "#FFFFFF");

        public MwMessageBoxButtonColorTheme SecondaryButtonTheme { get; set; } = new MwMessageBoxButtonColorTheme("#F3F4F6", "#E5E7EB", "#D1D5DB", "#D1D5DB", "#374151");

        public static MwMessageBoxVisualTheme CreateDefault()
        {
            return new MwMessageBoxVisualTheme();
        }
    }

    public sealed class MwMessageBoxState
    {
        public string Caption { get; set; }

        public string Message { get; set; }

        public string IconGlyph { get; set; }

        public string IconPathData { get; set; }

        public string TimeText { get; set; }

        public Brush AccentBrush { get; set; }

        public Brush IconBackgroundBrush { get; set; }

        public Brush IconForegroundBrush { get; set; }

        public IReadOnlyList<MwMessageBoxButtonDefinition> Buttons { get; set; }

        public MessageBoxResult DefaultResult { get; set; }

        public TextAlignment MessageTextAlignment { get; set; } = TextAlignment.Left;

        public FlowDirection WindowFlowDirection { get; set; } = FlowDirection.LeftToRight;

        public FlowDirection MessageFlowDirection { get; set; } = FlowDirection.LeftToRight;
    }

    public static class MwMessageBox
    {
        public static MwMessageBoxButtonText DefaultButtonText { get; set; } = MwMessageBoxButtonText.CreateDefault();

        public static MwMessageBoxIconTheme IconTheme { get; set; } = MwMessageBoxIconTheme.CreateDefault();

        public static MwMessageBoxVisualTheme VisualTheme { get; set; } = MwMessageBoxVisualTheme.CreateDefault();

        public static MessageBoxResult Show(string messageBoxText)
        {
            return Show(null, messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None, 0, null);
        }

        public static MessageBoxResult Show(string messageBoxText, string caption)
        {
            return Show(null, messageBoxText, caption, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None, 0, null);
        }

        public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button)
        {
            return Show(null, messageBoxText, caption, button, MessageBoxImage.None, MessageBoxResult.None, 0, null);
        }

        public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
        {
            return Show(null, messageBoxText, caption, button, icon, MessageBoxResult.None, 0, null);
        }

        public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
        {
            return Show(null, messageBoxText, caption, button, icon, defaultResult, 0, null);
        }

        public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
        {
            return Show(null, messageBoxText, caption, button, icon, defaultResult, options, null);
        }

        public static MessageBoxResult Show(Window owner, string messageBoxText)
        {
            return Show(owner, messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None, 0, null);
        }

        public static MessageBoxResult Show(Window owner, string messageBoxText, string caption)
        {
            return Show(owner, messageBoxText, caption, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None, 0, null);
        }

        public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button)
        {
            return Show(owner, messageBoxText, caption, button, MessageBoxImage.None, MessageBoxResult.None, 0, null);
        }

        public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
        {
            return Show(owner, messageBoxText, caption, button, icon, MessageBoxResult.None, 0, null);
        }

        public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
        {
            return Show(owner, messageBoxText, caption, button, icon, defaultResult, 0, null);
        }

        public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
        {
            return Show(owner, messageBoxText, caption, button, icon, defaultResult, options, null);
        }

        public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MwMessageBoxButtonText buttonText)
        {
            return Show(null, messageBoxText, caption, button, icon, MessageBoxResult.None, 0, buttonText);
        }

        public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MwMessageBoxButtonText buttonText)
        {
            return Show(owner, messageBoxText, caption, button, icon, MessageBoxResult.None, 0, buttonText);
        }

        public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options, MwMessageBoxButtonText buttonText)
        {
            return InvokeOnUiThread(() => ShowCore(owner, messageBoxText, caption, button, icon, defaultResult, options, buttonText));
        }

        public static MessageBoxResult ShowCustom(string messageBoxText, string caption, MessageBoxImage icon, params MwMessageBoxButtonDefinition[] buttons)
        {
            return ShowCustom(null, messageBoxText, caption, icon, MessageBoxResult.None, 0, buttons);
        }

        public static MessageBoxResult ShowCustom(Window owner, string messageBoxText, string caption, MessageBoxImage icon, params MwMessageBoxButtonDefinition[] buttons)
        {
            return ShowCustom(owner, messageBoxText, caption, icon, MessageBoxResult.None, 0, buttons);
        }

        public static MessageBoxResult ShowCustom(Window owner, string messageBoxText, string caption, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options, params MwMessageBoxButtonDefinition[] buttons)
        {
            return InvokeOnUiThread(() => ShowCustomCore(owner, messageBoxText, caption, icon, defaultResult, options, buttons));
        }

        internal static T InvokeOnUiThread<T>(Func<T> callback)
        {
            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }

            Application application = Application.Current;
            if (application == null)
            {
                return callback();
            }

            if (application.Dispatcher == null || application.Dispatcher.CheckAccess())
            {
                return callback();
            }

            return application.Dispatcher.Invoke(callback);
        }

        private static MessageBoxResult ShowCore(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options, MwMessageBoxButtonText buttonText)
        {
            owner = owner ?? GetActiveWindow();

            List<MwMessageBoxButtonDefinition> definitions = CreateButtonDefinitions(button, defaultResult, buttonText ?? DefaultButtonText).ToList();
            MwMessageBoxState state = CreateState(messageBoxText, caption, icon, definitions, defaultResult, options);
            MwMessageBoxWindowViewModel viewModel = new MwMessageBoxWindowViewModel(state);
            MwMessageBoxWindow dialog = new MwMessageBoxWindow(viewModel);
            if (owner != null)
            {
                dialog.Owner = owner;
                dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            }

            dialog.ShowDialog();
            return viewModel.Result;
        }

        private static MessageBoxResult ShowCustomCore(Window owner, string messageBoxText, string caption, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options, params MwMessageBoxButtonDefinition[] buttons)
        {
            owner = owner ?? GetActiveWindow();
            List<MwMessageBoxButtonDefinition> definitions = NormalizeButtonDefinitions(buttons, defaultResult).ToList();
            MwMessageBoxState state = CreateState(messageBoxText, caption, icon, definitions, defaultResult, options);
            MwMessageBoxWindowViewModel viewModel = new MwMessageBoxWindowViewModel(state);
            MwMessageBoxWindow dialog = new MwMessageBoxWindow(viewModel);
            if (owner != null)
            {
                dialog.Owner = owner;
                dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            }

            dialog.ShowDialog();
            return viewModel.Result;
        }

        private static IEnumerable<MwMessageBoxButtonDefinition> CreateButtonDefinitions(MessageBoxButton button, MessageBoxResult defaultResult, MwMessageBoxButtonText buttonText)
        {
            var labels = buttonText ?? MwMessageBoxButtonText.CreateDefault();
            var definitions = new List<MwMessageBoxButtonDefinition>();

            switch (button)
            {
                case MessageBoxButton.OK:
                    definitions.Add(CreateDefinition(labels.Ok, MessageBoxResult.OK, true));
                    break;
                case MessageBoxButton.OKCancel:
                    definitions.Add(CreateDefinition(labels.Ok, MessageBoxResult.OK, true));
                    definitions.Add(CreateDefinition(labels.Cancel, MessageBoxResult.Cancel, false, true));
                    break;
                case MessageBoxButton.YesNo:
                    definitions.Add(CreateDefinition(labels.Yes, MessageBoxResult.Yes, true));
                    definitions.Add(CreateDefinition(labels.No, MessageBoxResult.No));
                    break;
                case MessageBoxButton.YesNoCancel:
                    definitions.Add(CreateDefinition(labels.Yes, MessageBoxResult.Yes, true));
                    definitions.Add(CreateDefinition(labels.No, MessageBoxResult.No));
                    definitions.Add(CreateDefinition(labels.Cancel, MessageBoxResult.Cancel, false, true));
                    break;
                default:
                    definitions.Add(CreateDefinition(labels.Ok, MessageBoxResult.OK, true));
                    break;
            }

            return NormalizeButtonDefinitions(definitions, defaultResult);
        }

        private static IEnumerable<MwMessageBoxButtonDefinition> NormalizeButtonDefinitions(IEnumerable<MwMessageBoxButtonDefinition> buttons, MessageBoxResult defaultResult)
        {
            var definitions = (buttons ?? Enumerable.Empty<MwMessageBoxButtonDefinition>())
                .Where(item => item != null)
                .Select(item => new MwMessageBoxButtonDefinition
                {
                    Text = string.IsNullOrWhiteSpace(item.Text) ? item.Result.ToString() : item.Text,
                    Result = item.Result,
                    IsCancel = item.IsCancel,
                    IsDefault = item.IsDefault,
                    IsPrimary = item.IsPrimary,
                    ButtonStyle = item.ButtonStyle
                })
                .ToList();

            if (definitions.Count == 0)
            {
                definitions.Add(CreateDefinition(DefaultButtonText.Ok, MessageBoxResult.OK, true));
            }

            var targetDefault = defaultResult == MessageBoxResult.None
                ? definitions.FirstOrDefault(item => item.IsDefault)?.Result ?? definitions[0].Result
                : defaultResult;

            foreach (var item in definitions)
            {
                item.IsDefault = item.Result == targetDefault;
            }

            if (!definitions.Any(item => item.IsCancel))
            {
                var cancelButton = definitions.FirstOrDefault(item => item.Result == MessageBoxResult.Cancel);
                if (cancelButton != null)
                {
                    cancelButton.IsCancel = true;
                }
            }

            if (!definitions.Any(item => item.IsPrimary))
            {
                var primary = definitions.FirstOrDefault(item => item.IsDefault) ?? definitions[0];
                primary.IsPrimary = true;
            }

            foreach (var item in definitions)
            {
                item.ButtonStyle = item.ButtonStyle ?? GetButtonStyle(item.IsPrimary);
            }

            return definitions;
        }

        private static MwMessageBoxButtonDefinition CreateDefinition(string text, MessageBoxResult result, bool isPrimary = false, bool isCancel = false)
        {
            return new MwMessageBoxButtonDefinition
            {
                Text = text,
                Result = result,
                IsPrimary = isPrimary,
                IsDefault = isPrimary,
                IsCancel = isCancel,
                ButtonStyle = GetButtonStyle(isPrimary)
            };
        }

        internal static Style GetButtonStyle(bool isPrimary)
        {
            if (Application.Current != null)
            {
                var key = isPrimary ? "SaveButtonStyle" : "SettingsButtonStyle";
                var resourceStyle = Application.Current.TryFindResource(key) as Style;
                if (resourceStyle != null)
                {
                    return resourceStyle;
                }
            }

            var visualTheme = VisualTheme ?? MwMessageBoxVisualTheme.CreateDefault();
            var buttonTheme = isPrimary ? visualTheme.PrimaryButtonTheme : visualTheme.SecondaryButtonTheme;

            var style = new Style(typeof(System.Windows.Controls.Button));
            style.Setters.Add(new Setter(System.Windows.Controls.Control.BackgroundProperty, CreateBrush(buttonTheme.BackgroundColor)));
            style.Setters.Add(new Setter(System.Windows.Controls.Control.BorderBrushProperty, CreateBrush(buttonTheme.BorderColor)));
            style.Setters.Add(new Setter(System.Windows.Controls.Control.BorderThicknessProperty, new Thickness(1)));
            style.Setters.Add(new Setter(System.Windows.Controls.Control.ForegroundProperty, CreateBrush(buttonTheme.ForegroundColor)));
            style.Setters.Add(new Setter(System.Windows.Controls.Control.FontSizeProperty, 14d));
            style.Setters.Add(new Setter(System.Windows.Controls.Control.FontWeightProperty, FontWeights.SemiBold));
            style.Setters.Add(new Setter(System.Windows.Controls.Control.CursorProperty, System.Windows.Input.Cursors.Hand));

            var hoverTrigger = new Trigger { Property = UIElement.IsMouseOverProperty, Value = true };
            hoverTrigger.Setters.Add(new Setter(System.Windows.Controls.Control.BackgroundProperty, CreateBrush(buttonTheme.HoverBackgroundColor)));
            style.Triggers.Add(hoverTrigger);

            var pressedTrigger = new Trigger { Property = System.Windows.Controls.Primitives.ButtonBase.IsPressedProperty, Value = true };
            pressedTrigger.Setters.Add(new Setter(System.Windows.Controls.Control.BackgroundProperty, CreateBrush(buttonTheme.PressedBackgroundColor)));
            style.Triggers.Add(pressedTrigger);

            return style;
        }

        internal static MessageBoxResult ResolveFallbackResult(MwMessageBoxState state)
        {
            if (state == null)
            {
                return MessageBoxResult.None;
            }

            if (state.DefaultResult != MessageBoxResult.None)
            {
                return state.DefaultResult;
            }

            var cancelButton = state.Buttons != null ? state.Buttons.FirstOrDefault(item => item.IsCancel) : null;
            if (cancelButton != null)
            {
                return cancelButton.Result;
            }

            var defaultButton = state.Buttons != null ? state.Buttons.FirstOrDefault(item => item.IsDefault) ?? state.Buttons.FirstOrDefault() : null;
            return defaultButton != null ? defaultButton.Result : MessageBoxResult.None;
        }

        private static Window GetActiveWindow()
        {
            if (Application.Current == null)
            {
                return null;
            }

            var active = Application.Current.Windows.OfType<Window>().FirstOrDefault(w => w.IsActive);
            if (active != null)
            {
                return active;
            }

            if (Application.Current.MainWindow != null && Application.Current.MainWindow.IsVisible)
            {
                return Application.Current.MainWindow;
            }

            return Application.Current.Windows.OfType<Window>()
                .Where(w => w.IsVisible)
                .OrderByDescending(w => w.IsLoaded)
                .FirstOrDefault();
        }

        private static MwMessageBoxState CreateState(string message, string caption, MessageBoxImage icon, IReadOnlyList<MwMessageBoxButtonDefinition> buttons, MessageBoxResult defaultResult, MessageBoxOptions options)
        {
            var palette = CreatePaletteBrushes(GetPalette(icon));
            return new MwMessageBoxState
            {
                Caption = ResolveCaption(caption, icon),
                Message = message,
                IconGlyph = GetIconText(icon, IconTheme),
                IconPathData = GetIconPathData(icon),
                TimeText = DateTime.Now.ToString("HH:mm:ss"),
                AccentBrush = palette.AccentBrush,
                IconBackgroundBrush = palette.IconBackgroundBrush,
                IconForegroundBrush = palette.IconForegroundBrush,
                Buttons = buttons,
                DefaultResult = defaultResult,
                MessageTextAlignment = (options & MessageBoxOptions.RightAlign) == MessageBoxOptions.RightAlign ? TextAlignment.Right : TextAlignment.Left,
                WindowFlowDirection = (options & MessageBoxOptions.RtlReading) == MessageBoxOptions.RtlReading ? FlowDirection.RightToLeft : FlowDirection.LeftToRight,
                MessageFlowDirection = (options & MessageBoxOptions.RtlReading) == MessageBoxOptions.RtlReading ? FlowDirection.RightToLeft : FlowDirection.LeftToRight
            };
        }

        private static string ResolveCaption(string caption, MessageBoxImage icon)
        {
            if (!string.IsNullOrWhiteSpace(caption))
            {
                return caption;
            }

            switch (icon)
            {
                case MessageBoxImage.Warning:
                    return "警告提示";
                case MessageBoxImage.Error:
                    return "报警提示";
                case MessageBoxImage.Information:
                    return "信息提示";
                case MessageBoxImage.Question:
                    return "操作确认";
                default:
                    return "提示";
            }
        }

        private static string GetIconText(MessageBoxImage icon, MwMessageBoxIconTheme iconTheme)
        {
            var theme = iconTheme ?? MwMessageBoxIconTheme.CreateDefault();

            switch (icon)
            {
                case MessageBoxImage.None:
                    return theme.NoneGlyph;
                case MessageBoxImage.Warning:
                    return theme.WarningGlyph;
                case MessageBoxImage.Error:
                    return theme.ErrorGlyph;
                case MessageBoxImage.Information:
                    return theme.InformationGlyph;
                case MessageBoxImage.Question:
                    return theme.QuestionGlyph;
                default:
                    return theme.NoneGlyph;
            }
        }

        private static string GetIconPathData(MessageBoxImage icon)
        {
            switch (icon)
            {
                case MessageBoxImage.Warning:
                    return "M11,4 H13 V14 H11 Z M11,16 H13 V18 H11 Z";
                case MessageBoxImage.Error:
                    return "M7.76,6.34 L12,10.59 L16.24,6.34 L17.66,7.76 L13.41,12 L17.66,16.24 L16.24,17.66 L12,13.41 L7.76,17.66 L6.34,16.24 L10.59,12 L6.34,7.76 Z";
                case MessageBoxImage.Information:
                    return "M11,5 H13 V7 H11 Z M11,9 H13 V19 H11 Z";
                case MessageBoxImage.Question:
                    return "M10.2,8.8 C10.27,7.69 11.17,6.82 12.3,6.82 C13.46,6.82 14.36,7.66 14.36,8.75 C14.36,9.52 13.96,10.12 13.02,10.82 C11.74,11.78 11.1,12.65 11.1,14.35 L12.9,14.35 C12.9,13.26 13.27,12.74 14.1,12.09 C15.29,11.17 16,10.14 16,8.72 C16,6.69 14.37,5 12.3,5 C10.23,5 8.56,6.63 8.4,8.8 Z M11.05,16.2 H13.15 V18.3 H11.05 Z";
                default:
                    return "M8,11 H16 V13 H8 Z";
            }
        }

        private static MwMessageBoxColorPalette GetPalette(MessageBoxImage icon)
        {
            var visualTheme = VisualTheme ?? MwMessageBoxVisualTheme.CreateDefault();

            switch (icon)
            {
                case MessageBoxImage.Warning:
                    return CreatePalette(visualTheme.WarningPalette, visualTheme.NonePalette);
                case MessageBoxImage.Error:
                    return CreatePalette(visualTheme.ErrorPalette, visualTheme.NonePalette);
                case MessageBoxImage.Information:
                    return CreatePalette(visualTheme.InformationPalette, visualTheme.NonePalette);
                case MessageBoxImage.Question:
                    return CreatePalette(visualTheme.QuestionPalette, visualTheme.NonePalette);
                default:
                    return CreatePalette(visualTheme.NonePalette, MwMessageBoxVisualTheme.CreateDefault().NonePalette);
            }
        }

        private static MwMessageBoxPaletteBrushes CreatePaletteBrushes(MwMessageBoxColorPalette palette)
        {
            return new MwMessageBoxPaletteBrushes(palette);
        }

        private static MwMessageBoxColorPalette CreatePalette(MwMessageBoxColorPalette palette, MwMessageBoxColorPalette fallbackPalette)
        {
            var resolvedFallback = fallbackPalette ?? MwMessageBoxVisualTheme.CreateDefault().NonePalette;
            var resolvedPalette = palette ?? resolvedFallback;
            return new MwMessageBoxColorPalette(
                resolvedPalette.AccentColor ?? resolvedFallback.AccentColor,
                resolvedPalette.IconBackgroundColor ?? resolvedFallback.IconBackgroundColor,
                resolvedPalette.IconForegroundColor ?? resolvedFallback.IconForegroundColor);
        }

        private static SolidColorBrush CreateBrush(string color)
        {
            return (SolidColorBrush)new BrushConverter().ConvertFromString(color);
        }

        private sealed class MwMessageBoxPaletteBrushes
        {
            public MwMessageBoxPaletteBrushes(MwMessageBoxColorPalette palette)
            {
                var resolvedPalette = palette ?? MwMessageBoxVisualTheme.CreateDefault().NonePalette;
                AccentBrush = CreateBrush(resolvedPalette.AccentColor ?? "#9CA3AF");
                IconBackgroundBrush = CreateBrush(resolvedPalette.IconBackgroundColor ?? "#F3F4F6");
                IconForegroundBrush = CreateBrush(resolvedPalette.IconForegroundColor ?? "#6B7280");
            }

            public Brush AccentBrush { get; }

            public Brush IconBackgroundBrush { get; }

            public Brush IconForegroundBrush { get; }

            private static SolidColorBrush CreateBrush(string color)
            {
                return (SolidColorBrush)new BrushConverter().ConvertFromString(color);
            }
        }
    }
}