using CtrEditor.FuncionesBase;
using CtrEditor.ObjetosSim;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using Color = System.Windows.Media.Color;

namespace CtrEditor
{
    public enum AlignmentType
    {
        Left,
        Right,
        Top,
        Bottom,
        CenterHorizontally,
        CenterVertically,
        DistributeHorizontally,
        DistributeVertically,
        EqualWidth,
        EqualHeight,
        EqualAngle,
        JoinHorizontally,
        JoinVertically
    }

    public class ObjectManipulationManager
    {
        private enum ResizeMode
        {
            None,
            Move,
            Rotate,
            ResizeWidth,
            ResizeHeight,
            ResizeBoth
        }

        private enum HandleMode
        {
            None,
            Move,
            ResizeWidth,
            ResizeHeight,
            ResizeBoth,
            Rotate
        }

        private ResizeMode _currentResizeMode;
        private readonly MainWindow _mainWindow;
        private readonly Canvas _canvas;
        private Point _lastMousePosition;
        private bool _isDrawingCanvas = false;
        private bool _isDraggingUserControl = false;
        private bool _isMovingUserControl = false;
        private UserControl _currentDraggingControl;
        private Point _startPointUserControl;
        private Point _transformedBoundingBoxCenter;
        private float _lastAngle;
        private List<Rectangle> _resizeRectangles = new List<Rectangle>();
        private List<Rectangle> _highlightRectangles = new List<Rectangle>();
        private System.Threading.Timer _timerRemoveHighlight = null;
        private Rectangle _currentDraggingRectangle;
        private dataDebug _dataDebug = new dataDebug();
        private ObservableCollection<osBase> _selectedObjects = new ObservableCollection<osBase>();
        private List<Rectangle> _selectionHighlightRectangles = new List<Rectangle>();  // Add this line
        private List<(UserControl Control, Rectangle Highlight)> _selectionHighlightPairs = new List<(UserControl, Rectangle)>();
        private Point _rectangleStart;
        public Rectangle _selectionRectangle;  // Cambiado a private
        private ScrollViewer _scrollViewer;  // Add this line
        private Image _backgroundImage;      // Add this line
        internal bool IsDraggingCanvas { get; set; }
        private bool _isRectangleSelectionActive;
        public bool IsRectangleSelectionActive
        {
            get => _isRectangleSelectionActive;
            set
            {
                _isRectangleSelectionActive = value;
                if (value)
                {
                    // Al activar la selección por rectángulo, desactivar el panning
                    IsDraggingCanvas = false;
                }
            }
        }

        // Propiedad pública para verificar si hay un rectángulo de selección activo
        public bool HasActiveSelectionRectangle => _selectionRectangle != null;

        public ObjectManipulationManager(MainWindow mainWindow, Canvas canvas)
        {
            _mainWindow = mainWindow;
            _canvas = canvas;
            _scrollViewer = mainWindow.ImagenEnTrabajoScrollViewer;  // Add this line
            _backgroundImage = mainWindow.ImagenDeFondo;             // Add this line
        }

        private void PurgeDeletedObjects()
        {
            var deletedObjects = _selectedObjects.Where(obj => 
                obj.VisualRepresentation == null || 
                !_canvas.Children.Contains(obj.VisualRepresentation)).ToList();

            foreach (var obj in deletedObjects)
            {
                DeselectObject(obj);
            }
        }

        public ObservableCollection<osBase> SelectedObjects
        {
            get
            {
                PurgeDeletedObjects();
                return _selectedObjects;
            }
            private set
            {
                _selectedObjects = value;
                UpdateSelectionVisuals();
            }
        }

        public void UpdateSelectionVisuals()
        {
            PurgeDeletedObjects();
            // Asegurarse de que el canvas haya actualizado su layout
            _canvas.UpdateLayout();
            
            RemoveResizeRectangles();
            if (_selectedObjects.Any())
            {
                AddResizeRectangles(_selectedObjects);
                UpdateSelectionHighlights();
            }
        }

