using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CtrEditor.Controls;
using CtrEditor.ObjetosSim;
using CtrEditor.Serialization;
using Newtonsoft.Json;
using Ookii.Dialogs.Wpf;

namespace CtrEditor.PopUps
{
    public partial class LibraryWindowViewModel : ObservableObject
    {
        private readonly MainViewModel _mainViewModel;
        private List<osBase> _clipboardObjects = new List<osBase>();

        [ObservableProperty]
        private ObservableCollection<LibraryDirectoryItem> libraryDirectories;

        [ObservableProperty]
        private LibraryDirectoryItem selectedLibraryDirectory;

        [ObservableProperty]
        private ObservableCollection<LibraryItem> libraries;

        [ObservableProperty]
        private LibraryItem selectedLibrary;

        [ObservableProperty]
        private ObservableCollection<ObjectTypeGroup> filteredObjectsByType;

        [ObservableProperty]
        private osBase selectedObject;

        // Nueva propiedad para el TreeView jerárquico
        [ObservableProperty]
        private ObservableCollection<LibraryTreeNode> libraryTreeNodes;

        [ObservableProperty]
        private LibraryTreeNode selectedTreeNode;

        // Nueva propiedad para objetos seleccionados múltiples
        [ObservableProperty]
        private ObservableCollection<SelectableObjectWrapper> selectableObjects;

        // Commands
        public ICommand AddLibraryDirectoryCommand { get; }
        public ICommand RemoveLibraryDirectoryCommand { get; }
        public ICommand CopyObjectCommand { get; }
        public ICommand PasteObjectCommand { get; }
        public ICommand DeleteObjectCommand { get; }
        public ICommand CreateNewLibraryCommand { get; }

        // Nuevos comandos para menú contextual
        public ICommand CreateLibraryInDirectoryCommand { get; }
        public ICommand RemoveDirectoryCommand { get; }

        public LibraryWindowViewModel(MainViewModel mainViewModel)
        {
            _mainViewModel = mainViewModel;

            LibraryDirectories = new ObservableCollection<LibraryDirectoryItem>();
            Libraries = new ObservableCollection<LibraryItem>();
            FilteredObjectsByType = new ObservableCollection<ObjectTypeGroup>();
            LibraryTreeNodes = new ObservableCollection<LibraryTreeNode>();
            SelectableObjects = new ObservableCollection<SelectableObjectWrapper>();

            // Initialize commands
            AddLibraryDirectoryCommand = new RelayCommand(AddLibraryDirectory);
            RemoveLibraryDirectoryCommand = new RelayCommand(RemoveLibraryDirectory, () => SelectedLibraryDirectory != null);
            CopyObjectCommand = new RelayCommand(CopyObject, () => HasSelectedObjects());
            PasteObjectCommand = new RelayCommand(PasteObject, () => SelectedLibrary != null && (HasObjectsAvailableToPaste()));
            DeleteObjectCommand = new RelayCommand(DeleteObject, () => HasSelectedObjects() && SelectedLibrary != null && !SelectedLibrary.IsCurrentProject);
            CreateNewLibraryCommand = new RelayCommand(CreateNewLibrary, () => SelectedLibraryDirectory != null);

            // Nuevos comandos
            CreateLibraryInDirectoryCommand = new RelayCommand(CreateLibraryInDirectory, () => SelectedTreeNode?.IsDirectory == true);
            RemoveDirectoryCommand = new RelayCommand(RemoveDirectory, () => SelectedTreeNode?.IsDirectory == true && !SelectedTreeNode.IsCurrentProject);

            LoadLibraryDirectories();
            RefreshLibraryTree();
        }

        private bool HasSelectedObjects()
        {
            return SelectableObjects?.Any(o => o.IsSelected) == true || SelectedObject != null;
        }

        private bool HasObjectsAvailableToPaste()
        {
            // Verificar si hay objetos en el portapapeles interno o en el portapapeles del sistema
            return _clipboardObjects.Any() ||
                   (System.Windows.Clipboard.ContainsText() && IsValidObjectData(System.Windows.Clipboard.GetText()));
        }

