using System.Collections.ObjectModel; using System.Windows; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Messaging; using Microsoft.Extensions.Logging; using SharepointToolbox.Core.Messages; using SharepointToolbox.Core.Models; using SharepointToolbox.Services; namespace SharepointToolbox.ViewModels; public partial class MainWindowViewModel : ObservableRecipient { private readonly ProfileService _profileService; private readonly SessionManager _sessionManager; private readonly ILogger _logger; // Set by the view layer (MainWindow.xaml.cs) to open the dialog using DI public Func? OpenProfileManagementDialog { get; set; } [ObservableProperty] private TenantProfile? _selectedProfile; [ObservableProperty] private string _connectionStatus = "Not connected"; [ObservableProperty] private string _progressStatus = string.Empty; [ObservableProperty] private int _progressPercentage; public ObservableCollection TenantProfiles { get; } = new(); public IAsyncRelayCommand ConnectCommand { get; } public IAsyncRelayCommand ClearSessionCommand { get; } public RelayCommand ManageProfilesCommand { get; } public MainWindowViewModel( ProfileService profileService, SessionManager sessionManager, ILogger logger) { _profileService = profileService; _sessionManager = sessionManager; _logger = logger; ConnectCommand = new AsyncRelayCommand(ConnectAsync, () => SelectedProfile != null); ClearSessionCommand = new AsyncRelayCommand(ClearSessionAsync, () => SelectedProfile != null); ManageProfilesCommand = new RelayCommand(OpenProfileManagement); IsActive = true; } protected override void OnActivated() { base.OnActivated(); Messenger.Register(this, (r, m) => { var vm = (MainWindowViewModel)r; vm.ProgressStatus = m.Value.Message; vm.ProgressPercentage = m.Value.Total > 0 ? (int)(100.0 * m.Value.Current / m.Value.Total) : 0; }); } partial void OnSelectedProfileChanged(TenantProfile? value) { if (value != null) { WeakReferenceMessenger.Default.Send(new TenantSwitchedMessage(value)); } ConnectCommand.NotifyCanExecuteChanged(); ClearSessionCommand.NotifyCanExecuteChanged(); } public async Task LoadProfilesAsync() { try { var profiles = await _profileService.GetProfilesAsync(); TenantProfiles.Clear(); foreach (var profile in profiles) TenantProfiles.Add(profile); if (TenantProfiles.Count > 0) SelectedProfile = TenantProfiles[0]; } catch (Exception ex) { _logger.LogError(ex, "Failed to load tenant profiles."); } } private async Task ConnectAsync() { if (SelectedProfile == null) return; try { ConnectionStatus = "Connecting..."; await _sessionManager.GetOrCreateContextAsync(SelectedProfile, CancellationToken.None); ConnectionStatus = SelectedProfile.Name; } catch (Exception ex) { ConnectionStatus = "Connection failed"; _logger.LogError(ex, "Failed to connect to tenant {TenantUrl}.", SelectedProfile.TenantUrl); } } private async Task ClearSessionAsync() { if (SelectedProfile == null) return; try { await _sessionManager.ClearSessionAsync(SelectedProfile.TenantUrl); ConnectionStatus = "Not connected"; } catch (Exception ex) { _logger.LogError(ex, "Failed to clear session for {TenantUrl}.", SelectedProfile.TenantUrl); } } private void OpenProfileManagement() { if (OpenProfileManagementDialog == null) return; var dialog = OpenProfileManagementDialog(); dialog.Owner = Application.Current.MainWindow; dialog.ShowDialog(); // Reload profiles after dialog closes (modal — ShowDialog blocks until closed) _ = LoadProfilesAsync(); } }