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

namespace Sonex.Client.Controls;

public sealed partial class CheckBoxListControl : UserControl
{
    public CheckBoxListControl()
    {
        this.InitializeComponent();
    }

    public List<string> ItemsSource
    {
        get => (List<string>)GetValue(ItemsSourceProperty);
        set => SetValue(ItemsSourceProperty, value);
    }

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register(
            nameof(ItemsSource),
            typeof(List<string>),
            typeof(CheckBoxListControl),
            new PropertyMetadata(null, OnItemsChanged));

    public List<string> SelectedItems
    {
        get => (List<string>)GetValue(SelectedItemsProperty);
        set => SetValue(SelectedItemsProperty, value);
    }

    public static readonly DependencyProperty SelectedItemsProperty =
        DependencyProperty.Register(
            nameof(SelectedItems),
            typeof(List<string>),
            typeof(CheckBoxListControl),
            new PropertyMetadata(null, OnItemsChanged));

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

    private static void OnItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is CheckBoxListControl control)
        {
            control.BuildCheckBoxes();
        }
    }

    private void BuildCheckBoxes()
    {
        ItemsPanel.Children.Clear();

        if (ItemsSource == null)
            return;

        SelectedItems ??= new List<string>();

        foreach (var item in ItemsSource)
        {
            var checkBox = new CheckBox
            {
                Content = item.Replace('_', ' '),
                IsChecked = SelectedItems.Contains(item),
                Tag = item
            };

            checkBox.Checked += CheckBox_Checked;
            checkBox.Unchecked += CheckBox_Unchecked;

            ItemsPanel.Children.Add(checkBox);
        }
    }

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

        SelectedItems ??= new List<string>();

        if (!SelectedItems.Contains(item))
            SelectedItems.Add(item);

        ItemChecked?.Invoke(this, new CheckBoxChangedEventArgs(item, checkBox));
    }

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

        SelectedItems?.Remove(item);

        ItemUnchecked?.Invoke(this, new CheckBoxChangedEventArgs(item, checkBox));
    }
}

public sealed class CheckBoxChangedEventArgs : EventArgs
{
    public string Item { get; }
    public CheckBox CheckBox { get; }

    public CheckBoxChangedEventArgs(string item, CheckBox checkBox)
    {
        Item = item;

        CheckBox = checkBox;
    }
}