using ClosedXML.Excel;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;

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

    public partial class osExtraccionTag : osBase, IosBase
    {
        public static string NombreCategoria() => "Extraccion Datos";
        public static string NombreClase()
        {
            return "Extractor de Tags";
        }
        private string nombre = NombreClase();

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

        [ObservableProperty]
        [property: Category("Configuración")]
        [property: Description("Ejecutar extracción de tag")]
        [property: Name("Extraer")]
        bool extraer;

        [ObservableProperty]
        [property: Category("Configuración")]
        [property: Description("Eliminar saltos de línea del texto extraído")]
        [property: Name("Eliminar Enter")]
        bool eliminar_enters;

        [ObservableProperty]
        [property: Category("Configuración")]
        [property: Description("Idioma para reconocimiento OCR")]
        [property: Name("Idioma OCR")]
        [property: ItemsSource(typeof(IdiomasItemsSource<Idiomas>))]
        string idioma_Extraccion;

        [ObservableProperty]
        [property: Category("Configuración")]
        [property: Description("Patrón de extracción de texto")]
        [property: Name("Tipo de Patrón")]
        [property: ItemsSource(typeof(TagPatternItemsSource<TagPattern>))]
        string pattern_Type;

        public override void TopChanged(float value)
        {
            base.TopChanged(value);
            if (Extraer) ResetTimer();
        }

        public override void LeftChanged(float value)
        {
            base.LeftChanged(value);
            if (Extraer) ResetTimer();
        }

        partial void OnExtraerChanged(bool value)
        {
            if (Extraer)
                ResetTimer();
        }

        public override void OnResize(float Delta_Width, float Delta_Height)
        {
            if (Extraer)
                ResetTimer();
        }
        public override void OnMove(float LeftPixels, float TopPixels)
        {
            if (Extraer)
                ResetTimer();
        }

        public override void OnRotate(float Angle)
        {
            if (Extraer)
                ResetTimer();
        }

        public override void OnTimerAfterMovement()
        {
            Angulo = (float)Math.Round(Angulo / 90) * 90;

            if (Extraer)
                CaptureImageAreaAndDoOCR();
            Extraer = false;
        }


        private osBuscarCoincidencias Search_Templates;

        [ObservableProperty]
        [property: Category("Configuración")]
        [property: Description("Plantillas de búsqueda asociadas")]
        [property: Name("Plantillas Búsqueda")]
        [property: ItemsSource(typeof(osBaseItemsSource<osBuscarCoincidencias>))]
        string id_Search_Templates;

        partial void OnId_Search_TemplatesChanged(string value)
        {
            if (Search_Templates != null)
                Search_Templates.PropertyChanged -= OnMotorPropertyChanged;
            if (_mainViewModel != null && value != null && value.Length > 0)
            {
                Search_Templates = (osBuscarCoincidencias)_mainViewModel.ObjetosSimulables.FirstOrDefault(s => (s is osBuscarCoincidencias && s.Nombre == value), null);
                if (Search_Templates != null)
                    Search_Templates.PropertyChanged += OnMotorPropertyChanged;
            }
        }

        private void OnMotorPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(osBuscarCoincidencias.Nombre))
            {
                Id_Search_Templates = ((osBuscarCoincidencias)sender).Nombre;
            }
        }

        [ObservableProperty]
        [property: Category("Datos")]
        [property: Description("Texto extraído mediante OCR")]
        [property: Name("Tag Extraído")]
        string tag_extract;

        [ObservableProperty]
        [property: Category("Datos")]
        [property: Description("Clase del objeto para exportación")]
        [property: Name("Clase")]
        string clase;

        [ObservableProperty]
        [property: Category("Datos")]
        [property: Description("Nombre de la columna para exportación")]
        [property: Name("Nombre Columna")]
        string collumn_name;

        [ObservableProperty]
        [property: Category("Datos")]
        [property: Description("Número de columna Excel")]
        [property: Name("Número Columna")]
        int collumn_number;

        [ObservableProperty]
        [property: Category("Información")]
        [property: Description("Número de copia del objeto")]
        [property: Name("Número de Copia")]
        [property: ReadOnly(true)]
        int copy_Number;

        [ObservableProperty]
        [property: Category("Configuración")]
        [property: Description("Mostrar ventana de depuración OCR")]
        [property: Name("Mostrar Debug")]
        bool show_Debug_Window;

        [ObservableProperty]
        [property: Category("Apariencia")]
        [property: Description("Opacidad del objeto")]
        [property: Name("Opacidad")]
        float opacity_oculto;

        public osExtraccionTag()
        {
            Ancho = 1;
            Alto = 1;
            Angulo = 0;
            Opacity_oculto = 0.1f;
            Idioma_Extraccion = Idiomas.DEFAULT_LANGUAGE;
            Pattern_Type = TagPattern.DEFAULT_PATTERN;
            Eliminar_enters = true;
        }

        public void CaptureImageAreaAndDoOCR()
        {
            string extractedText = CaptureImageAreaAndDoOCRPPaddle(Left, Top, Ancho, Alto, Angulo, Show_Debug_Window);

            // Clean up the extracted text if eliminar_enters is true
            if (Eliminar_enters && !string.IsNullOrEmpty(extractedText))
            {
                // Replace all types of line endings with spaces
                extractedText = extractedText.Replace("\r\n", " ")
                                          .Replace("\n", " ")
                                          .Replace("\r", " ");

                // Replace multiple consecutive spaces with a single space
                extractedText = System.Text.RegularExpressions.Regex.Replace(extractedText, @"\s+", " ");

                // Trim spaces at the beginning and end
                extractedText = extractedText.Trim();
            }

            // Apply the selected pattern
            extractedText = TagPattern.ApplyPattern(extractedText, Pattern_Type);

            Tag_extract = extractedText;

            // Set default language to English if not set
            if (string.IsNullOrEmpty(Idioma_Extraccion))
            {
                Idioma_Extraccion = Idiomas.DEFAULT_LANGUAGE;
            }
        }

        public int ExportToExcel(IXLWorksheet worksheet, int row, int colBase)
        {
            // Agregar Tag
            worksheet.Cell(row + 2, Collumn_number + colBase).Value = Tag_extract;
            return Collumn_number + colBase;
        }


        public override void ucLoaded()
        {
            // El UserControl ya se ha cargado y podemos obtener las coordenadas para 
            // crear el objeto de simulacion
            base.ucLoaded();
            OnId_Search_TemplatesChanged(Id_Search_Templates); // Actualizar Link
        }

    }

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

        public ucExtraccionTag()
        {
            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 Resize(float width, float height)
        {
            if (Datos is osExtraccionTag datos)
            {
                datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
                datos.Alto += PixelToMeter.Instance.calc.PixelsToMeters(height);
            }
        }
        public void Move(float LeftPixels, float TopPixels)
        {
            if (Datos != null)
            {
                Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels);
                Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
            }
        }
        public float Angle()
        {
            if (Datos != null)
                if (Datos is osExtraccionTag datos)
                    return datos.Angulo;
            return 0f;
        }
        public void Rotate(float Angle)
        {
            if (Datos != null)
                if (Datos is osExtraccionTag datos)
                    datos.Angulo += Angle;
        }
        public void Highlight(bool State) { }
        public ZIndexEnum ZIndex_Base()
        {
            return ZIndexEnum.ExtraccionTag;
        }


    }
}



