using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data.Converters;
using CommunityToolkit.Mvvm.Input;
using ExCSS;
using InABox.Avalonia.Components.DateSelector;
using InABox.Avalonia.Converters;
using InABox.Core;
using System.Globalization;
using System.Windows.Input;

namespace InABox.Avalonia.Components;

public class DateSelectorDateChangedEventArgs(DateTime? oldDate, DateTime? newDate)
{
    public DateTime? OldDate { get; set; } = oldDate;

    public DateTime? NewDate { get; set; } = newDate;
}

public partial class DateSelectorButton : TemplatedControl
{
    public static readonly StyledProperty<string> PromptProperty =
        AvaloniaProperty.Register<DateSelectorButton, string>(nameof(Prompt));
    public static readonly StyledProperty<string> PrefixProperty =
        AvaloniaProperty.Register<DateSelectorButton, string>(nameof(Prefix));
    public static readonly StyledProperty<string> FormatProperty =
        AvaloniaProperty.Register<DateSelectorButton, string>(nameof(Format));
    public static readonly StyledProperty<DateTime?> DateProperty =
        AvaloniaProperty.Register<DateSelectorButton, DateTime?>(nameof(Date));

    public string Prompt
    {
        get => GetValue(PromptProperty);
        set => SetValue(PromptProperty, value);
    }

    public string Prefix 
    {
        get => GetValue(PrefixProperty);
        set => SetValue(PrefixProperty, value);
    }

    public string Format 
    {
        get => GetValue(FormatProperty);
        set => SetValue(FormatProperty, value);
    }

    public DateTime? Date 
    {
        get => GetValue(DateProperty);
        set => SetValue(DateProperty, value);
    }

    public event EventHandler<DateSelectorDateChangedEventArgs>? DateChanged;

    static DateSelectorButton()
    {
        DateProperty.Changed.AddClassHandler<DateSelectorButton>(DateProperty_Changed);
    }

    private static void DateProperty_Changed(DateSelectorButton button, AvaloniaPropertyChangedEventArgs args)
    {
        button.DateChanged?.Invoke(button, new(
            args.OldValue is DateTime oldDate ? oldDate : null,
            args.NewValue is DateTime newDate ? newDate : null));
    }

    [RelayCommand]
    private async Task Click()
    {
        var date = await Navigation.Popup<DateSelectorViewModel, DateTime?>(x =>
        {
            x.Date = Date;
        });
        if (date.HasValue)
        {
            Date = date.Value == DateTime.MinValue ? null : date.Value;
        }
    }
}

public class DateSelectorDateTimeFormatter : IMultiValueConverter
{
    public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
    {
        var date = values[0] as DateTime?;
        if (values[1] is not DateSelectorButton btn) return null;
        if (date.HasValue && !date.Value.IsEmpty())
        {
            var sFormat = btn.Format.NotWhiteSpaceOr("dd MMMM yy");
            var fmt = "{0} {1:" + sFormat + "}";
            return string.Format(fmt, btn.Prefix, date.Value).Trim();
        }
        return btn.Prompt.NotWhiteSpaceOr("Select Date");
    }
}