using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace CamBooth.App.Core;

[System.Windows.Markup.ContentProperty(nameof(DialogContent))]
public partial class BaseDialogOverlay : UserControl
{
    public static readonly DependencyProperty DialogTitleProperty =
        DependencyProperty.Register(nameof(DialogTitle), typeof(string), typeof(BaseDialogOverlay),
            new PropertyMetadata(null, OnDialogTitleChanged));

    public static readonly DependencyProperty DialogContentProperty =
        DependencyProperty.Register(nameof(DialogContent), typeof(object), typeof(BaseDialogOverlay),
            new PropertyMetadata(null, OnDialogContentChanged));

    public static readonly DependencyProperty CloseButtonTextProperty =
        DependencyProperty.Register(nameof(CloseButtonText), typeof(string), typeof(BaseDialogOverlay),
            new PropertyMetadata("Schließen", OnCloseButtonTextChanged));

    public static readonly DependencyProperty PrimaryButtonTextProperty =
        DependencyProperty.Register(nameof(PrimaryButtonText), typeof(string), typeof(BaseDialogOverlay),
            new PropertyMetadata(null, OnPrimaryButtonTextChanged));


    public string? DialogTitle
    {
        get => (string?)GetValue(DialogTitleProperty);
        set => SetValue(DialogTitleProperty, value);
    }

    public object? DialogContent
    {
        get => GetValue(DialogContentProperty);
        set => SetValue(DialogContentProperty, value);
    }

    public string CloseButtonText
    {
        get => (string)GetValue(CloseButtonTextProperty);
        set => SetValue(CloseButtonTextProperty, value);
    }

    public string? PrimaryButtonText
    {
        get => (string?)GetValue(PrimaryButtonTextProperty);
        set => SetValue(PrimaryButtonTextProperty, value);
    }

    public event EventHandler? Closed;
    public event EventHandler? PrimaryButtonClicked;

    private TaskCompletionSource<bool>? _tcs;


    public BaseDialogOverlay()
    {
        InitializeComponent();
        // Apply defaults after controls are created, since DP callbacks don't fire for default values
        CloseActionButton.Content = CloseButtonText;
        CloseActionButton.Foreground = new SolidColorBrush(Color.FromRgb(0x1F, 0x1A, 0x00));
        PrimaryActionButton.Foreground = new SolidColorBrush(Color.FromRgb(0x1F, 0x1A, 0x00));
    }


    public void Show()
    {
        Visibility = Visibility.Visible;
    }

    public Task<bool> ShowAsync()
    {
        _tcs = new TaskCompletionSource<bool>();
        Visibility = Visibility.Visible;
        return _tcs.Task;
    }

    public void Hide()
    {
        Visibility = Visibility.Collapsed;
        _tcs?.TrySetResult(false);
        _tcs = null;
        Closed?.Invoke(this, EventArgs.Empty);
    }


    private void CloseButton_Click(object sender, RoutedEventArgs e)
    {
        Visibility = Visibility.Collapsed;
        _tcs?.TrySetResult(false);
        _tcs = null;
        Closed?.Invoke(this, EventArgs.Empty);
    }

    private void PrimaryButton_Click(object sender, RoutedEventArgs e)
    {
        Visibility = Visibility.Collapsed;
        _tcs?.TrySetResult(true);
        _tcs = null;
        PrimaryButtonClicked?.Invoke(this, EventArgs.Empty);
    }


    private static void OnDialogContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var overlay = (BaseDialogOverlay)d;
        if (overlay.InnerContentPresenter != null)
            overlay.InnerContentPresenter.Content = e.NewValue;
    }

    private static void OnDialogTitleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var overlay = (BaseDialogOverlay)d;
        var title = (string?)e.NewValue;
        overlay.TitleTextBlock.Text = title;
        overlay.TitleTextBlock.Visibility = string.IsNullOrEmpty(title)
            ? Visibility.Collapsed
            : Visibility.Visible;
    }

    private static void OnCloseButtonTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((BaseDialogOverlay)d).CloseActionButton.Content = (string)e.NewValue;
    }

    private static void OnPrimaryButtonTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var overlay = (BaseDialogOverlay)d;
        var text = (string?)e.NewValue;
        overlay.PrimaryActionButton.Content = text;
        overlay.PrimaryActionButton.Visibility = string.IsNullOrEmpty(text)
            ? Visibility.Collapsed
            : Visibility.Visible;
    }
}
