"""
Frame Filter Module

This module provides a GUI panel for filtering frame retrieval analysis data.
It contains dropdown menus and input fields for various filter criteria including
target selection, chemistry, temperature-pressure profiles, and instrument settings.
"""

import os

from GUIBRUSHR.GUI.DataInterface.DBSQLite3 import DBSQLite3
from GUIBRUSHR.GUI.LAYOUT.MyPanel import MyPanel
from GUIBRUSHR.General_Constants.FunctionsAndConstants.Constant_Variables import ConstantVariables
from GUIBRUSHR.GUI.WIDGET.MyDropDown import MyDropdown
from GUIBRUSHR.GUI.WIDGET.MyTextField import MyTextField
from GUIBRUSHR.GUI.WIDGET.MyButton import MyButton
from GUIBRUSHR.GUI.DataInterface.DataInterface import get_target_list
from GUIBRUSHR.General_Constants.Classes.HelpButton import HelpButton


class FrameFilter(MyPanel):
    """
    A GUI panel for filtering frame retrieval analysis data.
    
    This class creates a comprehensive filter interface with dropdown menus
    for various scientific parameters and instrument selection capabilities.
    Inherits from MyPanel to provide basic panel functionality.
    """

    def __init__(self, parent, row, column, color, width, path_default, **kwargs):
        """
        Initialize the FrameFilter panel with all filter components.
        
        Creates dropdown menus for scientific parameters, instrument selection,
        and user input fields. Maintains the exact initialization sequence
        as the original code.
        """
        super().__init__(parent, color, row, column, width=width, **kwargs)
        
        # Initialize control flag (used to prevent premature operations)
        self.global_exc = 0
        
        # Store references and configuration
        self.path_folder_targets = parent.parent.frame_input.frame_path.path_folder_targets.get_text()
        self.parent = parent
        self.color = color
        
        # Initialize all filter components
        self._create_scientific_parameter_filters()
        self._create_instrument_controls(path_default)
        self._create_user_controls()
        self._create_help_button()
        self._create_search_button()

        # Enable operations after full initialization
        self.global_exc = 1

    def _create_scientific_parameter_filters(self):
        """Create dropdown filters for scientific parameters."""
        # Target selection
        target_list = get_target_list(self.path_folder_targets)
        self.dropdown_target = MyDropdown(
            self, 0, 1, target_list, "Target:", 
            color=self.color, columnspan=2
        )
        
        # Chemistry filter
        self.dropdown_chemistry = MyDropdown(
            self, 0, 3, ConstantVariables.LIST_CHEMISTRY_TABLE_FILTER, 
            "Chemistry:", columnspan=2, color=self.color
        )
        
        # Temperature-Pressure profile filter
        self.dropdown_t_p_profile = MyDropdown(
            self, 0, 5, ConstantVariables.LIST_PT_PROFILE_TABLE_FILTER, 
            "T-P profile:", columnspan=2, color=self.color
        )
        
        # Eccentricity and Opacity filter
        self.dropdown_ecc_opi = MyDropdown(
            self, 0, 7, ConstantVariables.LIST_ECC_OPI_TABLE_FILTER, 
            "Ecc Opi:", columnspan=2, color=self.color
        )
        
        # Scattering filter
        self.dropdown_scattering = MyDropdown(
            self, 0, 9, ConstantVariables.LIST_SCATTERING_TABLE_FILTER, 
            "Scattering:", columnspan=2, color=self.color
        )
        
        # Resolution filter
        self.dropdown_resolution = MyDropdown(
            self, 0, 11, ConstantVariables.LIST_RESOLUTION_TABLE_FILTER, 
            "Resolution:", columnspan=2, color=self.color
        )
        
        # Retrieval mode filter
        self.dropdown_retrieval_mode = MyDropdown(
            self, 0, 13, ConstantVariables.LIST_RETRIEVAL_MODE_FILTER,
            "Retrieval Model:", columnspan=2, color=self.color
        )
        
        # Radiative transfer mode filter (transmission or emission)
        self.dropdown_rad_mode = MyDropdown(
            self, 0, 15, ConstantVariables.LIST_RAD_MODE_FILTER,
            "Rad. Transf. Mode:", initial_value=0,
            color=self.color, columnspan=2
        )

    def _create_instrument_controls(self, path_default):
        """Create instrument selection and management controls."""
        # Initialize instrument list with default value
        list_instrument = ["None"]
        
        # Retrieve available instruments from database
        db = DBSQLite3(path_default)
        temp_list, _, _, _, _ = db.get_instruments()
        db.close_DB()
        
        # Add retrieved instruments to the list if available
        if temp_list is not None:
            list_instrument = list_instrument + temp_list
        
        # Create instrument selection dropdown
        self.dropdown_instruments = MyDropdown(
            self, 1, 1, list_instrument,
            "Instruments:", initial_value=0,
            color=self.color, columnspan=2
        )
        
        # Create text field for instrument input/display
        self.textfield_instruments = MyTextField(
            self, 1, 3, text="None", columnspan=2, 
            width=30, color=self.color
        )
        
        # Create button to add selected instrument
        self.button_instrument = MyButton(
            self, 1, 5, "ADD INSTRUMENT", "#74ff69", 
            command=self.add_instrument
        )

    def _create_user_controls(self):
        """Create user-related input controls."""
        # Get current system username
        username = os.environ.get("USER")

        # Create username input field
        self.username_t = MyTextField(
            self, 1, 7, label_text="User:", text=username,
            columnspan=2, width=20, color=self.color
        )

    def _create_help_button(self):
        """Create help button with comprehensive documentation for filters and table."""
        # Create comprehensive help text dictionary covering all filters and table functionality
        help_text = {
            "Target": "Select the target exoplanet or stellar system to filter retrieval runs. This dropdown lists all targets available in your target folder. Select 'All' to display retrieval runs for all targets in the database.",

            "Chemistry": "Filter retrieval runs by atmospheric chemistry model. Options include 'Equilibrium' (chemical equilibrium calculations), 'Free' (free chemistry with independent molecular abundances), or 'All' to display runs regardless of chemistry type.",

            "T-P profile": "Filter by temperature-pressure profile parameterization used in the retrieval. Common options include 'Guillot' (analytical T-P profile), 'Gradient' (gradient-based profile), 'Modif' (modified profiles), or 'All' to show all T-P profile types.",

            "Ecc Opi": "Filter by eccentricity and argument of periastron (ω) treatment. Options specify whether orbital eccentricity and ω were fixed or fitted as free parameters during the retrieval. Select 'All' to ignore this filter.",

            "Scattering": "Filter by atmospheric scattering treatment. Options include whether Rayleigh scattering, cloud scattering, or both were included in the radiative transfer model. Select 'All' to display runs with any scattering configuration.",

            "Resolution": "Filter by spectral resolution used in the retrieval. This distinguishes between high-resolution (HR) and low-resolution (LR) spectroscopy retrievals. Select 'All' to show results from all resolution modes.",

            "Retrieval Model": "Filter by the retrieval model framework used. Options specify whether the retrieval used a specific model configuration, combined models, or other specialized frameworks. Select 'All' to display all model types.",

            "Rad. Transf. Mode": "Filter by radiative transfer mode. Select 'Transmission' for transmission spectroscopy retrievals (transiting exoplanets), 'Emission' for emission spectroscopy retrievals (secondary eclipses or direct imaging), or 'All' to show both types.",

            "Instruments": "Select instruments used in the retrieval from the dropdown. Multiple instruments can be added by selecting each one and clicking 'ADD INSTRUMENT'. The selected instruments appear in the text field as a comma-separated list. The database will only return retrievals matching all selected instruments.",

            "ADD INSTRUMENT button": "Click this button to add the currently selected instrument from the dropdown to the instrument filter list. Instruments are appended to the text field with comma separation. You can manually edit the text field to remove or reorder instruments.",

            "User": "Filter retrieval runs by username. By default, this field shows your current system username. You can modify it to search for retrievals created by other users, or use wildcards for broader searches.",

            "SEARCH button": "Click to execute the search query with the current filter settings. The results table below will update to display all retrieval runs matching your filter criteria. Filters set to 'All' or left empty are ignored in the search.",

            "Results Table - Date column": "Displays the date and timestamp when each retrieval run was created. Format is typically YYYY-MM-DD_HH-MM-SS. This serves as a unique identifier for each retrieval run in the results folder.",

            "Results Table - Best parameters column": "Shows the names of parameters that were fitted in the retrieval (free parameters). This includes atmospheric parameters (temperature profile, molecular abundances, cloud properties) and any fitted system parameters. Molecular names are abbreviated for readability.",

            "Results Table - Priors column": "Lists the names of parameters that had Gaussian priors applied during the retrieval. Priors constrain parameter values to physically reasonable ranges and can incorporate previous knowledge about the system.",

            "Results Table - Order selection column": "Indicates which spectral order selection was used in the retrieval. This specifies the folder name containing the spectral orders processed for the analysis. 'full' means all available orders were used.",

            "Results Table - Nights column": "Shows which observation nights were included in the retrieval. Nights are identified by date or night identifier. Multiple nights are comma-separated. Including multiple nights improves signal-to-noise but requires careful handling of systematic differences between nights.",

            "Results Table - Tell removal method column": "Displays the telluric removal method applied to the high-resolution spectra before retrieval. Methods include PCA-based approaches (e.g., 'PCA', 'SYSREM'), polynomial fitting, or other telluric correction algorithms.",

            "Results Table - Rad mode column": "Shows the radiative transfer mode used in the retrieval: 'Transmission' for transmission spectroscopy or 'Emission' for emission spectroscopy. This must match the observational geometry.",

            "Results Table - File exists column": "Indicates whether the retrieval output files exist on disk. 'YES' means the retrieval results (chains, corner plots, model spectra) are available in the results folder. 'NO' means the database entry exists but files are missing or were deleted.",

            "Table functionality": "Click on any row in the results table to select it. Selected rows can be loaded for analysis in the corner plot and model plot panels. The table supports sorting by clicking column headers. Use the scroll bar to navigate through many results."
        }

        # Create help button positioned before the search button
        self.help_button = HelpButton(
            self, 0, 19,
            "Retrieval Search Filters and Results Table Help",
            help_text,
            columnspan=1, rowspan=2,
        )

    def _create_search_button(self):
        """Create the main search button."""
        # Create search button (command will be set by parent)
        self.search_button = MyButton(
            self, 1, 15, "SEARCH", "#BBFF33", command=None, columnspan=2
        )
        # Note: command=parent.frame_table.update_table will be set externally

    def modify_target_list(self, target_list):
        """
        Update the target dropdown with a new list of targets.
        
        This method cleans the existing target dropdown widget and creates
        a new one with the provided target list.
        """
        # Clean existing target dropdown
        self.dropdown_target.clean_widget()
        
        # Create new target dropdown with updated list
        self.dropdown_target = MyDropdown(
            self, 0, 0, target_list, "Target:", 
            color=self.color, columnspan=2
        )

    def add_instrument(self):
        """
        Add the selected instrument to the instrument text field.
        
        This method appends the currently selected instrument from the dropdown
        to the instrument text field, using comma separation for multiple instruments.
        Only operates when global_exc flag is set (after full initialization).
        """
        if self.global_exc:
            # Get current text from instrument field
            last_text = self.textfield_instruments.get_text()
            
            # Determine appropriate prefix (comma for additional instruments)
            prefix = "" if last_text == "" else ","
            
            # Create new line with selected instrument
            new_line = prefix + self.dropdown_instruments.get_value()
            
            # Insert the new instrument into the text field
            self.textfield_instruments.insert_text(last_text + new_line)
