using BepuPhysics.Collidables;
using BepuPhysics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;

namespace CtrEditor.Simulacion
{

    public class simGuia : simBase
    {
        private List<Action> _deferredActions;

        // Propiedades para acceder a las dimensiones del objeto WPF
        public float GuideThickness { get; set; } // Espesor de la guía

        // ✅ NUEVO: Agregar propiedades Width y Height para almacenar dimensiones reales
        public float Width { get; set; }
        public float Height { get; set; }

        public simGuia(Simulation simulation, List<Action> deferredActions, float width, float height, Vector2 topLeft, float angle)
        {
            _simulation = simulation;
            _deferredActions = deferredActions;

            // ✅ NUEVO: Almacenar dimensiones reales
            Width = width;
            Height = height;
            GuideThickness = height; // Mantener compatibilidad

            Create(width, height, topLeft, angle);
        }

        public void Create(float width, float height, Vector2 wpfTopLeft, float wpfAngle)
        {
            RemoverBody();

            // ✅ NUEVO: Actualizar dimensiones almacenadas
            Width = width;
            Height = height;
            GuideThickness = height; // Mantener compatibilidad

            // ✅ USAR COORDINATECONVERTER para conversión centralizada
            var zPosition = zAltura_Guia / 2 + zPos_Guia;
            var bepuCenter = CoordinateConverter.CalculateBepuCenterFromWpfTopLeft(wpfTopLeft, width, height, wpfAngle, zPosition);

            // ✅ CRÍTICO: Crear el Box con las dimensiones correctas almacenadas
            var box = new Box(Width, GuideThickness, zAltura_Guia);
            var shapeIndex = _simulation.Shapes.Add(box);

            // ✅ USAR COORDINATECONVERTER para conversión centralizada
            var bodyDescription = BodyDescription.CreateKinematic(
                new RigidPose(bepuCenter, CoordinateConverter.CreateBepuQuaternionFromWpfAngle(wpfAngle)),
                new CollidableDescription(shapeIndex, 0.1f),
                new BodyActivityDescription(0.01f)
            );

            BodyHandle = _simulation.Bodies.Add(bodyDescription);
            _bodyCreated = true;
        }

        // Método para actualizar las propiedades desde el objeto WPF
        public void UpdateProperties(float ancho, float altoGuia, float angulo)
        {
            // ✅ CORREGIDO: Actualizar todas las dimensiones
            Width = ancho;
            Height = altoGuia;
            GuideThickness = altoGuia; // Mantener compatibilidad
        }

        /// <summary>
        /// ✅ CORREGIDO - Actualiza las dimensiones y recrea el cuerpo físico si es necesario
        /// </summary>
        public void SetDimensions(float width, float height)
        {
            // ✅ NUEVO: Actualizar dimensiones almacenadas
            Width = width;
            Height = height;
            GuideThickness = height; // Mantener compatibilidad

            // ✅ CORREGIDO: Usar ChangeBodyShape para limpiar la forma anterior
            if (_simulation != null && _simulation.Bodies.BodyExists(BodyHandle))
            {
                var box = new Box(width, GuideThickness, zAltura_Guia);
                var shapeIndex = _simulation.Shapes.Add(box);
                ChangeBodyShape(shapeIndex);
            }
        }

        /// <summary>
        /// ✅ CORREGIDO - Actualiza posición usando las dimensiones reales almacenadas
        /// </summary>
        public void SetPosition(Vector2 wpfTopLeft, float wpfAngle, float actualWidth, float actualHeight)
        {
            // ✅ NUEVO: Actualizar dimensiones almacenadas
            Width = actualWidth;
            Height = actualHeight;
            GuideThickness = actualHeight; // Mantener compatibilidad

            // ✅ CRÍTICO: Recrear el box colisionador con las nuevas dimensiones
            if (_simulation != null && _simulation.Bodies.BodyExists(BodyHandle))
            {
                var box = new Box(actualWidth, GuideThickness, zAltura_Guia);
                var shapeIndex = _simulation.Shapes.Add(box);
                ChangeBodyShape(shapeIndex);
            }

            // ✅ USAR COORDINATECONVERTER para conversión centralizada con dimensiones reales
            var zPosition = zAltura_Guia / 2 + zPos_Guia;
            var bepuCenter = CoordinateConverter.CalculateBepuCenterFromWpfTopLeft(wpfTopLeft, actualWidth, actualHeight, wpfAngle, zPosition);

            // Actualizar posición y rotación simultáneamente
            CoordinateConverter.UpdateBepuBodyPose(_simulation, BodyHandle, bepuCenter, wpfAngle);
        }

        /// <summary>
        /// ✅ CORREGIDO: Actualiza tanto posición como rotación usando dimensiones reales
        /// </summary>
        internal void UpdateFromWpfParameters(Vector2 wpfTopLeft, float wpfAngle, float width, float height)
        {
            // ✅ NUEVO: Actualizar dimensiones almacenadas
            Width = width;
            Height = height;
            GuideThickness = height; // Mantener compatibilidad

            // ✅ CRÍTICO: Recrear el box colisionador con las nuevas dimensiones
            if (_simulation != null && _simulation.Bodies.BodyExists(BodyHandle))
            {
                var box = new Box(width, GuideThickness, zAltura_Guia);
                var shapeIndex = _simulation.Shapes.Add(box);
                ChangeBodyShape(shapeIndex);
            }

            // ✅ USAR COORDINATECONVERTER para conversión centralizada con dimensiones reales
            var zPosition = zAltura_Guia / 2 + zPos_Guia;
            var bepuCenter = CoordinateConverter.CalculateBepuCenterFromWpfTopLeft(wpfTopLeft, width, height, wpfAngle, zPosition);

            // Actualizar posición y rotación simultáneamente
            CoordinateConverter.UpdateBepuBodyPose(_simulation, BodyHandle, bepuCenter, wpfAngle);
        }

        /// <summary>
        /// ✅ CORREGIDO - Usar dimensiones reales almacenadas en lugar de aproximaciones
        /// </summary>
        public void SetPosition(Vector2 wpfTopLeft, float wpfAngle = 0)
        {
            // ✅ CORREGIDO: Usar dimensiones reales almacenadas en lugar de aproximaciones
            SetPosition(wpfTopLeft, wpfAngle, Width, Height);
        }
    }

}