        private bool IsValidObjectData(string text)
        {
            if (string.IsNullOrWhiteSpace(text)) return false;

            try
            {
                text = text.Trim();

                // Validación básica: debe ser JSON que empiece con [ o {
                if (!(text.StartsWith("[") || text.StartsWith("{"))) return false;

                // Intentar parsearlo rápidamente sin deserializar completamente
                var token = Newtonsoft.Json.Linq.JToken.Parse(text);
                return token != null;
            }
            catch
            {
                return false;
            }
        }

        private List<osBase> GetSelectedObjects()
        {
            var selected = new List<osBase>();

            // Primero agregar objetos seleccionados por checkbox
            if (SelectableObjects != null)
            {
                selected.AddRange(SelectableObjects.Where(o => o.IsSelected).Select(o => o.Object));
            }

            // Si no hay objetos con checkbox seleccionados, usar la selección simple
            if (!selected.Any() && SelectedObject != null)
            {
                selected.Add(SelectedObject);
            }

            return selected;
        }

        partial void OnSelectedTreeNodeChanged(LibraryTreeNode value)
        {
            if (value?.IsDirectory == false) // Es una biblioteca
            {
                SelectedLibrary = value.Library;
                LoadObjectsFromLibrary();
            }
            CommandManager.InvalidateRequerySuggested();
        }

        partial void OnSelectedLibraryDirectoryChanged(LibraryDirectoryItem value)
        {
            RefreshLibraries();
            CommandManager.InvalidateRequerySuggested();
        }

        partial void OnSelectedLibraryChanged(LibraryItem value)
        {
            LoadObjectsFromLibrary();
            CommandManager.InvalidateRequerySuggested();
        }

        private osVisFilter _objectFilter;
        public void SetObjectFilter(osVisFilter filter)
        {
            _objectFilter = filter;
            if (SelectedLibrary != null)
            {
                UpdateFilterTypes(filter);
            }
        }

        private void LoadLibraryDirectories()
        {
            LibraryDirectories.Clear();

            // Add current project directory
            LibraryDirectories.Add(new LibraryDirectoryItem
            {
                Path = _mainViewModel.directorioTrabajo,
                DisplayName = $"Proyecto Actual ({_mainViewModel.directorioTrabajo})",
                IsCurrentProject = true
            });

            // Add saved library directories
            foreach (var directory in EstadoPersistente.Instance.LibraryDirectories)
            {
                if (Directory.Exists(directory))
                {
                    LibraryDirectories.Add(new LibraryDirectoryItem
                    {
                        Path = directory,
                        DisplayName = directory, // Show full path instead of just folder name
                        IsCurrentProject = false
                    });
                }
            }

            if (LibraryDirectories.Any())
            {
                SelectedLibraryDirectory = LibraryDirectories.First();
            }
        }

        private void RefreshLibraries()
        {
            Libraries.Clear();

            if (SelectedLibraryDirectory == null) return;

            if (SelectedLibraryDirectory.IsCurrentProject)
            {
                // Add current project as a library
                Libraries.Add(new LibraryItem
                {
                    Name = "Proyecto Actual",
                    FilePath = null,
                    IsCurrentProject = true,
                    Objects = _mainViewModel.ObjetosSimulables.ToList()
                });

                // Add JSON files from current project directory
                AddJsonFilesFromDirectory(SelectedLibraryDirectory.Path);
            }
            else
            {
                // Add JSON files from selected library directory
                AddJsonFilesFromDirectory(SelectedLibraryDirectory.Path);
            }
        }

