using System.Windows;
using System.Windows.Controls;
using Microsoft.SharePoint.Client;
using SharepointToolbox.Core.Helpers;

namespace SharepointToolbox.Views.Dialogs;

public partial class FolderBrowserDialog : Window
{
    private readonly ClientContext _ctx;
    public string SelectedLibrary { get; private set; } = string.Empty;
    public string SelectedFolderPath { get; private set; } = string.Empty;

    public FolderBrowserDialog(ClientContext ctx)
    {
        InitializeComponent();
        _ctx = ctx;
        Loaded += OnLoaded;
    }

    private async void OnLoaded(object sender, RoutedEventArgs e)
    {
        try
        {
            // Load libraries
            var web = _ctx.Web;
            var lists = _ctx.LoadQuery(web.Lists
                .Include(l => l.Title, l => l.Hidden, l => l.BaseType, l => l.RootFolder)
                .Where(l => !l.Hidden && l.BaseType == BaseType.DocumentLibrary));
            var progress = new Progress<Core.Models.OperationProgress>();
            await ExecuteQueryRetryHelper.ExecuteQueryRetryAsync(_ctx, progress, CancellationToken.None);

            foreach (var list in lists)
            {
                var libNode = new TreeViewItem
                {
                    Header = list.Title,
                    Tag = new FolderNodeInfo(list.Title, string.Empty),
                };
                // Add dummy child for expand arrow
                libNode.Items.Add(new TreeViewItem { Header = "Loading..." });
                libNode.Expanded += LibNode_Expanded;
                FolderTree.Items.Add(libNode);
            }

            StatusText.Text = $"{FolderTree.Items.Count} libraries loaded.";
        }
        catch (Exception ex)
        {
            StatusText.Text = $"Error: {ex.Message}";
        }
    }

    private async void LibNode_Expanded(object sender, RoutedEventArgs e)
    {
        if (sender is not TreeViewItem node || node.Tag is not FolderNodeInfo info)
            return;

        // Only load children once
        if (node.Items.Count == 1 && node.Items[0] is TreeViewItem dummy && dummy.Header?.ToString() == "Loading...")
        {
            node.Items.Clear();
            try
            {
                var folderUrl = string.IsNullOrEmpty(info.FolderPath)
                    ? GetLibraryRootUrl(info.LibraryTitle)
                    : info.FolderPath;

                var folder = _ctx.Web.GetFolderByServerRelativeUrl(folderUrl);
                _ctx.Load(folder, f => f.Folders.Include(sf => sf.Name, sf => sf.ServerRelativeUrl));
                var progress = new Progress<Core.Models.OperationProgress>();
                await ExecuteQueryRetryHelper.ExecuteQueryRetryAsync(_ctx, progress, CancellationToken.None);

                foreach (var subFolder in folder.Folders)
                {
                    if (subFolder.Name.StartsWith("_") || subFolder.Name == "Forms")
                        continue;

                    var childNode = new TreeViewItem
                    {
                        Header = subFolder.Name,
                        Tag = new FolderNodeInfo(info.LibraryTitle, subFolder.ServerRelativeUrl),
                    };
                    childNode.Items.Add(new TreeViewItem { Header = "Loading..." });
                    childNode.Expanded += LibNode_Expanded;
                    node.Items.Add(childNode);
                }
            }
            catch (Exception ex)
            {
                node.Items.Add(new TreeViewItem { Header = $"Error: {ex.Message}" });
            }
        }
    }

    private string GetLibraryRootUrl(string libraryTitle)
    {
        var uri = new Uri(_ctx.Url);
        return $"{uri.AbsolutePath.TrimEnd('/')}/{libraryTitle}";
    }

    private void FolderTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        if (e.NewValue is TreeViewItem node && node.Tag is FolderNodeInfo info)
        {
            SelectedLibrary = info.LibraryTitle;
            SelectedFolderPath = info.FolderPath;
            SelectButton.IsEnabled = true;
        }
    }

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

    private void Cancel_Click(object sender, RoutedEventArgs e)
    {
        DialogResult = false;
        Close();
    }

    private record FolderNodeInfo(string LibraryTitle, string FolderPath);
}
