"""
Refactored GUI for the Excel Filter Tool
Main GUI class that orchestrates all components
"""

import tkinter as tk
from tkinter import filedialog, messagebox, ttk
import os
import json
import subprocess
import sys
import pandas as pd
import platform

# Update the imports to use absolute paths
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from filter import ExcelFilter
from gui_components.main_window import MainWindow
from gui_components.config_tab import ConfigTab
from gui_components.execution_tab import ExecutionTab
from gui_components.regex_builder_tab import RegexBuilderTab
from gui_components.help_tab import HelpTab
from utils.file_utils import browse_file, browse_save_file, load_config, save_config
from utils.logging_utils import log_message, log_error
from translations import Translations


class ExcelFilterGUI:
    """
    Main GUI class for the Excel Filter Tool
    """
    
    def __init__(self, root):
        """
        Initialize the GUI
        """
        self.root = root

        # Initialize translations
        self.translations = Translations()

        # Get user data directory for config files
        self.user_data_dir = self.get_user_data_directory()

        # Configuration
        self.config_file = os.path.join(self.user_data_dir, "config.json")

        # Load presets from file
        self.presets_file = os.path.join(self.user_data_dir, "presets.json")
        self.pattern_presets, self.pattern_descriptions = self.load_presets()
        
        # Windows 11 Fluent Design color palette
        self.win11_colors = {
            'primary': '#0078d4',      # Windows 11 Blue
            'primary_dark': '#005a9e', # Darker blue for hover effects
            'primary_light': '#cce4f7', # Light blue for active states
            'background': '#f0f0f0',   # Light gray background
            'surface': '#ffffff',      # White surface
            'text': '#212121',         # Dark text
            'text_secondary': '#616161', # Secondary text
            'border': '#e0e0e0',       # Border color
            'hover': '#e8f0fe',        # Hover effect
            'pressed': '#d0e0f5',      # Pressed effect
            'success': '#107c10',      # Success color
            'warning': '#c55c00',      # Warning color
            'error': '#c42b1c'         # Error color
        }

        # Create main window with Windows 11 styling (now larger)
        self.main_window = MainWindow(root)

        # Apply Windows 11 window properties (size is now handled by MainWindow)
        root.title(self.translations["app_title"])
        root.configure(bg=self.win11_colors['background'])

        # Set window icon if available
        try:
            root.iconbitmap('app_icon.ico')
        except:
            pass

        # Create tabs
        self.create_tabs()

        # Load configuration
        self.load_config()

    def get_user_data_directory(self):
        """
        Get the user data directory for storing config files.
        On Windows: %APPDATA%\\ExcelFilter
        On Linux/Mac: ~/.config/ExcelFilter or ~/Library/Application Support/ExcelFilter
        """
        app_name = "ExcelFilter"

        if platform.system() == "Windows":
            # Use %APPDATA%\ExcelFilter
            base_dir = os.path.expandvars("%APPDATA%")
            data_dir = os.path.join(base_dir, app_name)
        elif platform.system() == "Darwin":  # macOS
            # Use ~/Library/Application Support/ExcelFilter
            home = os.path.expanduser("~")
            data_dir = os.path.join(home, "Library", "Application Support", app_name)
        else:  # Linux and others
            # Use ~/.config/ExcelFilter
            home = os.path.expanduser("~")
            data_dir = os.path.join(home, ".config", app_name)

        # Create the directory if it doesn't exist
        try:
            os.makedirs(data_dir, exist_ok=True)
        except Exception as e:
            print(f"Warning: Could not create user data directory {data_dir}: {e}")
            # Fallback to current directory if we can't create the user directory
            data_dir = os.getcwd()

        return data_dir

    def connect_browse_buttons(self, config_tab):
        """
        Connect the browse buttons to their respective methods
        This ensures the buttons work even if created before methods are assigned
        """
        # Find and connect the browse buttons
        for child in config_tab.frame.winfo_children():
            if isinstance(child, ttk.Frame):
                for subchild in child.winfo_children():
                    if isinstance(subchild, ttk.Frame):
                        for widget in subchild.winfo_children():
                            if isinstance(widget, ttk.Button) and "Durchsuchen" in widget.cget("text"):
                                # Determine which button it is based on grid position
                                try:
                                    grid_info = widget.grid_info()
                                    if grid_info["row"] == 1:  # Input file row
                                        widget.config(command=self.browse_input_file)
                                    elif grid_info["row"] == 2:  # Output file row
                                        widget.config(command=self.browse_output_file)
                                except Exception as e:
                                    print(f"Error connecting browse button: {e}")
    
    def on_sheet_selected(self, event):
        """
        Wird aufgerufen, wenn ein Arbeitsblatt ausgewählt wird
        """
        selected_sheet = event.widget.get()
        self.config_tab.sheet_var.set(selected_sheet)
        self.update_columns_selection()
    
    def update_sheet_selection(self):
        """
        Aktualisiert die Arbeitsblattauswahl
        """
        input_file = self.config_tab.input_file_var.get()
        if not input_file:
            messagebox.showerror("Fehler", "Bitte geben Sie eine Eingabedatei an")
            return
        try:
            # Arbeitsblätter aus der Excel-Datei lesen
            xls = pd.ExcelFile(input_file)
            sheets = xls.sheet_names
            # Arbeitsblattauswahl aktualisieren
            self.config_tab.sheet_combobox['values'] = sheets
            if sheets:
                self.config_tab.sheet_combobox.current(0)
                self.config_tab.sheet_var.set(sheets[0])
            self.config_tab.log_message(f"Arbeitsblattauswahl aktualisiert: {sheets}")
        except Exception as e:
            self.config_tab.log_error(f"Fehler beim Aktualisieren der Arbeitsblattauswahl: {e}")
            messagebox.showerror("Fehler", f"Fehler beim Aktualisieren der Arbeitsblattauswahl: {e}")
    
    def update_columns_selection(self, selected_columns=None):
        """
        Aktualisiert die Spaltenauswahl

        Args:
            selected_columns: List of column names that should be initially selected
        """
        input_file = self.config_tab.input_file_var.get()
        if not input_file:
            messagebox.showerror("Fehler", "Bitte geben Sie eine Eingabedatei an")
            return
        try:
            # Spalten aus der Excel-Datei lesen
            sheet_name = self.config_tab.sheet_var.get()
            if sheet_name:
                df = pd.read_excel(input_file, sheet_name=sheet_name)
            else:
                df = pd.read_excel(input_file)
            columns = df.columns.tolist()
            # Spalten ohne Namen behandeln
            for i, column in enumerate(columns):
                if pd.isna(column) or column == "":
                    # Ersten nicht leeren Wert in der Spalte finden
                    for value in df.iloc[:, i]:
                        if pd.notna(value) and value != "":
                            columns[i] = str(value)[:10]  # Auf 10 Zeichen begrenzen
                            break
                    else:
                        columns[i] = f"Spalte_{i+1}"  # Falls alle Werte leer sind
            # Spaltenauswahl-Container leeren
            for widget in self.config_tab.columns_container.winfo_children():
                widget.destroy()
            # Regex-Spaltenauswahl aktualisieren
            self.config_tab.regex_column_combobox['values'] = ["Alle Spalten"] + columns
            self.config_tab.regex_column_combobox.current(0)
            # Spaltenauswahl erstellen
            self.config_tab.columns_vars = {}
            for i, column in enumerate(columns):
                var = tk.IntVar()
                # If selected_columns is provided and column is in it, select the checkbox
                if selected_columns and column in selected_columns:
                    var.set(1)
                self.config_tab.columns_vars[column] = var
                checkbox = ttk.Checkbutton(self.config_tab.columns_container, text=column, variable=var)
                checkbox.grid(row=i // 3, column=i % 3, sticky=tk.W, padx=5, pady=2)
                checkbox.configure(style='TCheckbutton')  # Ensure proper styling
            
            # Ensure container is properly configured and visible
            self.config_tab.columns_container.update_idletasks()
            
            # Debug: Check if checkboxes were actually created
            checkboxes = self.config_tab.columns_container.winfo_children()
            print(f"DEBUG: Created {len(checkboxes)} checkboxes for columns: {columns}")
            
            self.config_tab.log_message(f"Spaltenauswahl aktualisiert: {columns}")
        except Exception as e:
            self.config_tab.log_error(f"Fehler beim Aktualisieren der Spaltenauswahl: {e}")
            messagebox.showerror("Fehler", f"Fehler beim Aktualisieren der Spaltenauswahl: {e}")
            print(f"DEBUG: Error in update_columns_selection: {e}")
    
    def select_all_columns(self):
        """
        Wählt alle Spalten aus
        """
        for column, var in self.config_tab.columns_vars.items():
            var.set(1)
        self.config_tab.log_message("Alle Spalten ausgewählt")
    
    def deselect_all_columns(self):
        """
        Wählt alle Spalten ab
        """
        for column, var in self.config_tab.columns_vars.items():
            var.set(0)
        self.config_tab.log_message("Alle Spalten abgewählt")
    
    def create_tabs(self):
        """
        Create all tabs for the application
        """
        # Get scale factor from main window for DPI-aware scaling
        scale_factor = self.main_window.scale_factor

        # Configuration tab
        config_tab = ConfigTab(
            self.main_window.notebook,
            self.win11_colors,
            self.pattern_presets,
            self.pattern_descriptions,
            self.translations,
            scale_factor
        )

        # Connect config tab methods
        config_tab.browse_input_file = self.browse_input_file
        config_tab.browse_output_file = self.browse_output_file
        config_tab.process_file = self.process_file
        config_tab.save_config = self.save_config
        config_tab.load_config = self.load_config
        config_tab.on_sheet_selected = self.on_sheet_selected
        config_tab.update_columns_selection = self.update_columns_selection
        config_tab.select_all_columns = self.select_all_columns
        config_tab.deselect_all_columns = self.deselect_all_columns
        # Note: get_selected_columns is handled by config_tab's own method

        # Connect the browse buttons directly - this ensures they work
        self.connect_browse_buttons(config_tab)

        self.config_tab = config_tab
        self.main_window.add_tab(config_tab.get_frame(), "Konfiguration")

        # Execution tab
        execution_tab = ExecutionTab(self.main_window.notebook, self.win11_colors, scale_factor, self.translations)
        execution_tab.execute_command = self.process_file
        self.execution_tab = execution_tab
        self.main_window.add_tab(execution_tab.get_frame(), self.translations["tab_execution"] if self.translations else "Ausführung")

        # Connect config tab to execution tab and main window for logging and navigation
        self.config_tab.set_execution_tab(self.execution_tab)
        self.config_tab.set_main_gui(self)  # Pass the main GUI instance instead of main_window
        self.config_tab.set_on_columns_changed(lambda: self.execution_tab.update_command_display())

        # Connect execution tab to config tab for command display updates
        self.execution_tab.set_config_tab(self.config_tab)
        self.execution_tab.set_main_gui(self)

        # Regex Builder tab
        regex_builder_tab = RegexBuilderTab(self.main_window.notebook, self.win11_colors, scale_factor, main_gui=self)
        regex_builder_tab.apply_to_main = lambda: self.config_tab.pattern_var.set(regex_builder_tab.regex_pattern_var.get())
        self.regex_builder_tab = regex_builder_tab
        self.main_window.add_tab(regex_builder_tab.get_frame(), "Regex-Builder")

        # Help tab
        help_tab = HelpTab(self.main_window.notebook, self.win11_colors, scale_factor, self.translations, self.switch_language)
        self.main_window.add_tab(help_tab.get_frame(), "Hilfe")

        # Enhance tab appearance to look more like Windows 11
        self.main_window.enhance_tab_appearance()
    
    def browse_input_file(self):
        """
        Öffnet einen Dateidialog zum Auswählen der Eingabedatei
        """
        file_path = browse_file(
            title="Eingabedatei auswählen",
            filetypes=[("Excel Dateien", "*.xlsx;*.xls"), ("Alle Dateien", "*.*")]
        )
        
        if file_path:
            self.config_tab.input_file_var.set(file_path)
            self.config_tab.log_message(f"Eingabedatei ausgewählt: {file_path}")
            self.update_sheet_selection()
            self.update_columns_selection()
            
            # Auto-fill output file path
            if not self.config_tab.output_file_var.get():
                base_name = os.path.splitext(os.path.basename(file_path))[0]
                output_path = os.path.join(os.path.dirname(file_path), f"{base_name}_filtered.xlsx")
                self.config_tab.output_file_var.set(output_path)
    
    def browse_output_file(self):
        """
        Browse for output file
        """
        file_path = browse_save_file(
            title="Ausgabedatei speichern",
            filetypes=[("Excel Dateien", "*.xlsx"), ("Alle Dateien", "*.*")],
            defaultextension=".xlsx"
        )
        
        if file_path:
            self.config_tab.output_file_var.set(file_path)
    
    def load_config(self):
        """
        Load configuration from file
        """
        try:
            config = load_config(self.config_file)
            
            if config:
                self.config_tab.input_file_var.set(config.get("input_file", ""))
                self.config_tab.output_file_var.set(config.get("output_file", ""))
                self.config_tab.pattern_var.set(config.get("pattern", "error|warning|critical"))
                self.config_tab.sheet_var.set(config.get("sheet_name", "Sheet1"))
                self.config_tab.columns_var.set(config.get("columns", ""))
                
                self.config_tab.status_var.set("Konfiguration geladen")
                messagebox.showinfo("Erfolg", "Konfiguration erfolgreich geladen")
                
                # Auto-update sheets and columns if input file is set
                input_file = config.get("input_file", "")
                if input_file and os.path.exists(input_file):
                    self.update_sheet_selection()
                    self.update_columns_selection()
            else:
                self.config_tab.status_var.set("Keine Konfiguration gefunden")
        
        except Exception as e:
            self.config_tab.status_var.set(f"Fehler beim Laden: {e}")
            messagebox.showerror("Fehler", f"Fehler beim Laden der Konfiguration: {e}")
    
    def save_config(self):
        """
        Save current configuration to file
        """
        try:
            config = {
                "input_file": self.config_tab.input_file_var.get(),
                "output_file": self.config_tab.output_file_var.get(),
                "pattern": self.config_tab.pattern_var.get(),
                "sheet_name": self.config_tab.sheet_var.get(),
                "columns": self.config_tab.columns_var.get()
            }
            
            save_config(self.config_file, config)
            self.config_tab.status_var.set("Konfiguration gespeichert")
            messagebox.showinfo("Erfolg", "Konfiguration erfolgreich gespeichert")
            
        except Exception as e:
            self.config_tab.status_var.set(f"Fehler beim Speichern: {e}")
            messagebox.showerror("Fehler", f"Fehler beim Speichern der Konfiguration: {e}")
    
    def process_file(self):
        """
        Process the Excel file with current settings and display detailed professional statistics
        """
        input_file = self.config_tab.input_file_var.get()
        output_file = self.config_tab.output_file_var.get()
        pattern = self.config_tab.pattern_var.get()
        sheet_name = self.config_tab.sheet_var.get()
        columns = self.config_tab.columns_var.get()

        # Validate inputs
        if not input_file:
            self.config_tab.status_var.set("Fehler: Keine Eingabedatei ausgewählt")
            messagebox.showerror("Fehler", "Bitte wählen Sie eine Eingabedatei aus")
            return

        if not output_file:
            self.config_tab.status_var.set("Fehler: Keine Ausgabedatei ausgewählt")
            messagebox.showerror("Fehler", "Bitte wählen Sie eine Ausgabedatei aus")
            return

        # Check if pattern is required (required when regex is enabled)
        regex_enabled = self.config_tab.regex_enabled_var.get()
        if not pattern and regex_enabled:
            self.config_tab.status_var.set("Fehler: Kein Filtermuster angegeben")
            messagebox.showerror("Fehler", "Bitte geben Sie ein Filtermuster ein")
            return

        # Parse columns using the config tab's method
        if hasattr(self.config_tab, 'get_selected_columns'):
            column_list = self.config_tab.get_selected_columns()
        else:
            column_list = None

        if not column_list:  # If no columns selected, use all
            column_list = None

        try:
            # Start execution with progress indication
            self.execution_tab.start_execution()
            self.config_tab.status_var.set("🔬 Erweiterte Excel-Analyse läuft...")

            # Professional progress messages
            self.execution_tab.update_progress(5, "🔬 Initialisiere erweiterte Analyse-Engine...")
            self.root.update()

            self.execution_tab.update_progress(15, "📊 Lade und analysiere Excel-Dateistruktur...")
            self.root.update()

            # Get numeric filter settings from config tab
            numeric_filter = self.config_tab.get_numeric_filter_settings()

            # Create ExcelFilter with advanced statistics collection
            excel_filter = ExcelFilter(
                input_file=input_file,
                output_file=output_file,
                pattern=pattern,
                sheet_name=sheet_name if sheet_name else None,
                columns=column_list if column_list else None,
                numeric_filter=numeric_filter,
                language=self.translations.current_language
            )

            self.execution_tab.update_progress(25, "🔍 Führe intelligente Mustererkennung durch...")
            self.root.update()

            self.execution_tab.update_progress(40, "⚡ Wende fortschrittliche Filteralgorithmen an...")
            self.root.update()

            self.execution_tab.update_progress(60, "📈 Berechne Performance-Metriken und Statistiken...")
            self.root.update()

            self.execution_tab.update_progress(80, "💾 Optimiere und komprimiere Ausgabedatei...")
            self.root.update()

            # Execute the filtering process
            success, error_msg = excel_filter.process()

            self.execution_tab.update_progress(95, "📊 Erstelle detaillierte Verarbeitungsberichte...")

            if success:
                self.execution_tab.update_progress(100, "🎉 Excel-Filter-Analyse erfolgreich abgeschlossen!")

                stats = excel_filter.get_statistics()

                # Log detailed statistics directly to the execution tab log
                self.execution_tab.log_message("=" * 60)
                self.execution_tab.log_message("EXCEL-FILTER-ANALYSE ERFOLGREICH ABGESCHLOSSEN!")
                self.execution_tab.log_message("=" * 60)

                # File statistics
                self.execution_tab.log_message("DATEI-STATISTIKEN:")
                self.execution_tab.log_message(f"   Eingabedatei: {stats['input_file_size'] / (1024*1024):.2f} MB")
                self.execution_tab.log_message(f"   Ausgabedatei: {stats['output_file_size'] / (1024*1024):.2f} MB")
                if stats['compression_ratio'] > 0:
                    compression_pct = (stats['compression_ratio'] - 1) * 100
                    self.execution_tab.log_message(f"   Kompressionsrate: {compression_pct:+.1f}%")

                # Data processing statistics
                self.execution_tab.log_message("\nDATENVERARBEITUNG:")
                self.execution_tab.log_message(f"   Eingabe: {stats['input_rows']:,} Zeilen × {stats['input_columns']} Spalten")
                self.execution_tab.log_message(f"   Ausgabe: {stats['output_rows']:,} Zeilen × {stats['output_columns']} Spalten")
                if stats['input_rows'] > 0:
                    reduction_pct = (stats['rows_removed'] / stats['input_rows']) * 100
                    self.execution_tab.log_message(f"   Zeilen reduziert: {stats['rows_removed']:,} ({reduction_pct:.1f}%)")

                # Applied filters
                if stats['filters_applied']:
                    self.execution_tab.log_message(f"\n🎯 ANGEWENDETE FILTER: {', '.join(stats['filters_applied'])}")
                    if stats['input_rows'] > 0:
                        retention_rate = (stats['rows_filtered'] / stats['input_rows']) * 100
                        self.execution_tab.log_message(f"   Filter-Effizienz: {retention_rate:.1f}% Zeilen behalten")

                # Performance metrics
                self.execution_tab.log_message("\n⚡ PERFORMANCE-METRIKEN:")
                self.execution_tab.log_message(f"   Verarbeitungszeit: {stats['processing_time_seconds']:.2f} Sekunden")
                self.execution_tab.log_message(f"   Speicherverbrauch: {stats['memory_usage_mb']:.2f} MB")
                if stats['processing_time_seconds'] > 0 and stats['input_rows'] > 0:
                    rows_per_second = stats['input_rows'] / stats['processing_time_seconds']
                    self.execution_tab.log_message(f"   Geschwindigkeit: {rows_per_second:.0f} Zeilen/Sekunde")

                self.execution_tab.log_message("\n💾 Ausgabedatei wird automatisch geöffnet...")
                self.execution_tab.log_message("=" * 60)

                self.config_tab.status_var.set("✅ Erweiterte Analyse erfolgreich abgeschlossen")

                # Open the output file
                self.open_file(output_file)
                self.execution_tab.finish_execution(success=True)
            else:
                # Enhanced error handling with detailed error messages
                error_title = "Fehler bei der Excel-Filter-Analyse"
                detailed_error = error_msg if error_msg else "Unbekannter Fehler"
                
                self.execution_tab.update_progress(100, "Analyse fehlgeschlagen")
                self.config_tab.status_var.set("Erweiterte Analyse fehlgeschlagen")
                
                # Log detailed error information
                self.execution_tab.log_message("=" * 60)
                self.execution_tab.log_message("EXCEL-FILTER-ANALYSE FEHLGESCHLAGEN!")
                self.execution_tab.log_message("=" * 60)
                self.execution_tab.log_message(f"FEHLERDETAILS:")
                self.execution_tab.log_message(f"   Fehler: {detailed_error}")
                self.execution_tab.log_message("=" * 60)
                
                messagebox.showerror(error_title, f"Fehler bei der Excel-Filter-Analyse:\n\n{detailed_error}")
                self.execution_tab.finish_execution(success=False)

        except Exception as e:
            # Enhanced exception handling with more details
            error_details = f"{type(e).__name__}: {e}"
            self.execution_tab.update_progress(100, f"Kritischer Fehler in Analyse-Engine")
            self.config_tab.status_var.set(f"Analyse-Engine Fehler")
            
            # Log detailed exception information
            self.execution_tab.log_message("=" * 60)
            self.execution_tab.log_message("KRITISCHER FEHLER IN DER ANALYSE-ENGINE!")
            self.execution_tab.log_message("=" * 60)
            self.execution_tab.log_message(f"FEHLERDETAILS:")
            self.execution_tab.log_message(f"   Fehler: {error_details}")
            self.execution_tab.log_message("=" * 60)
            
            messagebox.showerror("Kritischer Fehler", f"Fehler in der Analyse-Engine:\n\n{error_details}")
            self.execution_tab.finish_execution(success=False)
    
    def open_file(self, file_path):
        """
        Open a file with the default application
        """
        try:
            if sys.platform == "win32":
                os.startfile(file_path)
            elif sys.platform == "darwin":
                subprocess.run(["open", file_path])
            else:
                subprocess.run(["xdg-open", file_path])
        except Exception as e:
            messagebox.showerror("Fehler", f"Fehler beim Öffnen der Datei: {e}")
    


    def switch_language(self, new_language):
        """
        Switch the application language

        Args:
            new_language: New language code ('en' or 'de')
        """
        try:
            # Update translations
            self.translations.set_language(new_language)

            # Update window title
            self.root.title(self.translations["app_title"])

            # Update pattern presets and descriptions
            self.pattern_presets = {
                self.translations["errors_and_warnings"]: r"error|warning|critical",
                self.translations["errors_only"]: r"error",
                self.translations["warnings_only"]: r"warning",
                self.translations["critical_errors"]: r"critical",
                self.translations["numbers_100_199"]: r"1\d{2}",
                self.translations["email_addresses"]: r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
                self.translations["phone_numbers"]: r"\+?[0-9\s-]{10,}",
                self.translations["date_yyyy_mm_dd"]: r"\d{4}-\d{2}-\d{2}"
            }

            self.pattern_descriptions = {
                self.translations["errors_and_warnings"]: self.translations["desc_errors_and_warnings"],
                self.translations["errors_only"]: self.translations["desc_errors_only"],
                self.translations["warnings_only"]: self.translations["desc_warnings_only"],
                self.translations["critical_errors"]: self.translations["desc_critical_errors"],
                self.translations["numbers_100_199"]: self.translations["desc_numbers_100_199"],
                self.translations["email_addresses"]: self.translations["desc_email_addresses"],
                self.translations["phone_numbers"]: self.translations["desc_phone_numbers"],
                self.translations["date_yyyy_mm_dd"]: self.translations["desc_date_yyyy_mm_dd"]
            }

            # Update tab names
            tab_names = [
                self.translations["tab_config"],
                self.translations["tab_execution"],
                self.translations["tab_regex_builder"],
                self.translations["tab_help"]
            ]

            for i, tab_name in enumerate(tab_names):
                try:
                    self.main_window.notebook.tab(i, text=tab_name)
                except:
                    pass  # Tab might not exist yet



            # Show success message
            messagebox.showinfo(
                self.translations["success"],
                f"{self.translations['language']} {self.translations['english'] if new_language == 'en' else self.translations['german']}"
            )

        except Exception as e:
            messagebox.showerror(
                self.translations["error"],
                f"{self.translations['error']}: {e}"
            )

    def load_presets(self):
        """
        Load pattern presets from file
        """
        try:
            if os.path.exists(self.presets_file):
                with open(self.presets_file, 'r', encoding='utf-8') as f:
                    presets_data = json.load(f)
                    presets = presets_data.get('presets', {})
                    descriptions = presets_data.get('descriptions', {})
            else:
                # Default presets if file doesn't exist
                presets = {
                    self.translations["errors_and_warnings"]: r"error|warning|critical",
                    self.translations["errors_only"]: r"error",
                    self.translations["warnings_only"]: r"warning",
                    self.translations["critical_errors"]: r"critical",
                    self.translations["numbers_100_199"]: r"1\d{2}",
                    self.translations["email_addresses"]: r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
                    self.translations["phone_numbers"]: r"\+?[0-9\s-]{10,}",
                    self.translations["date_yyyy_mm_dd"]: r"\d{4}-\d{2}-\d{2}"
                }
                descriptions = {
                    self.translations["errors_and_warnings"]: self.translations["desc_errors_and_warnings"],
                    self.translations["errors_only"]: self.translations["desc_errors_only"],
                    self.translations["warnings_only"]: self.translations["desc_warnings_only"],
                    self.translations["critical_errors"]: self.translations["desc_critical_errors"],
                    self.translations["numbers_100_199"]: self.translations["desc_numbers_100_199"],
                    self.translations["email_addresses"]: self.translations["desc_email_addresses"],
                    self.translations["phone_numbers"]: self.translations["desc_phone_numbers"],
                    self.translations["date_yyyy_mm_dd"]: self.translations["desc_date_yyyy_mm_dd"]
                }
                # Save default presets
                self.save_presets(presets, descriptions)
            return presets, descriptions
        except Exception as e:
            print(f"Error loading presets: {e}")
            # Return empty presets on error
            return {}, {}

    def save_presets(self, presets=None, descriptions=None):
        """
        Save pattern presets to file
        """
        try:
            if presets is None:
                presets = self.pattern_presets
            if descriptions is None:
                descriptions = self.pattern_descriptions

            presets_data = {
                'presets': presets,
                'descriptions': descriptions
            }

            with open(self.presets_file, 'w', encoding='utf-8') as f:
                json.dump(presets_data, f, indent=2, ensure_ascii=False)
        except Exception as e:
            print(f"Error saving presets: {e}")

    def manage_presets(self):
        """
        Open presets management dialog
        """
        PresetsManagerDialog(self.root, self)

    def run(self):
        """
        Run the main application loop
        """
        self.main_window.run()


class PresetsManagerDialog:
    """
    Dialog for managing pattern presets
    """

    def __init__(self, parent, main_gui):
        """
        Initialize the presets manager dialog

        Args:
            parent: Parent window
            main_gui: Main GUI instance
        """
        self.parent = parent
        self.main_gui = main_gui
        self.dialog = tk.Toplevel(parent)
        self.dialog.title("Voreingestellte Muster verwalten")
        self.dialog.geometry("600x500")
        self.dialog.resizable(True, True)
        self.dialog.transient(parent)
        self.dialog.grab_set()

        # Get scaling factor from main GUI if available
        self.scale_factor = getattr(main_gui, 'main_window', None)
        if self.scale_factor and hasattr(self.scale_factor, 'scale_factor'):
            self.scale_factor = self.scale_factor.scale_factor
        else:
            self.scale_factor = 1.0

        # Variables
        self.selected_preset_var = tk.StringVar()
        self.name_var = tk.StringVar()
        self.pattern_var = tk.StringVar()
        self.description_var = tk.StringVar()

        self.create_widgets()
        self.load_presets_list()
        self.center_dialog()

    def create_widgets(self):
        """
        Create dialog widgets
        """
        # Main frame
        main_frame = ttk.Frame(self.dialog, padding="10")
        main_frame.pack(fill=tk.BOTH, expand=True)

        # Title
        title_label = ttk.Label(main_frame, text="📝 Voreingestellte Regex-Muster verwalten",
                               font=('Helvetica', 12, 'bold'))
        title_label.pack(pady=(0, 10))

        # Content frame
        content_frame = ttk.Frame(main_frame)
        content_frame.pack(fill=tk.BOTH, expand=True)

        # Left side - Presets list
        left_frame = ttk.LabelFrame(content_frame, text="Vorhandene Muster", padding="5")
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 5))

        # Presets listbox with scrollbar
        listbox_frame = ttk.Frame(left_frame)
        listbox_frame.pack(fill=tk.BOTH, expand=True, pady=5)

        scrollbar = ttk.Scrollbar(listbox_frame)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        self.presets_listbox = tk.Listbox(
            listbox_frame,
            selectmode=tk.SINGLE,
            yscrollcommand=scrollbar.set,
            font=('Segoe UI', int(10 * self.scale_factor))
        )
        self.presets_listbox.pack(fill=tk.BOTH, expand=True)
        self.presets_listbox.bind('<<ListboxSelect>>', self.on_preset_selected)

        scrollbar.config(command=self.presets_listbox.yview)

        # Buttons for presets list
        buttons_frame = ttk.Frame(left_frame)
        buttons_frame.pack(fill=tk.X, pady=(5, 0))

        ttk.Button(buttons_frame, text="➕ Neu", command=self.add_preset).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(buttons_frame, text="🗑️ Löschen", command=self.delete_preset).pack(side=tk.LEFT)

        # Right side - Preset editor
        right_frame = ttk.LabelFrame(content_frame, text="Muster bearbeiten", padding="5")
        right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(5, 0))

        # Name field
        name_frame = ttk.Frame(right_frame)
        name_frame.pack(fill=tk.X, pady=2)
        ttk.Label(name_frame, text="Name:").pack(side=tk.LEFT)
        name_entry = ttk.Entry(name_frame, textvariable=self.name_var, font=('Segoe UI', 12))
        name_entry.pack(side=tk.RIGHT, fill=tk.X, expand=True, padx=(5, 0))

        # Pattern field
        pattern_frame = ttk.Frame(right_frame)
        pattern_frame.pack(fill=tk.X, pady=2)
        ttk.Label(pattern_frame, text="Regex-Muster:").pack(side=tk.LEFT, anchor=tk.N)
        pattern_entry = ttk.Entry(pattern_frame, textvariable=self.pattern_var, font=('Segoe UI', 12))
        pattern_entry.pack(side=tk.RIGHT, fill=tk.X, expand=True, padx=(5, 0))

        # Description field
        desc_frame = ttk.Frame(right_frame)
        desc_frame.pack(fill=tk.X, pady=2)
        ttk.Label(desc_frame, text="Beschreibung:").pack(side=tk.LEFT, anchor=tk.N)
        desc_entry = tk.Text(desc_frame, height=3, wrap=tk.WORD, font=('Segoe UI', 12))
        desc_entry.pack(side=tk.RIGHT, fill=tk.X, expand=True, padx=(5, 0))
        # Connect description text widget to variable
        desc_entry.bind('<KeyRelease>', lambda e: self.description_var.set(desc_entry.get(1.0, tk.END).strip()))

        # Action buttons
        action_frame = ttk.Frame(right_frame)
        action_frame.pack(fill=tk.X, pady=(10, 0))

        ttk.Button(action_frame, text="💾 Speichern", command=self.save_preset).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(action_frame, text="🔄 Zurücksetzen", command=self.reset_form).pack(side=tk.LEFT)

        # Dialog buttons
        dialog_buttons = ttk.Frame(main_frame)
        dialog_buttons.pack(fill=tk.X, pady=(10, 0))

        ttk.Button(dialog_buttons, text="✅ OK", command=self.on_ok).pack(side=tk.RIGHT, padx=(5, 0))
        ttk.Button(dialog_buttons, text="❌ Abbrechen", command=self.on_cancel).pack(side=tk.RIGHT)

    def load_presets_list(self):
        """
        Load presets into the listbox
        """
        self.presets_listbox.delete(0, tk.END)
        for name in self.main_gui.pattern_presets.keys():
            self.presets_listbox.insert(tk.END, name)

    def on_preset_selected(self, event):
        """
        Handle preset selection from listbox
        """
        selection = self.presets_listbox.curselection()
        if selection:
            index = selection[0]
            preset_name = self.presets_listbox.get(index)

            self.selected_preset_var.set(preset_name)
            self.name_var.set(preset_name)
            self.pattern_var.set(self.main_gui.pattern_presets.get(preset_name, ""))
            self.description_var.set(self.main_gui.pattern_descriptions.get(preset_name, ""))

            # Update description text widget
            for child in self.dialog.winfo_children():
                if isinstance(child, ttk.Frame):
                    for subchild in child.winfo_children():
                        if isinstance(subchild, ttk.Frame):
                            for widget in subchild.winfo_children():
                                if isinstance(widget, tk.Text):
                                    widget.delete(1.0, tk.END)
                                    widget.insert(1.0, self.description_var.get())

    def add_preset(self):
        """
        Add a new preset
        """
        self.selected_preset_var.set("")
        self.name_var.set("")
        self.pattern_var.set("")
        self.description_var.set("")

        # Clear description text widget
        for child in self.dialog.winfo_children():
            if isinstance(child, ttk.Frame):
                for subchild in child.winfo_children():
                    if isinstance(subchild, ttk.Frame):
                        for widget in subchild.winfo_children():
                            if isinstance(widget, tk.Text):
                                widget.delete(1.0, tk.END)

    def delete_preset(self):
        """
        Delete the selected preset
        """
        selection = self.presets_listbox.curselection()
        if not selection:
            messagebox.showwarning("Warnung", "Bitte wählen Sie zuerst ein Muster aus")
            return

        preset_name = self.presets_listbox.get(selection[0])

        if messagebox.askyesno("Löschen bestätigen", f"Möchten Sie das Muster '{preset_name}' wirklich löschen?"):
            # Remove from dictionaries
            if preset_name in self.main_gui.pattern_presets:
                del self.main_gui.pattern_presets[preset_name]
            if preset_name in self.main_gui.pattern_descriptions:
                del self.main_gui.pattern_descriptions[preset_name]

            # Save changes
            self.main_gui.save_presets()

            # Reload list
            self.load_presets_list()

            # Clear form
            self.reset_form()

            messagebox.showinfo("Erfolg", f"Muster '{preset_name}' wurde gelöscht")

    def save_preset(self):
        """
        Save the current preset
        """
        name = self.name_var.get().strip()
        pattern = self.pattern_var.get().strip()
        description = self.description_var.get().strip()

        if not name:
            messagebox.showerror("Fehler", "Bitte geben Sie einen Namen ein")
            return

        if not pattern:
            messagebox.showerror("Fehler", "Bitte geben Sie ein Regex-Muster ein")
            return

        # Check if name already exists (when not editing existing)
        selected_preset = self.selected_preset_var.get()
        if selected_preset and selected_preset != name:
            # Renaming - remove old name
            if selected_preset in self.main_gui.pattern_presets:
                del self.main_gui.pattern_presets[selected_preset]
            if selected_preset in self.main_gui.pattern_descriptions:
                del self.main_gui.pattern_descriptions[selected_preset]
        elif not selected_preset and name in self.main_gui.pattern_presets:
            if not messagebox.askyesno("Überschreiben", f"Ein Muster mit dem Namen '{name}' existiert bereits. Möchten Sie es überschreiben?"):
                return

        # Save preset
        self.main_gui.pattern_presets[name] = pattern
        self.main_gui.pattern_descriptions[name] = description

        # Save to file
        self.main_gui.save_presets()

        # Reload list
        self.load_presets_list()

        # Select the saved preset
        if name in self.main_gui.pattern_presets:
            for i in range(self.presets_listbox.size()):
                if self.presets_listbox.get(i) == name:
                    self.presets_listbox.selection_clear(0, tk.END)
                    self.presets_listbox.selection_set(i)
                    break

        self.selected_preset_var.set(name)
        messagebox.showinfo("Erfolg", f"Muster '{name}' wurde gespeichert")

    def reset_form(self):
        """
        Reset the form to empty state
        """
        self.selected_preset_var.set("")
        self.name_var.set("")
        self.pattern_var.set("")
        self.description_var.set("")

        # Clear description text widget
        for child in self.dialog.winfo_children():
            if isinstance(child, ttk.Frame):
                for subchild in child.winfo_children():
                    if isinstance(subchild, ttk.Frame):
                        for widget in subchild.winfo_children():
                            if isinstance(widget, tk.Text):
                                widget.delete(1.0, tk.END)

    def on_ok(self):
        """
        Handle OK button - save current changes and close
        """
        # Save any pending changes
        if self.name_var.get().strip():
            self.save_preset()

        # Update the config tab with new presets
        if hasattr(self.main_gui, 'config_tab'):
            self.main_gui.config_tab.pattern_presets = self.main_gui.pattern_presets
            self.main_gui.config_tab.pattern_descriptions = self.main_gui.pattern_descriptions
            # Refresh the combobox values using the dedicated method
            if hasattr(self.main_gui.config_tab, 'refresh_preset_combobox'):
                self.main_gui.config_tab.refresh_preset_combobox()

        self.dialog.destroy()

    def on_cancel(self):
        """
        Handle Cancel button
        """
        self.dialog.destroy()

    def center_dialog(self):
        """
        Center the dialog on the parent window
        """
        self.dialog.update_idletasks()
        width = self.dialog.winfo_width()
        height = self.dialog.winfo_height()
        x = (self.parent.winfo_width() // 2) - (width // 2) + self.parent.winfo_x()
        y = (self.parent.winfo_height() // 2) - (height // 2) + self.parent.winfo_y()
        self.dialog.geometry(f'{width}x{height}+{x}+{y}')


def main():
    """
    Main function to launch the GUI
    """
    root = tk.Tk()
    app = ExcelFilterGUI(root)
    app.run()


if __name__ == "__main__":
    main()
