"""
Frame Display Module

This module provides the FrameDisplay class for displaying frame configuration
details in the GUI. It handles the visualization of frame analysis parameters
and results through a dedicated panel interface.
"""

from pathlib import Path
from pandas import read_csv

from GUIBRUSHR.GUI.WIDGET.MyButton import MyButton
from GUIBRUSHR.GUI.LAYOUT.MyPanel import MyPanel
from GUIBRUSHR.GUI.WIDGET.MyFigure import MyFigure
from GUIBRUSHR.General_Constants.FunctionsAndConstants.Constant_Variables import ConstantVariables
from GUIBRUSHR.General_Constants.FunctionsAndConstants.general_functions import get_csv_value


def insert_newlines(text, every=50):
    """
    Insert newlines in a string at regular intervals.
    
    Args:
        text: The input string to process
        every: Number of characters after which to insert newlines (default: 50)
        
    Returns:
        String with newlines inserted at specified intervals
    """
    return '\n\t\t\t'.join(text[i:i + every] for i in range(0, len(text), every))


def _build_configuration_message(values, model_rep):
    """
    Build the configuration message string for display.

    Args:
        values: Dictionary containing extracted filter values
        model_rep: Model reprocessing value from CSV

    Returns:
        Formatted message string for display
    """
    message = (
        f"ID:\t\t\t{values['id']}\n"
        f"Order selection:\t\t{values['order_sel']}\n"
        f"Nights:\t\t\t{values['nights']}\n"
        f"Telluric method removal:\t{values['method']}\n"
        f"Instruments:\t\t{values['instruments']}\n"
        f"Radiative mode:\t\t{values['rad_mode']}\n"
        f"Chemistry:\t\t{values['modes']}\n"
        f"T-P profile:\t\t{values['atmos']}\n"
        f"Scattering:\t\t{values['scatterings']}\n"
        f"Eccentricity:\t\t{values['eccs']}\n"
        f"Resolution:\t\t{values['resolutions']}\n"
        f"Fitted params:\t\t{values['params']}\n"
        f"Fixed params:\t\t{values['fixed_params']}\n"
        f"Molecules Equilibrium:\t{values['molec_eq']}\n"
        f"Sigma Priors:\t\t{values['priors_complete']}\n"
        f"Model Reprocessing:\t{model_rep}"
    )

    return message


def _format_parameter_strings(params, fixed_params):
    """
    Format parameter strings by adding spaces after commas and inserting newlines.

    Args:
        params: String containing fitted parameters
        fixed_params: String containing fixed parameters

    Returns:
        Tuple of formatted parameter strings (params, fixed_params)
    """
    # Format fitted parameters
    formatted_params = params.replace(",", ", ")
    formatted_params = insert_newlines(formatted_params, 80)

    # Format fixed parameters
    formatted_fixed = fixed_params.replace(",", ", ")
    formatted_fixed = insert_newlines(formatted_fixed, 80)

    return formatted_params, formatted_fixed


def _extract_filter_values(arr_values):
    """
    Extract filter values from the array using constant indices.

    Args:
        arr_values: Array containing filter table values

    Returns:
        Dictionary containing extracted values with descriptive keys
    """
    # Extract all required values from the filter table
    filter_dict = ConstantVariables.DICT_FILTER_TABLE

    extracted_values = {
        'id': arr_values[filter_dict["ID"]["index"]],
        'order_sel': arr_values[filter_dict["Order_Sel"]["index"]],
        'nights': arr_values[filter_dict["Nights"]["index"]],
        'method': arr_values[filter_dict["Method"]["index"]],
        'instruments': arr_values[filter_dict["#Instruments"]["index"]],
        'rad_mode': arr_values[filter_dict["Rad Mode"]["index"]],
        'modes': arr_values[filter_dict["#modes"]["index"]],
        'atmos': arr_values[filter_dict["#atmos"]["index"]],
        'scatterings': arr_values[filter_dict["#scatterings"]["index"]],
        'eccs': arr_values[filter_dict["#eccs"]["index"]],
        'resolutions': arr_values[filter_dict["#resolutions"]["index"]],
        'params': arr_values[filter_dict["#Params"]["index"]],
        'fixed_params': arr_values[filter_dict["#Fixed Params"]["index"]],
        'molec_eq': arr_values[filter_dict["#Molec_EQ"]["index"]],
        'priors_complete': arr_values[filter_dict["#PriorsComplete"]["index"]]
    }

    return extracted_values


class FrameDisplay(MyPanel):
    """
    Frame Display Panel Class
    
    A specialized panel for displaying frame configuration details and analysis
    parameters. Inherits from MyPanel and provides functionality to show
    detailed information about frame analysis results.
    
    Attributes:
        global_exc: Flag to control execution state
        parent: Parent widget reference
        path_folder_targets: Path to the targets folder
        button_display_configuration: Button widget for displaying configuration
    """

    def __init__(self, parent, row, column, color, frame_input, **kwargs):
        """
        Initialize the FrameDisplay panel.
        
        Args:
            parent: Parent widget
            row: Row position in the grid
            column: Column position in the grid
            color: Background color for the panel
            frame_input: Frame input object containing path information
            **kwargs: Additional keyword arguments passed to parent class
        """
        # Initialize execution flag to prevent premature execution
        self.global_exc = 0
        
        # Store parent reference for accessing other components
        self.parent = parent
        
        # Extract target folder path from frame input
        self.path_folder_targets = frame_input.frame_path.path_folder_targets.get_text()
        
        # Initialize the parent MyPanel class
        super().__init__(parent, color, row, column, **kwargs)
        
        # Create the display configuration button
        self.button_display_configuration = MyButton(
            self, 0, 1, "DISPLAY INITIAL CONFIGURATION", "#74ff69",
            command=self.display_conf, color_panel=color
        )
        
        # Enable execution after initialization is complete
        self.global_exc = 1

    def display_conf(self):
        """
        Display the configuration details in a popup figure.
        
        This method retrieves configuration data from the filter table,
        reads additional information from CSV files, and displays all
        the details in a formatted message window.
        """
        # Only execute if initialization is complete
        if self.global_exc == 1:
            # Get target selection from dropdown
            target = self.parent.frame_filter.dropdown_target.get_value()
            
            # Get array values from the filter table
            arr_values = self.parent.frame_table.table.get_arr_values()
            
            # Construct path to results folder
            results_path = str(Path(
                self.path_folder_targets, 
                target, 
                ConstantVariables.RESULTS_FOLDER,
                arr_values[ConstantVariables.DICT_FILTER_TABLE["ID"]["index"]]
            ))
            
            # Read general information from CSV file
            df_general_info = read_csv(str(Path(results_path, "df_general_info.csv")))
            
            # Extract all filter values using helper method
            values = _extract_filter_values(arr_values)
            
            # Format parameter strings with proper spacing and line breaks
            values['params'], values['fixed_params'] = _format_parameter_strings(
                values['params'], values['fixed_params']
            )
            
            # Get model reprocessing value from CSV
            model_rep = get_csv_value(df_general_info, "model_reprocessing")
            
            # Build the complete configuration message
            message = _build_configuration_message(values, model_rep)
            
            # Display the configuration in a popup figure
            MyFigure("Detail components", message=message)
