using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using SharepointToolbox.Core.Models;
using SharepointToolbox.Services;

namespace SharepointToolbox.Views.Dialogs;

/// <summary>
/// Dialog for selecting multiple SharePoint sites.
/// Loads sites from ISiteListService, shows them in a filterable list with checkboxes.
/// </summary>
public partial class SitePickerDialog : Window
{
    private readonly ISiteListService _siteListService;
    private readonly TenantProfile _profile;
    private List<SitePickerItem> _allItems = new();

    /// <summary>
    /// Returns the list of sites the user checked before clicking OK.
    /// </summary>
    public IReadOnlyList<SiteInfo> SelectedUrls =>
        _allItems.Where(i => i.IsSelected).Select(i => new SiteInfo(i.Url, i.Title)).ToList();

    public SitePickerDialog(ISiteListService siteListService, TenantProfile profile)
    {
        InitializeComponent();
        _siteListService = siteListService;
        _profile = profile;
    }

    private async void Window_Loaded(object sender, RoutedEventArgs e) => await LoadSitesAsync();

    private async Task LoadSitesAsync()
    {
        StatusText.Text = "Loading sites...";
        LoadButton.IsEnabled = false;
        try
        {
            var sites = await _siteListService.GetSitesAsync(
                _profile,
                new Progress<OperationProgress>(),
                System.Threading.CancellationToken.None);

            _allItems = sites.Select(s => new SitePickerItem(s.Url, s.Title)).ToList();
            ApplyFilter();
            StatusText.Text = $"{_allItems.Count} sites loaded.";
        }
        catch (InvalidOperationException ex)
        {
            StatusText.Text = ex.Message;
        }
        catch (Exception ex)
        {
            StatusText.Text = $"Error: {ex.Message}";
        }
        finally
        {
            LoadButton.IsEnabled = true;
        }
    }

    private void ApplyFilter()
    {
        var filter = FilterBox.Text.Trim();
        SiteList.ItemsSource = string.IsNullOrEmpty(filter)
            ? (IEnumerable<SitePickerItem>)_allItems
            : _allItems.Where(i =>
                i.Url.Contains(filter, StringComparison.OrdinalIgnoreCase) ||
                i.Title.Contains(filter, StringComparison.OrdinalIgnoreCase)).ToList();
    }

    private void FilterBox_TextChanged(object sender, TextChangedEventArgs e) => ApplyFilter();

    private void SelectAll_Click(object sender, RoutedEventArgs e)
    {
        foreach (var item in _allItems) item.IsSelected = true;
        ApplyFilter();
    }

    private void DeselectAll_Click(object sender, RoutedEventArgs e)
    {
        foreach (var item in _allItems) item.IsSelected = false;
        ApplyFilter();
    }

    private async void LoadButton_Click(object sender, RoutedEventArgs e) => await LoadSitesAsync();

    private void OK_Click(object sender, RoutedEventArgs e)
    {
        DialogResult = true;
        Close();
    }
}

/// <summary>
/// Mutable wrapper for a site entry shown in the SitePickerDialog list.
/// Supports two-way CheckBox binding via INotifyPropertyChanged.
/// </summary>
public class SitePickerItem : INotifyPropertyChanged
{
    private bool _isSelected;

    public string Url { get; init; } = string.Empty;
    public string Title { get; init; } = string.Empty;

    public bool IsSelected
    {
        get => _isSelected;
        set
        {
            if (_isSelected == value) return;
            _isSelected = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSelected)));
        }
    }

    public event PropertyChangedEventHandler? PropertyChanged;

    public SitePickerItem(string url, string title)
    {
        Url = url;
        Title = title;
    }
}
