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

namespace InABox.Avalonia.Components;

public class TimeSelectorTimeChangedEventArgs(TimeSpan? oldTime, TimeSpan? newTime)
{
    public TimeSpan? OldTime { get; set; } = oldTime;

    public TimeSpan? NewTime { get; set; } = newTime;
}

public partial class TimeSelectorButton : TemplatedControl
{
    public static readonly StyledProperty<string> PromptProperty =
        AvaloniaProperty.Register<TimeSelectorButton, string>(nameof(Prompt));
    public static readonly StyledProperty<string> PrefixProperty =
        AvaloniaProperty.Register<TimeSelectorButton, string>(nameof(Prefix));
    public static readonly StyledProperty<string> FormatProperty =
        AvaloniaProperty.Register<TimeSelectorButton, string>(nameof(Format));
    public static readonly StyledProperty<TimeSpan?> TimeProperty =
        AvaloniaProperty.Register<TimeSelectorButton, TimeSpan?>(nameof(Time));

    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 TimeSpan? Time 
    {
        get => GetValue(TimeProperty);
        set => SetValue(TimeProperty, value);
    }

    public event EventHandler<TimeSelectorTimeChangedEventArgs>? TimeChanged;

    static TimeSelectorButton()
    {
        TimeProperty.Changed.AddClassHandler<TimeSelectorButton>(TimeProperty_Changed);
    }

    private static void TimeProperty_Changed(TimeSelectorButton button, AvaloniaPropertyChangedEventArgs args)
    {
        button.TimeChanged?.Invoke(button, new(
            args.OldValue is TimeSpan oldTime ? oldTime : null,
            args.NewValue is TimeSpan newTime ? newTime : null));
    }

    [RelayCommand]
    private async Task Click()
    {
        var time = await Navigation.Popup<TimeSelectorViewModel, TimeSpan?>(x =>
        {
            x.Time = Time;
        });
        if (time.HasValue)
        {
            Time = time.Value == TimeSpan.MinValue ? null : time.Value;
        }
    }
}

public class TimeSelectorTimeSpanFormatter : IMultiValueConverter
{
    public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
    {
        var time = values[0] as TimeSpan?;
        if (values[1] is not TimeSelectorButton btn) return null;
        if (time.HasValue && time.Value != TimeSpan.MinValue)
        {
            var sFormat = btn.Format.NotWhiteSpaceOr("hh\\:mm tt");
            var fmt = "{0} {1:" + sFormat + "}";
            return string.Format(fmt, btn.Prefix, DateTime.Today.Add(time.Value)).Trim();
        }
        return btn.Prompt.NotWhiteSpaceOr("Select Time");
    }
}