using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using CtrEditor.FuncionesBase;
using CtrEditor.Simulacion.Fluids.Components;
using nkast.Aether.Physics2D.Common;
using CommunityToolkit.Mvvm.ComponentModel;
using Color = System.Windows.Media.Color;
using System.ComponentModel;
using LibS7Adv;

namespace CtrEditor.ObjetosSim
{
    /// <summary>
    /// Lógica para ucValvulaFluido.xaml
    /// </summary>
    public partial class ucValvulaFluido : UserControl, IDataContainer
    {
        public osBase? Datos { get; set; }
        public int zIndex_fromFrames { get; set; }
        
        public ucValvulaFluido()
        {
            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.Estaticos;
        }
    }
    
    /// <summary>
    /// ViewModel para la válvula de fluidos
    /// </summary>
    public partial class osValvulaFluido : osBase, IosBase
    {
        // Válvula en la simulación de fluidos
        private Valvula _valvula;
        
        // Referencia al sistema de fluidos
        private osSistemaFluidos _sistemaFluidos;
        
        // Propiedades dimensionales
        [ObservableProperty]
        [property: Category("Dimensiones:")]
        [property: Description("Ancho de la válvula en metros")]
        private float ancho = 0.1f;
        
        [ObservableProperty]
        [property: Description("Alto de la válvula en metros")]
        [property: Category("Dimensiones:")]
        private float alto = 0.06f;
        
        [ObservableProperty]
        [property: Description("Diámetro de la tubería conectada")]
        [property: Category("Dimensiones:")]
        private float diametroTuberia = 0.05f;
        
        // Propiedades visuales
        [ObservableProperty]
        [property: Description("Color de la válvula")]
        [property: Category("Visual:")]
        private Color color = Colors.Silver;
        
        [ObservableProperty]
        [property: Description("Color del indicador de apertura")]
        [property: Category("Visual:")]
        private Color colorIndicador = Colors.CornflowerBlue;
        
        // Propiedades de funcionamiento
        [ObservableProperty]
        [property: Description("Apertura de la válvula (0-1)")]
        [property: Category("Operación:")]
        private float apertura = 1.0f;
        
        partial void OnAperturaChanged(float value)
        {
            Apertura = Math.Clamp(value, 0, 1);
            
            // Actualizar la válvula en la simulación
            if (_valvula != null)
            {
                _valvula.Apertura = Apertura;
            }
        }
        
        // Tag PLC para la válvula
        [ObservableProperty]
        [property: Description("Tag de lectura/escritura de la apertura (0-100%)")]
        [property: Category("PLC:")]
        private string tagApertura;
        
        // Propiedades calculadas para visualización
        public float AperturaVisual => Ancho * 0.8f * Apertura;
        public float GrosorIndicador => Alto * 0.2f;
        public float ValorApertura => Apertura;
        
        // Propiedades para posicionamiento de elementos
        public float OffsetXRectangulo => -Ancho / 2;
        public float OffsetYRectangulo => -Alto / 2;
        public float OffsetXIndicador => -Ancho * 0.4f;
        public float OffsetYIndicador => -GrosorIndicador / 2;
        public float OffsetXTexto => -Ancho * 0.15f;
        public float OffsetYTexto => Alto * 0.1f;
        
        // Nombre de la clase para identificación
        public static string NombreClase()
        {
            return "ValvulaFluido";
        }
        
        private string nombre = NombreClase();
        public override string Nombre
        {
            get => nombre;
            set => SetProperty(ref nombre, value);
        }
        
        /// <summary>
        /// Constructor
        /// </summary>
        public osValvulaFluido()
        {
            // Constructor
        }
        
        public override void OnMove(float LeftPixels, float TopPixels)
        {
            if (_valvula != null)
            {
                // Actualizar posición de la válvula en la simulación
                _valvula.ActualizarPosicion(new Vector2(Left, Top));
            }
        }
        
        public override void OnRotate(float Delta_Angle)
        {
            // La rotación visual ya está manejada por el XAML
            // No necesita actualizaciones adicionales en la simulación
        }
        
        public override void ucLoaded()
        {
            base.ucLoaded();
            
            // Buscar el sistema de fluidos en la simulación
            if (_mainViewModel?.ObjetosSimulables != null)
            {
                foreach (var obj in _mainViewModel.ObjetosSimulables)
                {
                    if (obj is osSistemaFluidos sistemaFluidos)
                    {
                        _sistemaFluidos = sistemaFluidos;
                        break;
                    }
                }
            }
            
            // Crear la válvula en la simulación
            if (_sistemaFluidos != null)
            {
                _valvula = _sistemaFluidos.CrearValvula(
                    new Vector2(Left, Top),
                    DiametroTuberia,
                    Apertura
                );
            }
        }
        
        public override void ucUnLoaded()
        {
            // Eliminar la válvula de la simulación
            if (_sistemaFluidos != null && _valvula != null)
            {
                _sistemaFluidos.EliminarComponente(_valvula);
                _valvula = null;
            }
        }
        
        public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
        {
            // Manejar la comunicación con PLC
            if (!string.IsNullOrEmpty(TagApertura))
            {
                float aperturaPlc = LeerWordTagScaled(TagApertura) / 100.0f;
                Apertura = Math.Clamp(aperturaPlc, 0, 1);
            }
        }
    }
}
