using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using NetDocsForLLM.Models; using NetDocsForLLM.Services; using Ookii.Dialogs.Wpf; using System; using System.Collections.ObjectModel; using System.IO; using System.Threading.Tasks; using System.Windows; namespace NetDocsForLLM.ViewModels { public class MainViewModel : ObservableObject { private readonly IAssemblyAnalyzer _assemblyAnalyzer; private readonly IDocumentationGenerator _documentationGenerator; private ObservableCollection _selectedAssemblies; private DocumentationModel _documentationModel; private ExportSettings _settings; private string _documentationPreview; private string _documentationStats; private string _statusMessage; private bool _isProcessing; private bool _hasGeneratedDocumentation; public ObservableCollection SelectedAssemblies { get => _selectedAssemblies; set => SetProperty(ref _selectedAssemblies, value); } public DocumentationModel DocumentationModel { get => _documentationModel; set => SetProperty(ref _documentationModel, value); } public ExportSettings Settings { get => _settings; set => SetProperty(ref _settings, value); } public string DocumentationPreview { get => _documentationPreview; set => SetProperty(ref _documentationPreview, value); } public string DocumentationStats { get => _documentationStats; set => SetProperty(ref _documentationStats, value); } public string StatusMessage { get => _statusMessage; set => SetProperty(ref _statusMessage, value); } public bool IsProcessing { get => _isProcessing; set => SetProperty(ref _isProcessing, value); } public bool HasGeneratedDocumentation { get => _hasGeneratedDocumentation; set => SetProperty(ref _hasGeneratedDocumentation, value); } public bool HasSelectedAssemblies => SelectedAssemblies.Count > 0; public IRelayCommand SelectAssembliesCommand { get; } public IRelayCommand RemoveAssemblyCommand { get; } public IRelayCommand GenerateDocumentationCommand { get; } public IRelayCommand CopyToClipboardCommand { get; } public IRelayCommand ExportDocumentationCommand { get; } public MainViewModel(IAssemblyAnalyzer assemblyAnalyzer, IDocumentationGenerator documentationGenerator) { _assemblyAnalyzer = assemblyAnalyzer ?? throw new ArgumentNullException(nameof(assemblyAnalyzer)); _documentationGenerator = documentationGenerator ?? throw new ArgumentNullException(nameof(documentationGenerator)); _selectedAssemblies = new ObservableCollection(); _documentationModel = new DocumentationModel(); _settings = new ExportSettings(); _documentationPreview = string.Empty; _documentationStats = string.Empty; _statusMessage = "Listo"; _isProcessing = false; _hasGeneratedDocumentation = false; SelectAssembliesCommand = new RelayCommand(SelectAssemblies); RemoveAssemblyCommand = new RelayCommand(RemoveAssembly); GenerateDocumentationCommand = new AsyncRelayCommand(GenerateDocumentationAsync); CopyToClipboardCommand = new RelayCommand(CopyToClipboard, () => HasGeneratedDocumentation); ExportDocumentationCommand = new RelayCommand(ExportDocumentation, () => HasGeneratedDocumentation); // Subscribe to collection changes to update HasSelectedAssemblies _selectedAssemblies.CollectionChanged += (sender, e) => { OnPropertyChanged(nameof(HasSelectedAssemblies)); }; } private void SelectAssemblies() { var dialog = new VistaOpenFileDialog { Filter = "Ensamblados .NET (*.dll)|*.dll", Multiselect = true, Title = "Seleccionar librerías .NET" }; if (dialog.ShowDialog() == true) { foreach (var filePath in dialog.FileNames) { try { // Check if the assembly is already selected if (_selectedAssemblies.Count(a => a.FilePath == filePath) > 0) continue; var assembly = _assemblyAnalyzer.LoadAssembly(filePath); if (assembly != null) { SelectedAssemblies.Add(assembly); StatusMessage = $"Librería cargada: {assembly.Name}"; } } catch (Exception ex) { MessageBox.Show($"Error al cargar el ensamblado: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } } } } private void RemoveAssembly(AssemblyModel assembly) { if (assembly != null) { SelectedAssemblies.Remove(assembly); StatusMessage = $"Librería removida: {assembly.Name}"; } } private async Task GenerateDocumentationAsync() { if (SelectedAssemblies.Count == 0) { MessageBox.Show("Por favor, seleccione al menos una librería para generar documentación.", "Sin librerías", MessageBoxButton.OK, MessageBoxImage.Information); return; } try { IsProcessing = true; StatusMessage = "Generando documentación..."; // Generate documentation DocumentationModel = await Task.Run(() => _documentationGenerator.GenerateDocumentation(SelectedAssemblies, Settings)); // Generate preview DocumentationPreview = await Task.Run(() => _documentationGenerator.GenerateDocumentationPreview(DocumentationModel, Settings)); // Update stats var totalTypes = DocumentationModel.Namespaces.Sum(n => n.Types.Count); var totalMembers = DocumentationModel.Namespaces.Sum(n => n.Types.Sum(t => t.Members.Count)); DocumentationStats = $"Resumen: {DocumentationModel.Namespaces.Count} namespaces, " + $"{totalTypes} tipos, {totalMembers} miembros"; HasGeneratedDocumentation = true; StatusMessage = "Documentación generada correctamente"; } catch (Exception ex) { MessageBox.Show($"Error al generar la documentación: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); StatusMessage = "Error al generar documentación"; } finally { IsProcessing = false; } } private void CopyToClipboard() { if (string.IsNullOrEmpty(DocumentationPreview)) return; try { Clipboard.SetText(DocumentationPreview); StatusMessage = "Documentación copiada al portapapeles"; } catch (Exception ex) { MessageBox.Show($"Error al copiar al portapapeles: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } } private void ExportDocumentation() { if (string.IsNullOrEmpty(DocumentationPreview)) return; var dialog = new VistaSaveFileDialog { Filter = Settings.OutputFormat == OutputFormat.Json ? "Archivos JSON (*.json)|*.json" : "Archivos YAML (*.yaml;*.yml)|*.yaml;*.yml", DefaultExt = Settings.OutputFormat == OutputFormat.Json ? ".json" : ".yaml", Title = "Guardar documentación" }; if (dialog.ShowDialog() == true) { try { File.WriteAllText(dialog.FileName, DocumentationPreview); StatusMessage = $"Documentación guardada en: {dialog.FileName}"; } catch (Exception ex) { MessageBox.Show($"Error al guardar el archivo: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } } } } }