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

namespace CtrEditor.Simulacion
{
    public class simPumpExample : simBase
    {
        public float Width;
        public float Height;
        public float Depth;
        private float _mass;
        
        // Propiedades hidráulicas
        public double PumpHead { get; set; } = 50.0;
        public double MaxFlow { get; set; } = 0.01;
        public double SpeedRatio { get; set; } = 1.0;
        public bool IsRunning { get; set; } = true;
        public int PumpDirection { get; set; } = 1;
        
        // Estado actual de la simulación hidráulica
        public double CurrentFlow { get; set; } = 0.0;
        public double CurrentPressure { get; set; } = 0.0;

        public simPumpExample(Simulation simulation, List<Action> deferredActions, Vector3 dimensions, Vector2 position, float mass)
        {
            _simulation = simulation;
            Width = dimensions.X;
            Height = dimensions.Y;
            Depth = dimensions.Z;
            _mass = mass;

            // Usar COORDINATECONVERTER para conversión centralizada
            var position3D = new Vector3(position.X, CoordinateConverter.WpfYToBepuY(position.Y), Depth / 2f + zPos_Transporte + zAltura_Transporte);
            Create(position3D);
        }

        public float CenterX
        {
            get
            {
                return GetPosition().X;
            }
            set
            {
                var pos = GetPosition();
                SetPosition(value, pos.Y, pos.Z);
            }
        }

        public float CenterY
        {
            get
            {
                // Usar COORDINATECONVERTER para conversión centralizada
                return CoordinateConverter.BepuYToWpfY(GetPosition().Y);
            }
            set
            {
                var pos = GetPosition();
                // Usar COORDINATECONVERTER para conversión centralizada
                SetPosition(pos.X, CoordinateConverter.WpfYToBepuY(value), pos.Z);
            }
        }

        public Vector2 Center
        {
            get
            {
                var pos3D = GetPosition();
                // Usar COORDINATECONVERTER para conversión centralizada
                return CoordinateConverter.BepuVector3ToWpfVector2(pos3D);
            }
            set
            {
                // Mantener la Z actual, solo cambiar X, Y
                var currentPos = GetPosition();
                // Usar COORDINATECONVERTER para conversión centralizada
                SetPosition(value.X, CoordinateConverter.WpfYToBepuY(value.Y), currentPos.Z);
            }
        }

        public float Mass
        {
            get
            {
                if (_simulation != null && _simulation.Bodies.BodyExists(BodyHandle))
                {
                    var bodyReference = _simulation.Bodies.GetBodyReference(BodyHandle);
                    return 1f / bodyReference.LocalInertia.InverseMass;
                }
                return _mass;
            }
            set
            {
                _mass = value;
                if (_simulation != null && _simulation.Bodies.BodyExists(BodyHandle))
                {
                    var box = new Box(Width, Height, Depth);
                    var inertia = box.ComputeInertia(_mass);
                    _simulation.Bodies.SetLocalInertia(BodyHandle, inertia);
                }
            }
        }

        private void Create(Vector3 position)
        {
            RemoverBody();

            var box = new Box(Width, Height, Depth);
            var shapeIndex = _simulation.Shapes.Add(box);

            // Crear el cuerpo estático (las bombas no se mueven físicamente)
            var inertia = box.ComputeInertia(_mass);
            var bodyDescription = BodyDescription.CreateKinematic(
                new RigidPose(position),
                new CollidableDescription(shapeIndex, 0),
                new BodyActivityDescription(-1f)
            );
            
            BodyHandle = _simulation.Bodies.Add(bodyDescription);
            _bodyCreated = true;

            // Registrar en el diccionario del SimulationManager
            if (_simulationManager != null)
                _simulationManager.CollidableData[BodyHandle.Value] = this;
        }

        public void SetDimensions(Vector3 dimensions)
        {
            Width = dimensions.X;
            Height = dimensions.Y;
            Depth = dimensions.Z;

            if (_simulation != null && _simulation.Bodies.BodyExists(BodyHandle))
            {
                var box = new Box(Width, Height, Depth);
                var shapeIndex = _simulation.Shapes.Add(box);
                ChangeBodyShape(shapeIndex);
            }
        }

        public void SetMass(float mass)
        {
            Mass = mass;
        }

        /// <summary>
        /// Actualiza las propiedades hidráulicas de la bomba
        /// </summary>
        public void UpdateHydraulicProperties(double pumpHead, double maxFlow, double speedRatio, bool isRunning, int direction)
        {
            PumpHead = pumpHead;
            MaxFlow = maxFlow;
            SpeedRatio = speedRatio;
            IsRunning = isRunning;
            PumpDirection = direction;
        }

        /// <summary>
        /// Aplica los resultados de la simulación hidráulica
        /// </summary>
        public void ApplyHydraulicResults(double flow, double pressure)
        {
            CurrentFlow = flow;
            CurrentPressure = pressure;
        }

        /// <summary>
        /// Obtiene el caudal actual de la bomba
        /// </summary>
        public double GetCurrentFlow()
        {
            return CurrentFlow;
        }

        /// <summary>
        /// Obtiene la presión actual de la bomba
        /// </summary>
        public double GetCurrentPressure()
        {
            return CurrentPressure;
        }

        public new void RemoverBody()
        {
            base.RemoverBody();
        }
    }
}