        public void SuscribirEventos(UserControl userControl)
        {
            userControl.MouseEnter += UserControl_MouseEnter;
            userControl.MouseLeave += UserControl_MouseLeave;
            userControl.Cursor = Cursors.Hand;

            userControl.MouseLeftButtonDown += UserControl_MouseLeftButtonDown;
            userControl.MouseLeftButtonUp += UserControl_MouseLeftButtonUp;
            userControl.MouseMove += UserControl_MouseMove;
        }

        private void UserControl_MouseEnter(object sender, MouseEventArgs e)
        {
            if (sender is UserControl userControl && userControl is IDataContainer dataContainer)
            {
                dataContainer.Highlight(true);

                if (_mainWindow.DataContext is MainViewModel viewModel)
                {
                    var selectedObject = viewModel.SelectedItemOsList;

                    if (selectedObject?.VisualRepresentation != userControl)
                    {
                        AddHighlightRectangles(userControl);
                    }
                }
            }
        }

        private void UserControl_MouseLeave(object sender, MouseEventArgs e)
        {
            if (sender is UserControl userControl && userControl is IDataContainer dataContainer)
                dataContainer.Highlight(false);
        }

        public void AddResizeRectangles(IEnumerable<osBase> selectedObjects)
        {
            double rectHighlightSize = 1;
            RemoveResizeRectangles();

            // Calcular el bounding box que contenga todos los objetos seleccionados
            Rect boundingBox = CalculateTotalBoundingBox(selectedObjects);

            FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(boundingBox);
            rectBox.Left -= (float)rectHighlightSize;
            rectBox.Right += (float)rectHighlightSize;
            rectBox.Top -= (float)rectHighlightSize;
            rectBox.Bottom += (float)rectHighlightSize;

            _transformedBoundingBoxCenter = new Point(
                boundingBox.Left + boundingBox.Width / 2,
                boundingBox.Top + boundingBox.Height / 2
            );

            // Selection rectangle
            Rectangle selectionRect = CreateSelectionRectangle(rectBox, rectHighlightSize);
            _resizeRectangles.Add(selectionRect);
            _canvas.Children.Add(selectionRect);

            // Load rotation cursors
            Cursor rotationCursorRx = new Cursor(Application.GetResourceStream(
                new Uri("pack://application:,,,/CtrEditor;component/Icons/rotationRx.cur")).Stream);
            Cursor rotationCursorSx = new Cursor(Application.GetResourceStream(
                new Uri("pack://application:,,,/CtrEditor;component/Icons/rotationSx.cur")).Stream);

            // Add resize/rotation handles
            AddResizeHandles(rectBox, 10, rotationCursorRx, rotationCursorSx);
        }

        private Rect CalculateTotalBoundingBox(IEnumerable<osBase> selectedObjects)
        {
            double left = double.MaxValue;
            double top = double.MaxValue;
            double right = double.MinValue;
            double bottom = double.MinValue;

            foreach (var obj in selectedObjects)
            {
                if (obj.VisualRepresentation != null && obj.Show_On_This_Page)
                {
                    // Obtener el bounding box del objeto actual
                    Rect objectBounds = VisualTreeHelper.GetDescendantBounds(obj.VisualRepresentation);
                    GeneralTransform transform = obj.VisualRepresentation.TransformToAncestor(_canvas);
                    Rect transformedBounds = transform.TransformBounds(objectBounds);

                    // Actualizar los límites del bounding box total
                    left = Math.Min(left, transformedBounds.Left);
                    top = Math.Min(top, transformedBounds.Top);
                    right = Math.Max(right, transformedBounds.Right);
                    bottom = Math.Max(bottom, transformedBounds.Bottom);
                }
            }

            return new Rect(
                new Point(left, top),
                new Point(right, bottom)
            );
        }