        private void AddJsonFilesFromDirectory(string directoryPath)
        {
            if (!Directory.Exists(directoryPath)) return;

            var jsonFiles = Directory.GetFiles(directoryPath, "*.json", SearchOption.AllDirectories);

            foreach (var jsonFile in jsonFiles)
            {
                try
                {
                    var relativePath = Path.GetRelativePath(directoryPath, jsonFile);
                    var displayName = Path.GetFileNameWithoutExtension(jsonFile);

                    var libraryItem = new LibraryItem
                    {
                        Name = displayName,
                        FilePath = jsonFile,
                        IsCurrentProject = false,
                        Objects = LoadObjectsFromJsonFile(jsonFile)
                    };

                    Libraries.Add(libraryItem);
                }
                catch (Exception ex)
                {
                    // Log error but continue processing other files
                    System.Diagnostics.Debug.WriteLine($"Error loading library {jsonFile}: {ex.Message}");
                }
            }
        }

        private List<osBase> LoadObjectsFromJsonFile(string filePath)
        {
            var objects = new List<osBase>();

            try
            {
                var settings = new JsonSerializerSettings
                {
                    TypeNameHandling = TypeNameHandling.All,
                    NullValueHandling = NullValueHandling.Ignore
                };

                string json = File.ReadAllText(filePath);

                // Try to detect format: check if it starts with '[' (AllPages.json format) or '{' (normal format)
                json = json.Trim();

                if (json.StartsWith("["))
                {
                    // AllPages.json format: direct array of objects
                    var directObjects = JsonConvert.DeserializeObject<List<osBase>>(json, settings);
                    if (directObjects != null)
                    {
                        objects.AddRange(directObjects);
                    }
                }
                else if (json.StartsWith("{"))
                {
                    // Normal format: SimulationData wrapper
                    var simulationData = JsonConvert.DeserializeObject<SimulationData>(json, settings);
                    if (simulationData?.ObjetosSimulables != null)
                    {
                        objects.AddRange(simulationData.ObjetosSimulables);
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"Error loading objects from {filePath}: {ex.Message}");
            }

            return objects;
        }

        private void LoadObjectsFromLibrary()
        {
            FilteredObjectsByType.Clear();
            SelectableObjects.Clear();

            if (SelectedLibrary == null) return;

            // Crear objetos seleccionables con checkboxes
            foreach (var obj in SelectedLibrary.Objects)
            {
                SelectableObjects.Add(new SelectableObjectWrapper { Object = obj, IsSelected = false });
            }

            // Update filter types and tags when library changes
            if (_objectFilter != null)
            {
                UpdateFilterTypes(_objectFilter);
            }

            ApplyFiltering(SelectedLibrary.Objects);
        }

        public void UpdateFilterTypes(osVisFilter filter)
        {
            if (SelectedLibrary?.Objects != null)
            {
                var types = SelectedLibrary.Objects.Select(o => o.GetType()).Distinct();
                filter.UpdateAvailableTypes(types);
                filter.UpdateAvailableTags(SelectedLibrary.Objects);
            }
        }

        private void ApplyFiltering(List<osBase> objects)
        {
            // Group objects by type
            var groupedObjects = objects
                .GroupBy(obj => obj.GetType())
                .Select(group => new ObjectTypeGroup
                {
                    Type = group.Key,
                    TypeName = GetTypeDisplayName(group.Key),
                    Objects = new ObservableCollection<osBase>(group.ToList())
                })
                .OrderBy(group => group.TypeName)
                .ToList();

            FilteredObjectsByType.Clear();
            foreach (var group in groupedObjects)
            {
                FilteredObjectsByType.Add(group);
            }
        }

        public void OnFilterChanged(osVisFilterViewModel filterViewModel)
        {
            if (SelectedLibrary == null) return;

            var filteredObjects = new List<osBase>();

            foreach (var obj in SelectedLibrary.Objects)
            {
                bool isVisible = true;

                // Apply Show All filter
                if (!filterViewModel.ShowAll)
                {
                    // Check type filter
                    var typeFilter = filterViewModel.TypeFilters.FirstOrDefault(tf => tf.Type == obj.GetType());
                    if (typeFilter == null || !typeFilter.IsSelected)
                    {
                        isVisible = false;
                    }

                    // Check tag filters
                    if (filterViewModel.TagFilters.Any() && filterViewModel.TagFilters.Any(tf => tf.IsSelected))
                    {
                        var selectedTags = filterViewModel.TagFilters.Where(tf => tf.IsSelected).Select(tf => tf.TagName).ToList();
                        bool hasMatchingTag = obj.ListaEtiquetas.Any(tag => selectedTags.Contains(tag));
                        if (!hasMatchingTag)
                        {
                            isVisible = false;
                        }
                    }

                    // Check search tags
                    if (!string.IsNullOrWhiteSpace(filterViewModel.SearchTags))
                    {
                        var searchTags = filterViewModel.SearchTags
                            .Split(' ', StringSplitOptions.RemoveEmptyEntries)
                            .Where(tag => tag.StartsWith("#") && tag.Length > 1)
                            .Select(tag => tag.Substring(1).ToLowerInvariant())
                            .ToList();

                        if (searchTags.Any())
                        {
                            bool hasMatchingSearchTag = searchTags.Any(searchTag => obj.ListaEtiquetas.Contains(searchTag));
                            if (!hasMatchingSearchTag)
                            {
                                isVisible = false;
                            }
                        }
                    }

                    // Check other filters
                    if (filterViewModel.ShowCloned && !obj.Cloned)
                        isVisible = false;

                    if (filterViewModel.ShowAutoCreated && !obj.AutoCreated)
                        isVisible = false;

                    if (filterViewModel.ShowEnableOnAllPages && !obj.Enable_On_All_Pages)
                        isVisible = false;

                    if (filterViewModel.ShowOnThisPage && !obj.Show_On_This_Page)
                        isVisible = false;
                }

                if (isVisible)
                {
                    filteredObjects.Add(obj);
                }
            }

            ApplyFiltering(filteredObjects);
        }

        private string GetTypeDisplayName(Type type)
        {
            try
            {
                var methodInfo = type.GetMethod("NombreClase", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
                return methodInfo != null ? methodInfo.Invoke(null, null)?.ToString() : type.Name;
            }
            catch
            {
                return type.Name;
            }
        }

        private void AddLibraryDirectory()
        {
            var dialog = new VistaFolderBrowserDialog();
            if (dialog.ShowDialog() == true)
            {
                var path = dialog.SelectedPath;
                if (!EstadoPersistente.Instance.LibraryDirectories.Contains(path))
                {
                    EstadoPersistente.Instance.LibraryDirectories.Add(path);
                    EstadoPersistente.Instance.GuardarEstado();
                    LoadLibraryDirectories();
                }
            }
        }

        private void RemoveLibraryDirectory()
        {
            if (SelectedLibraryDirectory != null && !SelectedLibraryDirectory.IsCurrentProject)
            {
                var result = MessageBox.Show(
                    $"¿Está seguro de que desea eliminar el directorio '{SelectedLibraryDirectory.DisplayName}' de la lista de bibliotecas?",
                    "Confirmar eliminación",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Question);

                if (result == MessageBoxResult.Yes)
                {
                    EstadoPersistente.Instance.LibraryDirectories.Remove(SelectedLibraryDirectory.Path);
                    EstadoPersistente.Instance.GuardarEstado();
                    LoadLibraryDirectories();
                }
            }
        }

        private void CopyObject()
        {
            var objectsToCopy = GetSelectedObjects();
            if (objectsToCopy.Any())
            {
                try
                {
                    // Usar el mismo sistema de portapapeles que MainWindow
                    // Crear copias usando la misma lógica que DuplicarObjeto
                    var objectsCopy = new List<osBase>();

                    var settings = new JsonSerializerSettings
                    {
                        Formatting = Formatting.Indented,
                        NullValueHandling = NullValueHandling.Ignore,
                        TypeNameHandling = TypeNameHandling.All
                    };

                    foreach (var obj in objectsToCopy)
                    {
                        // Prepare object for serialization
                        obj.SalvarDatosNoSerializables();

                        // Serialize and deserialize to create a deep copy (same as DuplicarObjeto)
                        var serializedData = JsonConvert.SerializeObject(obj, settings);
                        var copiedObject = JsonConvert.DeserializeObject<osBase>(serializedData, settings);

                        if (copiedObject != null)
                        {
                            objectsCopy.Add(copiedObject);
                        }

                        // Restore object state
                        obj.RestaurarDatosNoSerializables();
                    }

                    // Copiar al portapapeles del sistema usando el mismo formato que MainWindow
                    string jsonString = JsonConvert.SerializeObject(objectsCopy, settings);
                    System.Windows.Clipboard.SetText(jsonString);

                    MessageBox.Show($"{objectsCopy.Count} objeto(s) copiado(s) al portapapeles del sistema.", "Información", MessageBoxButton.OK, MessageBoxImage.Information);
                    CommandManager.InvalidateRequerySuggested();
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Error al copiar objeto(s): {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        private void PasteObject()
        {
            if (SelectedLibrary != null)
            {
                try
                {
                    List<osBase> objectsToPaste = new List<osBase>();

                    // Si hay objetos en el portapapeles interno (modo anterior)
                    if (_clipboardObjects.Any())
                    {
                        objectsToPaste = _clipboardObjects.ToList();
                    }
                    // Si no, intentar usar el portapapeles del sistema
                    else if (System.Windows.Clipboard.ContainsText())
                    {
                        string jsonString = System.Windows.Clipboard.GetText();

                        if (!string.IsNullOrWhiteSpace(jsonString))
                        {
                            var settings = new JsonSerializerSettings
                            {
                                TypeNameHandling = TypeNameHandling.All,
                                NullValueHandling = NullValueHandling.Ignore,
                                ObjectCreationHandling = ObjectCreationHandling.Replace,
                                ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
                            };

                            // Intentar deserializar como lista de objetos
                            try
                            {
                                objectsToPaste = JsonConvert.DeserializeObject<List<osBase>>(jsonString, settings);
                            }
                            catch
                            {
                                // Si falla, intentar como objeto individual
                                try
                                {
                                    var singleObject = JsonConvert.DeserializeObject<osBase>(jsonString, settings);
                                    if (singleObject != null)
                                    {
                                        objectsToPaste = new List<osBase> { singleObject };
                                    }
                                }
                                catch
                                {
                                    MessageBox.Show("No se pudo deserializar el contenido del portapapeles como objetos válidos.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
                                    return;
                                }
                            }
                        }
                    }

                    if (!objectsToPaste.Any())
                    {
                        MessageBox.Show("No hay objetos para pegar.", "Información", MessageBoxButton.OK, MessageBoxImage.Information);
                        return;
                    }

                    foreach (var objToPaste in objectsToPaste)
                    {
                        // Create a new unique ID for the pasted object
                        objToPaste.Id.ObtenerNuevaID();

                        // Update name to include ID
                        string nombre = Regex.IsMatch(objToPaste.Nombre, @"_\d+$")
                            ? Regex.Replace(objToPaste.Nombre, @"_\d+$", $"_{objToPaste.Id.Value}")
                            : objToPaste.Nombre + "_" + objToPaste.Id.Value;
                        objToPaste.Nombre = nombre;

                        if (SelectedLibrary.IsCurrentProject)
                        {
                            // Add to current project
                            _mainViewModel.ObjetosSimulables.Add(objToPaste);
                            _mainViewModel.CrearUserControlDesdeObjetoSimulable(objToPaste);
                            _mainViewModel.HasUnsavedChanges = true;
                        }
                        else
                        {
                            // Add to selected library file
                            SelectedLibrary.Objects.Add(objToPaste);
                            SaveLibraryToFile(SelectedLibrary);
                        }
                    }

                    // Si se pegó en el proyecto actual, recargar la imagen actual
                    if (SelectedLibrary.IsCurrentProject)
                    {
                        ReloadCurrentImage();
                    }

                    RefreshLibraries();
                    LoadObjectsFromLibrary();
                    MessageBox.Show($"{objectsToPaste.Count} objeto(s) pegado(s).", "Información", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Error al pegar objeto: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        // Método para recargar la imagen actual después de pegar en el proyecto actual
        private void ReloadCurrentImage()
        {
            try
            {
                // Forzar recarga de la imagen actual para reflejar los cambios
                var currentImage = _mainViewModel.SelectedImage;
                if (!string.IsNullOrEmpty(currentImage))
                {
                    // Temporalmente cambiar a null y luego restaurar para forzar la recarga
                    _mainViewModel.SelectedImage = null;
                    _mainViewModel.SelectedImage = currentImage;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"Error al recargar imagen actual: {ex.Message}");
            }
        }

        private void DeleteObject()
        {
            var objectsToDelete = GetSelectedObjects();
            if (objectsToDelete.Any() && SelectedLibrary != null && !SelectedLibrary.IsCurrentProject)
            {
                var message = objectsToDelete.Count == 1
                    ? $"¿Está seguro de que desea eliminar el objeto '{objectsToDelete.First().Nombre}'?"
                    : $"¿Está seguro de que desea eliminar {objectsToDelete.Count} objetos?";

                var result = MessageBox.Show(message, "Confirmar eliminación", MessageBoxButton.YesNo, MessageBoxImage.Question);

                if (result == MessageBoxResult.Yes)
                {
                    try
                    {
                        foreach (var obj in objectsToDelete)
                        {
                            SelectedLibrary.Objects.Remove(obj);
                        }

                        SaveLibraryToFile(SelectedLibrary);
                        LoadObjectsFromLibrary();
                        SelectedObject = null;

                        var successMessage = objectsToDelete.Count == 1
                            ? "Objeto eliminado."
                            : $"{objectsToDelete.Count} objetos eliminados.";

                        MessageBox.Show(successMessage, "Información", MessageBoxButton.OK, MessageBoxImage.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"Error al eliminar objeto(s): {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
            }
        }

        private void CreateNewLibrary()
        {
            if (SelectedLibraryDirectory == null) return;

            var dialog = new Microsoft.Win32.SaveFileDialog
            {
                DefaultExt = ".json",
                Filter = "JSON files (*.json)|*.json",
                InitialDirectory = SelectedLibraryDirectory.Path,
                Title = "Crear nueva biblioteca"
            };

            if (dialog.ShowDialog() == true)
            {
                try
                {
                    var emptyLibrary = new SimulationData
                    {
                        ObjetosSimulables = new ObservableCollection<osBase>(),
                        UnitConverter = PixelToMeter.Instance.calc,
                        PLC_ConnectionData = new LibS7Adv.PLCViewModel()
                    };

                    var settings = new JsonSerializerSettings
                    {
                        Formatting = Formatting.Indented,
                        NullValueHandling = NullValueHandling.Ignore,
                        TypeNameHandling = TypeNameHandling.All
                    };

                    string json = JsonConvert.SerializeObject(emptyLibrary, settings);
                    File.WriteAllText(dialog.FileName, json);

                    RefreshLibraries();
                    MessageBox.Show("Nueva biblioteca creada.", "Información", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Error al crear biblioteca: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        private void SaveLibraryToFile(LibraryItem library)
        {
            if (library.IsCurrentProject || string.IsNullOrEmpty(library.FilePath)) return;

            try
            {
                var settings = new JsonSerializerSettings
                {
                    Formatting = Formatting.Indented,
                    NullValueHandling = NullValueHandling.Ignore,
                    TypeNameHandling = TypeNameHandling.All
                };

                string json;

                // Detectar si es formato AllPages.json basándose en el nombre del archivo
                var fileName = Path.GetFileName(library.FilePath).ToLowerInvariant();
                bool isAllPagesFormat = fileName.Contains("allpages") || fileName.StartsWith("allpages");

                if (isAllPagesFormat)
                {
                    // Formato AllPages.json: guardar como array directo de objetos
                    json = JsonConvert.SerializeObject(library.Objects, settings);
                }
                else
                {
                    // Formato normal: guardar con wrapper SimulationData
                    var simulationData = new SimulationData
                    {
                        ObjetosSimulables = new ObservableCollection<osBase>(library.Objects),
                        UnitConverter = PixelToMeter.Instance.calc,
                        PLC_ConnectionData = new LibS7Adv.PLCViewModel()
                    };
                    json = JsonConvert.SerializeObject(simulationData, settings);
                }

                File.WriteAllText(library.FilePath, json);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error al guardar biblioteca: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void RefreshLibraryTree()
        {
            LibraryTreeNodes.Clear();

            foreach (var directory in LibraryDirectories)
            {
                var directoryNode = new LibraryTreeNode
                {
                    DisplayName = directory.DisplayName,
                    IsDirectory = true,
                    IsCurrentProject = directory.IsCurrentProject,
                    DirectoryPath = directory.Path,
                    Children = new ObservableCollection<LibraryTreeNode>()
                };

                // Agregar bibliotecas como hijos del directorio
                if (directory.IsCurrentProject)
                {
                    // Agregar proyecto actual
                    directoryNode.Children.Add(new LibraryTreeNode
                    {
                        DisplayName = "Proyecto Actual",
                        IsDirectory = false,
                        Library = new LibraryItem
                        {
                            Name = "Proyecto Actual",
                            IsCurrentProject = true,
                            Objects = _mainViewModel.ObjetosSimulables.ToList()
                        }
                    });
                }

                // Agregar archivos JSON
                if (Directory.Exists(directory.Path))
                {
                    var jsonFiles = Directory.GetFiles(directory.Path, "*.json", SearchOption.AllDirectories);
                    foreach (var jsonFile in jsonFiles)
                    {
                        try
                        {
                            var displayName = Path.GetFileNameWithoutExtension(jsonFile);
                            directoryNode.Children.Add(new LibraryTreeNode
                            {
                                DisplayName = displayName,
                                IsDirectory = false,
                                Library = new LibraryItem
                                {
                                    Name = displayName,
                                    FilePath = jsonFile,
                                    IsCurrentProject = false,
                                    Objects = LoadObjectsFromJsonFile(jsonFile)
                                }
                            });
                        }
                        catch
                        {
                            // Ignorar archivos que no se pueden cargar
                        }
                    }
                }

                LibraryTreeNodes.Add(directoryNode);
            }
        }

        private void CreateLibraryInDirectory()
        {
            if (SelectedTreeNode?.IsDirectory != true) return;

            var oldSelectedDirectory = SelectedLibraryDirectory;

            // Temporalmente cambiar el directorio seleccionado
            SelectedLibraryDirectory = LibraryDirectories.FirstOrDefault(d => d.Path == SelectedTreeNode.DirectoryPath);
            CreateNewLibrary();
            RefreshLibraryTree();

            // Restaurar el directorio seleccionado
            SelectedLibraryDirectory = oldSelectedDirectory;
        }

        private void RemoveDirectory()
        {
            if (SelectedTreeNode?.IsDirectory != true || SelectedTreeNode.IsCurrentProject) return;

            var result = MessageBox.Show($"¿Eliminar el directorio '{SelectedTreeNode.DisplayName}' de la lista de bibliotecas?",
                "Confirmar eliminación", MessageBoxButton.YesNo, MessageBoxImage.Question);

            if (result == MessageBoxResult.Yes)
            {
                EstadoPersistente.Instance.LibraryDirectories.Remove(SelectedTreeNode.DirectoryPath);
                EstadoPersistente.Instance.GuardarEstado();
                LoadLibraryDirectories();
                RefreshLibraryTree();
            }
        }


    }



    // Support classes
    public class LibraryDirectoryItem
    {
        public string Path { get; set; }
        public string DisplayName { get; set; }
        public bool IsCurrentProject { get; set; }
    }

    public class LibraryItem
    {
        public string Name { get; set; }
        public string FilePath { get; set; }
        public bool IsCurrentProject { get; set; }
        public List<osBase> Objects { get; set; } = new List<osBase>();
        public string DisplayName => IsCurrentProject ? $"{Name} (Proyecto)" : Name;
    }

    public class ObjectTypeGroup
    {
        public Type Type { get; set; }
        public string TypeName { get; set; }
        public ObservableCollection<osBase> Objects { get; set; } = new ObservableCollection<osBase>();
    }
}