using System.Windows;
using System.Windows.Controls;
using LibS7Adv;
using CtrEditor.Simulacion;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Numerics;
using System.Windows.Media;
using CtrEditor.FuncionesBase;
using System.ComponentModel;

namespace CtrEditor.ObjetosSim
{
    /// <summary>
    /// Interaction logic for ucBotella.xaml
    /// </summary>
    /// 

    public partial class osBotella : osBase, IosBase
    {
        private simBotella SimGeometria;

        // Otros datos y métodos relevantes para la simulación

        public static string NombreClase()
        {
            return "Botella";
        }

        public static string NombreCategoria()
        {
            return "Dinamicos";
        }
        private string nombre = NombreClase();

        [property: Category("Identificación")]
        [property: Description("Nombre identificativo del objeto")]
        [property: Name("Nombre")]
        public override string Nombre
        {
            get => nombre;
            set => SetProperty(ref nombre, value);
        }

        public override void OnMove(float LeftPixels, float TopPixels)
        {
            UpdateAfterMove();
        }

        public override void OnResize(float Delta_Width, float Delta_Height)
        {
            Diametro += Delta_Width;
        }

        [ObservableProperty]
        [property: Category("Apariencia")]
        [property: Description("Color visual de la botella")]
        [property: Name("Color")]
        private Brush colorButton_oculto;

        [ObservableProperty]
        [property: Category("Configuración")]
        [property: Description("Diámetro de la botella en metros")]
        [property: Name("Diámetro")]
        private float diametro;

        partial void OnDiametroChanged(float value)
        {
            // Asegurar que el diámetro sea al menos 0.01m para evitar errores en la simulación
            if (value < 0.01f)
            {
                diametro = 0.01f;
                return;
            }
            SimGeometria?.SetDiameter(Diametro);
        }

        [ObservableProperty]
        [property: Category("Información")]
        [property: Description("Velocidad actual desde la simulación")]
        [property: Name("Velocidad de Simulación")]
        private string velocidad_desde_simulacion;

        [ObservableProperty]
        [property: Category("Información")]
        [property: Description("Inercia actual desde la simulación")]
        [property: Name("Inercia de Simulación")]
        private float inercia_desde_simulacion;

        [ObservableProperty]
        [property: Category("Información")]
        [property: Description("Porcentaje de tracción con transporte")]
        [property: Name("Porcentaje de Tracción")]
        private float porcentaje_Traccion;

        [ObservableProperty]
        [property: Category("Información")]
        [property: Description("Indica si la botella está en un transporte con freno")]
        [property: Name("En Transporte con Freno")]
        private bool enTransporteConFreno;

        [ObservableProperty]
        [property: Category("Calibración")]
        [property: Description("Nivel de deslizamiento/presión (0-9) para calibración de fricción")]
        [property: Name("Nivel de Deslizamiento")]
        private float nivelDeslizamiento;

        [ObservableProperty]
        [property: Category("Simulación")]
        [property: Description("Masa del objeto en kg")]
        [property: Name("Masa")]
        private float mass;
        partial void OnMassChanged(float value)
        {
            SimGeometria?.SetMass(value);
        }

        public Vector2 GetCentro()
        {
            return new Vector2(Left + Diametro / 2, Top + Diametro / 2);
        }

        public void SetCentro(float x, float y)
        { Left = x - Diametro / 2; Top = y - Diametro / 2; }

        public void SetCentro(Vector2 centro)
        {
            Left = centro.X - Diametro / 2;
            Top = centro.Y - Diametro / 2;
        }

        private void ActualizarGeometrias()
        {
            if (SimGeometria != null && !RemoverDesdeSimulacion)
            {
                SimGeometria.SetPosition(GetCentro());
            }
        }

        public osBotella()
        {
            Diametro = 0.10f;
            Mass = 1;
            ColorButton_oculto = Brushes.Gray;
        }

        public void UpdateAfterMove()
        {
            if (!RemoverDesdeSimulacion)
            {
                ActualizarGeometrias();
                SimGeometria?.SetDiameter(Diametro);
            }
        }

        public override void UpdateGeometryStart()
        {
            // Se llama cuando inicia la simulación - crear geometría si no existe
            if (SimGeometria == null)
            {
                SimGeometria = simulationManager.AddBotella(Diametro, GetCentro(), Mass);
                SimGeometria.SimObjectType = "Botella";
                SimGeometria.WpfObject = this;
            }
            else
            {
                ActualizarGeometrias();
                SimGeometria?.SetDiameter(Diametro);
                SimGeometria?.SetMass(Mass);
            }
        }

        public override void UpdateGeometryStep()
        {
            // Se llama durante cada paso de la simulación
            if (SimGeometria != null)
            {
                // Actualizar posición desde la simulación hacia WPF
                SetCentro(SimGeometria.Center);
            }
        }
        public override void UpdateControl(int elapsedMilliseconds)
        {
            SetCentro(SimGeometria.Center);

            // Sistema de colores jerarquizado para diferentes estados
            if (SimGeometria.isOnBrakeTransport)
                ColorButton_oculto = Brushes.Blue;    // En transporte con freno (prioridad sobre presión)
            else if (!SimGeometria.isOnBrakeTransport && SimGeometria.ContactPressure > 0)
                ColorButton_oculto = Brushes.Red;      // La botella tiene mucha presion
            else
                ColorButton_oculto = Brushes.Gray;      // 5. Estado libre

            // Ha sido marcada para remover
            if (SimGeometria.Descartar)
                RemoverDesdeSimulacion = true;

            // ✅ ELIMINADO: Lógica redundante - BEPU.cs ya elimina botellas que caen en Z automáticamente

            Velocidad_desde_simulacion = SimGeometria.GetLinearVelocity().ToString();
            Inercia_desde_simulacion = SimGeometria.Mass; // En BEPU usamos masa en lugar de inercia directa
            Porcentaje_Traccion = SimGeometria.OverlapPercentage;
            EnTransporteConFreno = SimGeometria.isOnBrakeTransport;  // Actualizar estado de freno
            NivelDeslizamiento = 10-SimGeometria.forceScale*10; // ✅ NUEVO: Mostrar nivel de deslizamiento para calibración
        }

        public override void ucLoaded()
        {
            // El UserControl ya se ha cargado y podemos obtener las coordenadas para 
            // crear el objeto de simulacion
            base.ucLoaded();
            SimGeometria = simulationManager.AddBotella(Diametro, GetCentro(), Mass);
        }
        public override void ucUnLoaded()
        {
            // El UserControl se esta eliminando
            // eliminar el objeto de simulacion
            simulationManager.Remove(SimGeometria);
        }

    }

    public partial class ucBotella : UserControl, IDataContainer
    {
        public osBase? Datos { get; set; }
        public int zIndex_fromFrames { get; set; }

        public ucBotella()
        {
            InitializeComponent();
            this.Loaded += OnLoaded;
            this.Unloaded += OnUnloaded;
        }
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            Datos?.ucLoaded();
        }
        private void OnUnloaded(object sender, RoutedEventArgs e)
        {
            Datos?.ucUnLoaded();
        }

        public void Highlight(bool State) { }
        public ZIndexEnum ZIndex_Base()
        {
            return ZIndexEnum.Dinamicos;
        }
    }
}