        private Rectangle CreateSelectionRectangle(FuncionesBase.MutableRect rectBox, double rectHighlightSize)
        {
            var rect = new Rectangle
            {
                Width = rectBox.Width + (rectHighlightSize * 2),
                Height = rectBox.Height + (rectHighlightSize * 2),
                Fill = Brushes.Transparent,
                Stroke = new SolidColorBrush(Color.FromArgb(180, 0, 120, 215)),
                StrokeThickness = 1.5,
                Tag = "Selection",
                IsHitTestVisible = false,
                StrokeDashArray = new DoubleCollection(new double[] { 3, 3 })
            };

            Canvas.SetLeft(rect, rectBox.Left - rectHighlightSize);
            Canvas.SetTop(rect, rectBox.Top - rectHighlightSize);
            Canvas.SetZIndex(rect, ((int)ZIndexEnum.RectangulosPropiead - 1));

            return rect;
        }

        private void AddResizeHandles(FuncionesBase.MutableRect rectBox, double rectSize,
            Cursor rotationCursorRx, Cursor rotationCursorSx)
        {
            var positions = new List<(Point Position, string Tag, Cursor Cursor, Brush Stroke)>
            {
                (new Point(rectBox.Left, rectBox.Top), "TopLeft", Cursors.Arrow, Brushes.Gray),
                (new Point(rectBox.Right, rectBox.Top), "TopRight", rotationCursorRx, Brushes.Red),
                (new Point(rectBox.Left, rectBox.Bottom), "BottomLeft", rotationCursorSx, Brushes.DarkRed),
                (new Point(rectBox.Right, rectBox.Bottom), "BottomRight", Cursors.SizeNWSE, Brushes.Blue),
                (new Point(rectBox.Left + rectBox.Width / 2, rectBox.Top), "TopCenter", Cursors.Arrow, Brushes.Gray),
                (new Point(rectBox.Left + rectBox.Width / 2, rectBox.Bottom), "BottomCenter", Cursors.SizeNS, Brushes.Blue),
                (new Point(rectBox.Left, rectBox.Top + rectBox.Height / 2), "CenterLeft", rotationCursorRx, Brushes.Red),
                (new Point(rectBox.Right, rectBox.Top + rectBox.Height / 2), "CenterRight", Cursors.SizeWE, Brushes.Blue)
            };

            foreach (var (Position, Tag, Cursor, Stroke) in positions)
            {
                var handle = CreateResizeHandle(rectSize, Tag, Cursor, Stroke);
                SetHandlePosition(handle, Position, rectSize);
                _resizeRectangles.Add(handle);
                _canvas.Children.Add(handle);
            }
        }

        private Rectangle CreateResizeHandle(double rectSize, string tag, Cursor cursor, Brush stroke)
        {
            var handle = new Rectangle
            {
                Width = rectSize,
                Height = rectSize,
                Fill = Brushes.Transparent,
                Stroke = stroke,
                StrokeThickness = 1,
                Tag = tag,
                Cursor = cursor
            };

            handle.MouseLeftButtonDown += UserControl_MouseLeftButtonDown;
            handle.MouseMove += UserControl_MouseMove;
            handle.MouseLeftButtonUp += UserControl_MouseLeftButtonUp;
            handle.MouseLeave += ResizeRectangle_MouseLeave;

            Canvas.SetZIndex(handle, (int)ZIndexEnum.RectangulosPropiead);
            return handle;
        }

        private void SetHandlePosition(Rectangle handle, Point position, double rectSize)
        {
            if (!double.IsInfinity(position.X) && !double.IsNaN(position.X))
                Canvas.SetLeft(handle, position.X - rectSize / 2);
            if (!double.IsInfinity(position.Y) && !double.IsNaN(position.Y))
                Canvas.SetTop(handle, position.Y - rectSize / 2);
        }

        public void RemoveResizeRectangles()
        {
            if (_resizeRectangles == null || _resizeRectangles.Count == 0)
                return;

            foreach (var rect in _resizeRectangles)
            {
                _canvas.Children.Remove(rect);
            }
            _resizeRectangles.Clear();
        }

