using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;

namespace Sonex.Client.Controls;

public sealed partial class CheckListControl : UserControl
{
    public CheckListControl()
    {
        InitializeComponent();
    }

    public IList<CheckListItem>? ItemsSource
    {
        get => (IList<CheckListItem>?)GetValue(ItemsSourceProperty);
        set => SetValue(ItemsSourceProperty, value);
    }

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register(
            nameof(ItemsSource),
            typeof(IList<CheckListItem>),
            typeof(CheckListControl),
            new PropertyMetadata(null, OnItemsSourceChanged));

    public bool ShowKeyValueText
    {
        get => (bool)GetValue(ShowKeyValueTextProperty);
        set => SetValue(ShowKeyValueTextProperty, value);
    }

    public static readonly DependencyProperty ShowKeyValueTextProperty =
        DependencyProperty.Register(
            nameof(ShowKeyValueText),
            typeof(bool),
            typeof(CheckListControl),
            new PropertyMetadata(true, OnShowKeyValueTextChanged));

    public event EventHandler<CheckListChangedEventArgs>? ItemChecked;
    public event EventHandler<CheckListChangedEventArgs>? ItemUnchecked;

    private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is not CheckListControl control)
            return;

        control.ApplyShowKeyValueTextToItems();
    }

    private static void OnShowKeyValueTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is not CheckListControl control)
            return;

        control.ApplyShowKeyValueTextToItems();
    }

    private void ApplyShowKeyValueTextToItems()
    {
        if (ItemsSource == null)
            return;

        foreach (var item in ItemsSource)
        {
            item.ShowKeyValueText = ShowKeyValueText;
        }
    }

    private void CheckBox_Click(object sender, RoutedEventArgs e)
    {
        if (sender is not CheckBox checkBox || checkBox.Tag is not CheckListItem item)
        {
            return;
        }

        var isChecked = checkBox.IsChecked == true;
        item.Checked = isChecked;

        if (isChecked)
            ItemChecked?.Invoke(this, new CheckListChangedEventArgs(item, checkBox));
        else
            ItemUnchecked?.Invoke(this, new CheckListChangedEventArgs(item, checkBox));
    }
}

public sealed class CheckListItem
{
    public bool Checked { get; set; }
    public string Title { get; set; } = string.Empty;
    public string Description { get; set; } = string.Empty;
    public string IconGlyph { get; set; } = string.Empty;
    public string Key { get; set; } = string.Empty;
    public object? Value { get; set; }
    public bool ShowKeyValueText { get; set; } = true;

    public string DisplayTitle => string.IsNullOrWhiteSpace(Title) ? Key : Title;

    public Visibility DescriptionVisibility =>
        string.IsNullOrWhiteSpace(Description) ? Visibility.Collapsed : Visibility.Visible;

    public Visibility IconVisibility =>
        string.IsNullOrWhiteSpace(IconGlyph) ? Visibility.Collapsed : Visibility.Visible;

    public string KeyValueText
    {
        get
        {
            var valueText = Value?.ToString() ?? string.Empty;

            if (string.IsNullOrWhiteSpace(Key))
                return valueText;

            if (string.IsNullOrWhiteSpace(valueText))
                return Key;

            return $"{Key}: {valueText}";
        }
    }

    public Visibility KeyValueVisibility =>
        !ShowKeyValueText || string.IsNullOrWhiteSpace(KeyValueText) ? Visibility.Collapsed : Visibility.Visible;
}

public sealed class CheckListChangedEventArgs : EventArgs
{
    public CheckListChangedEventArgs(CheckListItem item, CheckBox checkBox)
    {
        Item = item;
        CheckBox = checkBox;
    }

    public CheckListItem Item { get; }
    public CheckBox CheckBox { get; }
}