        public void MakeResizeRectanglesTransparent()
        {
            if (_resizeRectangles == null || _resizeRectangles.Count == 0)
                return;

            foreach (var rect in _resizeRectangles)
            {
                rect.Opacity = 0;
            }
        }

        public void MakeResizeRectanglesNormal()
        {
            if (_resizeRectangles == null || _resizeRectangles.Count == 0)
                return;

            foreach (var rect in _resizeRectangles)
            {
                rect.Opacity = 1;
            }
        }

        private void HandleObjectSelection(UserControl userControl, osBase datos)
        {
            PurgeDeletedObjects();
            var viewModel = _mainWindow.DataContext as MainViewModel;
            if (viewModel == null) return;

            bool isControlPressed = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl);

            if (viewModel.IsMultiSelectionActive)
            {
                if (isControlPressed)
                {
                    // Deseleccionar objeto si está presionada la tecla Ctrl
                    if (_selectedObjects.Contains(datos))
                    {
                        DeselectObject(datos);
                    }
                }
                else if (!_selectedObjects.Contains(datos))
                {
                    // Seleccionar objeto si no está ya seleccionado
                    SelectObject(datos);
                }
            }
            else
            {
                // Modo selección única
                ClearSelection();
                SelectObject(datos);
            }

            viewModel.SelectedItemOsList = datos;
            UpdateSelectionVisuals();
        }

        public void SelectObject(osBase obj)
        {
            if (!_selectedObjects.Contains(obj))
            {
                _selectedObjects.Add(obj);
                obj.IsSelected = true;
                if (_mainWindow.DataContext is MainViewModel viewModel && viewModel.IsMultiSelectionActive)
                {
                    AddSelectionHighlight(obj.VisualRepresentation);
                }
            }
        }

        public void DeselectObject(osBase obj)
        {
            if (_selectedObjects.Contains(obj))
            {
                _selectedObjects.Remove(obj);
                obj.IsSelected = false;
                RemoveSelectionHighlight(obj.VisualRepresentation);
            }
        }

        public void ClearSelection()
        {
            foreach (var obj in _selectedObjects.ToList())
            {
                DeselectObject(obj);
            }
            RemoveAllSelectionHighlights();
            RemoveResizeRectangles();

            if (_mainWindow.DataContext is MainViewModel viewModel)
            {
                viewModel.SelectedItemOsList = null;
            }
        }

        public void OnMultiSelectionModeChanged(bool isActive)
        {
            if (!isActive)
            {
                // Mantener solo el último objeto seleccionado
                if (_selectedObjects.Count > 1)
                {
                    var lastSelected = _selectedObjects.Last();
                    ClearSelection();
                    SelectObject(lastSelected);
                }
                RemoveAllSelectionHighlights();
            }
            else
            {
                UpdateAllSelectionHighlights();
            }
        }

        private void AddSelectionHighlight(UserControl userControl, bool isReference = false)
        {
            if (userControl == null) return;

            RemoveSelectionHighlight(userControl);

            Rect boundingBox = VisualTreeHelper.GetDescendantBounds(userControl);
            GeneralTransform transform = userControl.TransformToAncestor(_canvas);
            Rect transformedBoundingBox = transform.TransformBounds(boundingBox);

            Rectangle highlightRect = new Rectangle
            {
                Width = transformedBoundingBox.Width,
                Height = transformedBoundingBox.Height,
                Fill = Brushes.Transparent,
                Stroke = new SolidColorBrush(isReference ? 
                    Color.FromArgb(180, 128, 0, 128) :  // Purple for reference
                    Color.FromArgb(180, 255, 0, 0)),    // Red for others
                StrokeThickness = isReference ? 3 : 2,  // Más grueso para el de referencia
                Tag = "SelectionHighlight",
                IsHitTestVisible = false
            };

            Canvas.SetLeft(highlightRect, transformedBoundingBox.Left);
            Canvas.SetTop(highlightRect, transformedBoundingBox.Top);
            Canvas.SetZIndex(highlightRect, (int)ZIndexEnum.RectangulosPropiead - 1);

            _selectionHighlightPairs.Add((userControl, highlightRect));
            _canvas.Children.Add(highlightRect);
        }

        private void RemoveSelectionHighlight(UserControl userControl)
        {
            var pairsToRemove = _selectionHighlightPairs.Where(p => p.Control == userControl).ToList();
            foreach (var pair in pairsToRemove)
            {
                _canvas.Children.Remove(pair.Highlight);
                _selectionHighlightPairs.Remove(pair);
            }
        }

        private void RemoveAllSelectionHighlights()
        {
            foreach (var pair in _selectionHighlightPairs)
            {
                _canvas.Children.Remove(pair.Highlight);
            }
            _selectionHighlightPairs.Clear();
        }

        private void UpdateAllSelectionHighlights()
        {
            if (_mainWindow.DataContext is MainViewModel viewModel && viewModel.IsMultiSelectionActive)
            {
                RemoveAllSelectionHighlights();
                bool isFirst = true;
                foreach (var selectedObject in _selectedObjects)
                {
                    if (selectedObject.VisualRepresentation != null)
                    {
                        AddSelectionHighlight(selectedObject.VisualRepresentation, isFirst);
                        isFirst = false;
                    }
                }
            }
        }

        private void UpdateSelectionHighlights()
        {
            UpdateAllSelectionHighlights();
        }

        private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!_isDrawingCanvas)
            {
                if (_resizeRectangles != null && _resizeRectangles.Contains(sender))
                {
                    _currentDraggingRectangle = sender as Rectangle;
                    _lastMousePosition = e.GetPosition(_canvas);
                    _currentDraggingRectangle.CaptureMouse();
                    _isMovingUserControl = true;
                    _startPointUserControl = e.GetPosition(_canvas);
                    e.Handled = true;
                    return;
                }

                var userControl = sender as UserControl;
                if (userControl != null)
                {
                    if (userControl.DataContext is osBase datos)
                    {
                        HandleObjectSelection(userControl, datos);
                    }

                    // Solo iniciar el arrastre si no se presionó Ctrl
                    if (!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
                    {
                        userControl.CaptureMouse();
                        _currentDraggingControl = userControl;
                        _isMovingUserControl = true;
                        InitializeDrag(e);
                    }
                }
            }
        }

        private void InitializeDrag(MouseButtonEventArgs e)
        {
            _isDraggingUserControl = true;
            _startPointUserControl = e.GetPosition(_canvas);
        }

        private void UserControl_MouseMove(object sender, MouseEventArgs e)
        {
            if (_isMovingUserControl)
            {
                var currentPosition = e.GetPosition(_canvas);
                MakeResizeRectanglesTransparent();

                if (_isDraggingUserControl)
                {
                    HandleDrag(currentPosition);
                }
                else if (_currentDraggingRectangle != null)
                {
                    string resizeDirection = _currentDraggingRectangle.Tag as string;
                    if (resizeDirection != null)
                    {
                        var mode = DetermineHandleMode(resizeDirection);
                        switch (mode)
                        {
                            case HandleMode.Rotate:
                                HandleRotation(currentPosition);
                                break;
                            case HandleMode.ResizeWidth:
                            case HandleMode.ResizeHeight:
                            case HandleMode.ResizeBoth:
                                HandleResize(currentPosition, mode);
                                break;
                        }
                    }
                }
            }
        }

        private void HandleDrag(Point currentPosition)
        {
            PurgeDeletedObjects();
            var dx = currentPosition.X - _startPointUserControl.X;
            var dy = currentPosition.Y - _startPointUserControl.Y;

            RemoveAllSelectionHighlights(); // Remover antes de mover

            foreach (var selectedObject in _selectedObjects)
            {
                var newX = Canvas.GetLeft(selectedObject.VisualRepresentation) + dx;
                var newY = Canvas.GetTop(selectedObject.VisualRepresentation) + dy;
                selectedObject.Move((float)newX, (float)newY);
            }
            _startPointUserControl = currentPosition;

            UpdateAllSelectionHighlights();
        }

        private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (_isMovingUserControl)
            {
                if (sender is UserControl userControl)
                {
                    userControl.ReleaseMouseCapture();
                }
                else if (sender is Rectangle rectangle)
                {
                    rectangle.ReleaseMouseCapture();
                }

                RemoveAllSelectionHighlights(); // Remover antes de actualizar
                UpdateSelectionVisuals();
                UpdateAllSelectionHighlights();

                // Restaurar los rectángulos de selección si es necesario
                if (_mainWindow.DataContext is MainViewModel viewModel && viewModel.IsMultiSelectionActive)
                {
                    foreach (var selectedObject in _selectedObjects)
                    {
                        AddSelectionHighlight(selectedObject.VisualRepresentation);
                    }
                }

                _isDraggingUserControl = false;
                _isMovingUserControl = false;
                _currentDraggingRectangle = null;
                _currentResizeMode = ResizeMode.None;
                _lastAngle = 0;
            }
            MarkUnsavedChanges();
        }

        private void MarkUnsavedChanges()
        {
            if (_mainWindow.DataContext is MainViewModel viewModel)
            {
                if (_isMovingUserControl || _isDraggingUserControl)
                {
                    viewModel.HasUnsavedChanges = true;
                }
            }
        }

        private void ResizeRectangle_MouseLeave(object sender, MouseEventArgs e)
        {
            var rect = sender as Rectangle;
            if (rect != null)
            {
                rect.Fill = Brushes.Transparent;
            }
        }

        public void AddHighlightRectangles(UserControl userControl)
        {
            double rectSize = 1;
            RemoveHighlightRectangles();

            if (userControl is IDataContainer dataContainer && dataContainer.Datos is osBase mvBase && mvBase.Show_On_This_Page)
            {
                Rect boundingBox = VisualTreeHelper.GetDescendantBounds(userControl);
                GeneralTransform transform = userControl.TransformToAncestor(_canvas);
                Rect transformedBoundingBox = transform.TransformBounds(boundingBox);

                FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(transformedBoundingBox);
                rectBox.Left -= (float)rectSize;
                rectBox.Right += (float)rectSize;
                rectBox.Top -= (float)rectSize;
                rectBox.Bottom += (float)rectSize;

                Rectangle highlightRect = new Rectangle
                {
                    Width = rectBox.Width,
                    Height = rectBox.Height,
                    Fill = Brushes.Transparent,
                    Stroke = new SolidColorBrush(Color.FromArgb(128, 0, 0, 0)),
                    StrokeThickness = 1,
                    Tag = "Highlight",
                    IsHitTestVisible = false,
                    StrokeDashArray = new DoubleCollection(new double[] { 2, 2 })
                };

                Canvas.SetLeft(highlightRect, rectBox.Left);
                Canvas.SetTop(highlightRect, rectBox.Top); // Corregido: usando rectBox.Top en lugar de highlightRect.Top

                _highlightRectangles.Add(highlightRect);
                _canvas.Children.Add(highlightRect);
                Canvas.SetZIndex(highlightRect, ((int)ZIndexEnum.RectangulosPropiead));

                if (_timerRemoveHighlight == null)
                    _timerRemoveHighlight = new System.Threading.Timer(TimerCallbackRemoveHighlight, null, Timeout.Infinite, Timeout.Infinite);

                _timerRemoveHighlight.Change(2000, Timeout.Infinite);
            }
        }

        private void TimerCallbackRemoveHighlight(object state)
        {
            if (Application.Current != null)
            {
                Application.Current.Dispatcher.Invoke(RemoveHighlightRectangles);
            }
        }

        public void RemoveHighlightRectangles()
        {
            if (_highlightRectangles == null || _highlightRectangles.Count == 0)
                return;

            foreach (var rect in _highlightRectangles)
            {
                _canvas.Children.Remove(rect);
            }
            _highlightRectangles.Clear();
        }

        private HandleMode DetermineHandleMode(string resizeDirection)
        {
            return resizeDirection switch
            {
                "TopLeft" => HandleMode.None,
                "TopRight" or "BottomLeft" or "CenterLeft" => HandleMode.Rotate,
                "BottomRight" => HandleMode.ResizeBoth,
                "TopCenter" => HandleMode.None,
                "BottomCenter" => HandleMode.ResizeHeight,
                "CenterRight" => HandleMode.ResizeWidth,
                _ => HandleMode.None
            };
        }

        private void HandleResize(Point currentPosition, HandleMode mode)
        {
            PurgeDeletedObjects();
            RemoveAllSelectionHighlights(); // Remover antes de redimensionar

            foreach (var selectedObject in _selectedObjects)
            {
                bool resizeWidth = mode == HandleMode.ResizeWidth || mode == HandleMode.ResizeBoth;
                bool resizeHeight = mode == HandleMode.ResizeHeight || mode == HandleMode.ResizeBoth;
                HandleResizeForObject(selectedObject, currentPosition, resizeWidth, resizeHeight);
            }
            _startPointUserControl = currentPosition;

            UpdateAllSelectionHighlights();
        }

        private void HandleResizeForObject(osBase obj, Point currentPosition, bool activateSizeWidth, bool activateSizeHeight)
        {
            double widthChange = activateSizeWidth ? currentPosition.X - _startPointUserControl.X : 0;
            double heightChange = activateSizeHeight ? currentPosition.Y - _startPointUserControl.Y : 0;

            obj.Resize(widthChange, heightChange);
        }

        private void HandleRotation(Point currentPosition)
        {
            PurgeDeletedObjects();
            RemoveAllSelectionHighlights(); // Remover antes de rotar

            // Calcular el ángulo respecto al centro del bounding box que contiene todos los objetos seleccionados
            double deltaX = currentPosition.X - _transformedBoundingBoxCenter.X;
            double deltaY = currentPosition.Y - _transformedBoundingBoxCenter.Y;
            double angle = Math.Atan2(deltaY, deltaX) * (180 / Math.PI);

            if ((_lastAngle == 0 && angle != 0) || Math.Abs(angle - _lastAngle) > 45)
            {
                _lastAngle = (float)angle;
            }
            else
            {
                double deltaAngle = angle - _lastAngle;
                foreach (var selectedObject in _selectedObjects)
                {
                    selectedObject.Rotate(deltaAngle);
                }
                _lastAngle = (float)angle;
            }

            UpdateAllSelectionHighlights();
        }

        public void AlignObjects(AlignmentType alignmentType)
        {
            PurgeDeletedObjects();
            if (_selectedObjects.Count <= 1) return;

            var alignment = new ObjectAlignment(_selectedObjects, _selectedObjects.FirstOrDefault());

            switch (alignmentType)
            {
                case AlignmentType.Left:
                    alignment.AlignLeft();
                    break;
                case AlignmentType.Right:
                    alignment.AlignRight();
                    break;
                case AlignmentType.Top:
                    alignment.AlignTop();
                    break;
                case AlignmentType.Bottom:
                    alignment.AlignBottom();
                    break;
                case AlignmentType.CenterHorizontally:
                    alignment.AlignCenterHorizontally();
                    break;
                case AlignmentType.CenterVertically:
                    alignment.AlignCenterVertically();
                    break;
                case AlignmentType.DistributeHorizontally:
                    alignment.DistributeHorizontally();
                    break;
                case AlignmentType.DistributeVertically:
                    alignment.DistributeVertically();
                    break;
                case AlignmentType.EqualWidth:
                    alignment.EqualWidth();
                    break;
                case AlignmentType.EqualHeight:
                    alignment.EqualHeight();
                    break;
                case AlignmentType.EqualAngle:
                    alignment.EqualAngle();
                    break;
                case AlignmentType.JoinHorizontally:
                    alignment.JoinHorizontally();
                    break;
                case AlignmentType.JoinVertically:
                    alignment.JoinVertically();
                    break;
            }

            // Update the selection visuals after alignment
            UpdateSelectionVisuals();
        }

        public void EliminarObjetosSeleccionados()
        {
            if (_selectedObjects.Count == 0) return;

            var viewModel = _mainWindow.DataContext as MainViewModel;
            if (viewModel == null) return;

            // Crear una copia de la lista para evitar modificaciones durante la iteración
            var objectsToRemove = _selectedObjects.ToList();

            foreach (var obj in objectsToRemove)
            {
                viewModel.RemoverObjetoSimulable(obj);
            }

            // Limpiar la selección y actualizar la interfaz
            ClearSelection();
            RemoveResizeRectangles();
            RemoveAllSelectionHighlights();
            
            // Actualizar el estado de cambios sin guardar
            if (viewModel != null)
            {
                viewModel.HasUnsavedChanges = true;
            }
        }

        public void StartRectangleSelection(Point startPoint)
        {
            _rectangleStart = startPoint;
            _selectionRectangle = new Rectangle
            {
                Stroke = Brushes.Blue,
                StrokeThickness = 1,
                Fill = new SolidColorBrush(Color.FromArgb(50, 0, 0, 255))
            };

            Canvas.SetLeft(_selectionRectangle, startPoint.X);
            Canvas.SetTop(_selectionRectangle, startPoint.Y);
            Canvas.SetZIndex(_selectionRectangle, (int)ZIndexEnum.RectangulosPropiead);

            _canvas.Children.Add(_selectionRectangle);
        }

        private void UpdateSelectionRectangle(Point currentPoint)
        {
            double left = Math.Min(_rectangleStart.X, currentPoint.X);
            double top = Math.Min(_rectangleStart.Y, currentPoint.Y);
            double width = Math.Abs(currentPoint.X - _rectangleStart.X);
            double height = Math.Abs(currentPoint.Y - _rectangleStart.Y);

            _selectionRectangle.Width = width;
            _selectionRectangle.Height = height;
            Canvas.SetLeft(_selectionRectangle, left);
            Canvas.SetTop(_selectionRectangle, top);
        }

        public void FinishRectangleSelection(Point currentPoint)
        {
            if (_selectionRectangle != null)
            {
                var left = Canvas.GetLeft(_selectionRectangle);
                var top = Canvas.GetTop(_selectionRectangle);
                var right = left + _selectionRectangle.Width;
                var bottom = top + _selectionRectangle.Height;
                var selectionBounds = new Rect(new Point(left, top), new Point(right, bottom));

                var itemsToProcess = _canvas.Children.OfType<UserControl>().Where(child => child is IDataContainer).ToList();

                foreach (var child in itemsToProcess)
                {
                    var childBounds = GetElementBounds(child);
                    if (selectionBounds.Contains(childBounds) || selectionBounds.IntersectsWith(childBounds))
                    {
                        if (child.DataContext is osBase osObject)
                        {
                            SelectObject(osObject);
                        }
                    }
                }

                _canvas.Children.Remove(_selectionRectangle);
                _selectionRectangle = null;

                UpdateSelectionVisuals();
            }
        }

        private Rect GetElementBounds(FrameworkElement element)
        {
            var bounds = VisualTreeHelper.GetDescendantBounds(element);
            var transform = element.TransformToAncestor(_canvas);
            return transform.TransformBounds(bounds);
        }

        public void UpdateRectangleSelection(Point currentPoint)
        {
            if (_selectionRectangle != null)
            {
                UpdateSelectionRectangle(currentPoint);
            }
        }
    }
}