"""
Panel for managing and displaying parameter settings in the GUI.

This module provides a panel interface for configuring various parameters used in the application,
including temperature profiles, chemistry settings, and instrument configurations.
"""

import copy
from pathlib import Path
from typing import Tuple, Any, Optional
import numpy as np

from GUIBRUSHR.GUI.WIDGET.MyDropDown import MyDropdown
from GUIBRUSHR.GUI.WIDGET.MyEntry import MyEntry
from GUIBRUSHR.GUI.WIDGET.MyTextField import MyTextField
from GUIBRUSHR.GUI.WIDGET.MyButton import MyButton
from GUIBRUSHR.GUI.WIDGET.MyLabel import MyLabel
from GUIBRUSHR.GUI.LAYOUT.MyPanel import MyPanel
from GUIBRUSHR.GUI.LAYOUT.MyTabPanel import MyTabPanel
from GUIBRUSHR.GUI.Input_Output_Panels.Input_Panels.TabPanels.Frame_Parameters.Class_Parameter_Panel import ParametersGUI
from GUIBRUSHR.General_Constants.FunctionsAndConstants.Constant_Variables import ConstantVariables
from GUIBRUSHR.General_Constants.Classes.HelpButton import HelpButton
from GUIBRUSHR.General_Constants.FunctionsAndConstants.general_functions import get_line_lists, get_condensed_line_list
from GUIBRUSHR.GUI.DataInterface.DataInterface import (
    get_target_info,
    get_target_list,
    get_target_instruments,
    get_target_nights
)
from GUIBRUSHR.GUI.DataInterface.DBSQLite3 import DBSQLite3

# Constants
NO = 0
YES = 1
NORMAL = "normal"
NONE_999 = -999


def _create_tab_help_button(panel_idx: int, parent_panel: Any, has_vmr_button=False, has_hce_button=False,
                            has_molecule_button=False, has_condensed_button=False, has_hydrogen_button=False) -> HelpButton:
    """
    Create tab-specific help button with parameter descriptions.

    Args:
        panel_idx: Index of the panel (0-7)
        parent_panel: Parent panel widget
        has_vmr_button: Whether this panel has VMR button
        has_hce_button: Whether this panel has Hybrid Chemical Equilibrium button
        has_molecule_button: Whether this panel has ADD MOLECULE button
        has_condensed_button: Whether this panel has ADD CONDENSED MOLECULE button
        has_hydrogen_button: Whether this panel has UPDATE H-, H, e- button

    Returns:
        HelpButton instance
    """
    # Tab descriptions
    tab_descriptions = [
        "Planet + Data: Parameters related to planetary properties, orbital characteristics, data scaling, and instrumental offsets.",
        "Clouds/Haze: Parameters controlling cloud deck properties, haze opacity, and aerosol scattering in the atmosphere.",
        "Temperatures: Temperature-pressure profile parameters for parameterizations (isothermal, Madhu, Guillot).",
        "Temperatures2: Additional temperature profile parameters for parameterizations (personalized profiles, nodal points).",
        "VMR: Volume Mixing Ratio profile parameters for species with altitude-dependent abundances (Gaussian peaks).",
        "Equilibrium: Chemical equilibrium parameters including metallicity, C/O ratio, and elemental abundances.",
        "Molecules: Molecular species and their volume mixing ratios. Includes major atmospheric constituents and trace species.",
        "Condensed elements: Condensed species (cloud particles) parameters including particle properties and sedimentation efficiency."
    ]

    # Collect parameters for this panel
    help_text = {"Tab Description": tab_descriptions[panel_idx]}

    for param_name, param_data in ConstantVariables.PARAMS_DICT.items():
        if param_data["panel"] == panel_idx:
            # Get description from params dict, with fallback
            description = param_data.get("description", f"Parameter {param_name} (description pending)")
            label = param_data.get("label", param_name)

            # Format the help entry
            help_text[f"{param_name} ({label})"] = description

    # Add button-specific help if applicable
    if has_vmr_button:
        help_text["UPDATE VMR PARAMETERS button"] = "Automatically populate VMR peak, pressure, and width parameters for all molecules with present=1 and VMR=0. Creates altitude-dependent Gaussian abundance profiles."

    if has_hce_button:
        help_text["ADD ELEMENT TO HYBRID CHEMICAL EQUILIBRIUM button"] = "Adds the selected element for hybrid chemical equilibrium modeling."

    if has_hydrogen_button:
        help_text["UPDATE H-, H, e- button"] = "Updates the abundances of H- (hydrogen minus), H (atomic hydrogen), and e- (free electrons) based on the H2 and He abundances. Calculates derived abundances for consistency in hot atmosphere models."

    if has_molecule_button:
        help_text["ADD MOLECULE TO RETRIEVAL button"] = "Adds the selected molecule with its isotope, sub-isotope, and abundance to the atmospheric composition. Allows manual specification of molecular abundances."

    if has_condensed_button:
        help_text["ADD CONDENSED MOLECULE TO RETRIEVAL button"] = "Adds cloud/aerosol species (e.g., Al2O3, MgSiO3, Fe) to the model. Controls cloud particle composition and properties."

    return HelpButton(
        parent_panel, 0, 14,
        f"Tab Parameters Help",
        help_text,
        columnspan=2
    )


class PanelParameters(MyPanel):
    """
    Panel for managing parameter settings in the GUI.

    This class provides a comprehensive interface for configuring various parameters
    used in the application, including temperature profiles, chemistry settings,
    and instrument configurations.

    Attributes:
        parent: Parent widget
        path_default: Default path for file operations
        path_folder_targets: Path where the folder of targets is found
        target_information: Information about the current target
        list_hr_instrument: List of high-resolution instruments
        list_lr_instrument: List of low-resolution instruments
        global_exc: Global execution flag
        param_names_list: List of parameter names
        multi_params_list: List of multiple parameters
        list_panel: List of parameter panels
        list_params_widget: List of parameter widgets
        list_param_multiple_values: List of multiple parameter values
    """

    def __init__(self, parent: Any, row: int, column: int, color: str, path_default: str, **kwargs) -> None:
        """
        Initialize the parameters panel.

        Args:
            parent: Parent widget
            row: Row position in parent's grid
            column: Column position in parent's grid
            color: Background color
            path_default: Default path for file operations
            **kwargs: Additional keyword arguments
        """
        self.target_information = None
        self.list_hr_instrument = None
        self.list_lr_instrument = None
        self.parent = parent
        self.path_default = path_default
        # Path where the folder of targets is found
        self.path_folder_targets = parent.frame_input.frame_path.path_folder_targets.get_text()
        # Hereditary
        super().__init__(parent, color, row, column, **kwargs)
        #
        self.global_exc = 0
        # DB connection
        self._initialize_target_info()
        # Add panels
        self._create_tab_panel()
        self._create_parameters_tabs(color)
        #
        self.global_exc = 1

    def _create_parameters_tabs(self, color):
        no = 0
        yes = 1
        normal = "normal"
        none_999 = -999
        color_params = ConstantVariables.COLOR_SUB_NOTEBOOK_2
        # Panel colors
        labels_params = [
            "Name", "Pres", "Value", "Scale", "Range Min", "Range Max", "In bestpars",
            "Mass", "Sigma Prior", "Constant VMR", "Type Params", "Rayleigh"
        ]
        columnspan = [
            3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        ]
        sum_index = [
            0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        ]
        #
        self.param_names_list = ConstantVariables.params_list
        self.multi_params_list = ConstantVariables.LIST_MULTIPLE_PARAM
        self.list_panel = []

        # Create global help button for table columns
        self._create_global_help_button()

        # Track which panels have special buttons for help text
        NUM_PARAMETER_PANELS = 8  # Number of parameter tabs
        panel_has_vmr_button = [False] * NUM_PARAMETER_PANELS
        panel_has_hce_button = [False] * NUM_PARAMETER_PANELS
        panel_has_molecule_button = [False] * NUM_PARAMETER_PANELS
        panel_has_condensed_button = [False] * NUM_PARAMETER_PANELS
        panel_has_hydrogen_button = [False] * NUM_PARAMETER_PANELS

        for panel_idx, panel in enumerate(self.tab_manager.tab_list):
            self.list_panel.append(MyPanel(panel, color_params, 0, 0))

            for index, elem in enumerate(labels_params):
                _ = MyLabel(
                    self.list_panel[-1], 0, index + sum_index[index], label_text=elem,
                    columnspan=columnspan[index], color=color_params
                )
        # Create list of all params
        self.list_params_widget = []
        self.list_param_multiple_values = []
        row = 1
        #
        last_panel = -1
        for param_name in ConstantVariables.PARAMS_DICT.keys():
            temp_param = ConstantVariables.PARAMS_DICT[param_name]
            name = temp_param["name"]
            multi = int(temp_param["multi"])
            present = int(temp_param["present"])
            molec = int(temp_param["molec"])
            #
            value = temp_param["value"]
            if value in ["target_kp", "h_ecc", "k_ecc", "radius", "temperature", "omega"]:
                if self.target_information.kp is None:
                    value = -99999
                else:
                    if value == "target_kp":
                        value = self.target_information.kp
                    elif value == "h_ecc":
                        if self.target_information.eccentricity is None or self.target_information.argument_of_periastron is None:
                            value = np.sqrt(self.target_information.eccentricity) * np.sin(
                                self.target_information.argument_of_periastron)
                        else:
                            value = 0
                    elif value == "k_ecc":
                        if self.target_information.eccentricity is None or self.target_information.argument_of_periastron is None:
                            value = np.sqrt(self.target_information.eccentricity) * np.cos(
                                self.target_information.argument_of_periastron)
                        else:
                            value = 0
                    elif value == "radius":
                        value = self.target_information.radius
                    elif value == "temperature":
                        value = self.target_information.equilibrium_temperature
                    elif value == "omega":
                        value = np.log10(2 * np.pi / self.target_information.period)
            elif value == "nothing":
                value = ""
            else:
                value = float(value)
            #
            scale = temp_param["scale"]
            range_min = temp_param["range_min"]
            if range_min == "radius":
                range_min = value - 0.1 * value
            range_max = temp_param["range_max"]
            if range_max == "radius":
                range_max = value + 0.1 * value
            rayleigh = int(temp_param["rayleigh"])
            bestpars = int(temp_param["bestpars"])
            mass = float(temp_param["mass"])
            prior = temp_param["prior"]
            if prior == "nothing":
                prior = ""
            constant_vmr = temp_param["constant_vmr"]
            index_panel = temp_param["panel"]
            chemical_formula = temp_param["chemical_formula"]
            if chemical_formula == "None":
                chemical_formula = None
            if index_panel != last_panel:
                row = 1
                last_panel = index_panel
            else:
                row += 1
            state = temp_param["state"]
            type_params = temp_param["type"]
            param_gui = ParametersGUI(
                self.list_panel[index_panel], row, color_params,
                [name, present, molec, value, scale, range_min, range_max, rayleigh, bestpars, mass, prior,
                 constant_vmr, type_params],
                state, chemical_formula=chemical_formula
            )
            self.list_params_widget.append(copy.copy(param_gui))
            if multi > 0:
                self.list_param_multiple_values.append(copy.copy(param_gui))
            #
            if name == "omega":
                self.entry_rv_sampling = MyEntry(
                    self.list_panel[0], row, 15, "0.1", "Kernel sampling (km/s):", color=color, columnspan=2
                )
            elif name == "width_peak":
                row += 1
                panel_has_vmr_button[4] = True
                self.panel_vmr = MyPanel(self.list_panel[4], color_params, row, 0, columnspan=20)
                self.list_molec_selected = MyTextField(self.panel_vmr, 0, 1, "", label_text="Current molecules:",
                                                       columnspan=4, color=color_params, width=110, height=10)
                self.update_params_vmr = MyButton(self.panel_vmr, 0, 4, 'UPDATE VMR PARAMETERS', "#00AA00",
                                                  command=self.update_params_vmr_func)
            elif name == "sio_ratio_linear":
                #
                row += 1
                panel_has_hce_button[5] = True
                elems = ConstantVariables.LIST_ELEMENT_FOR_HYBRID
                self.elems = ParametersGUI(
                    self.list_panel[5],
                    row, color_params,
                    ["", yes, yes, -5, 0.1, -10, -1, no, yes, none_999, none_999, no, "Log10"],
                    normal, elems=elems,
                )
                #
                row += 1
                self.button_hce = MyButton(
                    self.list_panel[5], row, 0, 'ADD ELEMENT TO HYBRID CHEMICAL EQUILIBRIUM', "#00AA00",
                    columnspan=20, command=self.update_elem_textfield
                )
                #
                row += 1
                self.textfield_hce = MyTextField(
                    self.list_panel[5], row, 0, "", label_text="Current elements:",
                    columnspan=20, color=color_params, height=10, width=110
                )
            elif name == "e-":
                #
                row += 1
                panel_has_hydrogen_button[6] = True
                panel_has_molecule_button[6] = True
                self.hydrogen_minus = MyPanel(self.list_panel[6], color_params, row, 0, columnspan=20)
                self.update_params_vmr = MyButton(
                    self.hydrogen_minus, 0, 1, 'UPDATE H-, H, e-',
                    "#00AA00", command=self.update_hydrogen_menus_btn
                )
                #
                row += 1
                molecs, isotopes, opacity_line_lists_HR, opacity_line_lists_LR, isotope_masses = get_line_lists()
                self.molecs = ParametersGUI(
                    self.list_panel[6],
                    row, color_params,
                    ["", yes, yes, -5, 0.01, -10, -1, no, yes, 0, none_999, yes, "Log10"],
                    normal,
                    chemical_formula="",
                    molecs=molecs, isotopes=isotopes, opacity_line_lists_HR=opacity_line_lists_HR,
                    opacity_line_lists_LR=opacity_line_lists_LR, isotope_masses=isotope_masses,
                )
                self.panel_sampling = MyPanel(self.list_panel[6], color_params, row, 14, columnspan=1)
                self.entry_lbl_sampling_hr = MyEntry(
                    self.panel_sampling, 0, 1, "4", "LBL sampling HR:", color=color, columnspan=2
                )
                self.entry_lbl_sampling_lr = MyEntry(
                    self.panel_sampling, 1, 1, "4", "LBL sampling LR:", color=color, columnspan=2
                )
                self.entry_lbl_sampling_lr.set_status("disabled")
                #
                row += 1
                self.molec_panel = MyPanel(self.list_panel[6], color_params, row, 0, columnspan=20)
                self.button_molecs = MyButton(
                    self.molec_panel, 0, 1, 'ADD MOLECULE TO RETRIEVAL', "#00AA00", command=self.update_molec_textfield
                )
                #
                row += 1
                self.textfield_molecs = MyTextField(
                    self.list_panel[6], row, 0, "", label_text="Current molecules:",
                    columnspan=20, color=color_params, height=7, width=150
                )
            elif name == "eddy_diff_coeff":
                #
                row += 1
                panel_has_condensed_button[7] = True
                condensed_molecs_list, condensed_names_list, condensed_masses, condensed_visualization_name = get_condensed_line_list()
                self.condensed_molecs = ParametersGUI(
                    self.list_panel[7],
                    row, color_params,
                    ["", yes, no, -7, 0.01, -12, -4, no, yes, 0, none_999, yes, "Log10"],
                    normal,
                    chemical_formula="", condensed_molecs_names=condensed_names_list,
                    condensed_molecs_list=condensed_molecs_list, condensed_molecs_masses=condensed_masses,
                    condensed_visualization_name=condensed_visualization_name
                )
                #
                row += 1
                self.condensed_molec_panel = MyPanel(self.list_panel[7], color_params, row, 0, columnspan=20)
                self.button_condensed_molecs = MyButton(
                    self.condensed_molec_panel, 0, 1, 'ADD CONDENSED MOLECULE TO RETRIEVAL', "#00AA00",
                    command=self.update_condensed_molec_textfield
                )
                #
                row += 1
                self.textfield_condensed_molecs = MyTextField(self.list_panel[7], row, 0, "",
                                                              label_text="Current condensed \nmolecules:",
                                                              columnspan=20, color=color_params, height=10, width=110)
        #
        for panel in self.list_panel:
            panel.pack(padx=3, pady=3)

        # Create help buttons for each panel after all parameters are created
        self.tab_help_buttons = []
        for panel_idx in range(NUM_PARAMETER_PANELS):
            tab_help = _create_tab_help_button(
                panel_idx,
                self.list_panel[panel_idx],
                has_vmr_button=panel_has_vmr_button[panel_idx],
                has_hce_button=panel_has_hce_button[panel_idx],
                has_molecule_button=panel_has_molecule_button[panel_idx],
                has_condensed_button=panel_has_condensed_button[panel_idx],
                has_hydrogen_button=panel_has_hydrogen_button[panel_idx]
            )
            self.tab_help_buttons.append(tab_help)

    def _create_global_help_button(self) -> None:
        """Create global help button explaining table column headers."""
        help_text = {
            "Name": "Parameter name. This identifier is used throughout the retrieval to reference this specific parameter.",

            "Pres": "Presence flag. Determines if this parameter is included in the current retrieval configuration. Checkbox indicates active status.",

            "Value": "Initial or fixed value for the parameter. For fitted parameters, this serves as the starting point for MCMC sampling. Can be numeric or reference target properties.",

            "Scale": "Step size for MCMC proposals. Controls how much the parameter value can change between MCMC iterations. Smaller values lead to finer sampling but slower convergence.",

            "Range Min": "Minimum allowed value for the parameter during MCMC sampling. Acts as a hard boundary - proposed values below this are automatically rejected.",

            "Range Max": "Maximum allowed value for the parameter during MCMC sampling. Acts as a hard boundary - proposed values above this are automatically rejected.",

            "In bestpars": "Include in fitted parameters. When enabled, this parameter will be fitted during the retrieval. When disabled, the parameter is held fixed at its Value.",

            "Mass": "Molecular mass in atomic mass units (amu). Used for calculating mean molecular weight and atmospheric scale height. Only relevant for molecular species parameters.",

            "Sigma Prior": "Standard deviation for Gaussian prior. When specified, applies a Gaussian constraint centered on Value with this width. Use -999 for uniform priors (no constraint).",

            "Constant VMR": "Volume Mixing Ratio constraint. Controls whether the molecular abundance is constant with altitude or allowed to vary with pressure.",

            "Type Params": "Parameter type for internal calculations. 'Linear' for parameters sampled in linear space. 'Log10' for parameters sampled in log10 space (e.g., pressures, abundances)."
        }

        self.global_help_button = HelpButton(
            self, 0, 0,
            "Parameter Table Columns Help",
            help_text,
            columnspan=1
        )

    def adjust_LR_list(self, inner_call_for_lr_molecules_param, use_hr_linelist_for_lr):
        self.molecs.select_LR_list(inner_call_for_lr_molecules_param, use_hr_linelist_for_lr)
        status = "normal" if use_hr_linelist_for_lr else "disabled"
        self.entry_lbl_sampling_lr.set_status(status)

    def _initialize_target_info(self) -> None:
        """
        Initialize target information from database.
        
        This method loads target information, including high and low resolution
        instrument lists, from the database.
        """
        target_list = get_target_list(self.path_folder_targets)
        self.target_information = get_target_info(self.path_folder_targets, target_list[0])
        self.list_hr_instrument = get_target_instruments(
            self.path_folder_targets, target_list[0], "HR", "Transmission", Path(__file__).name
        )
        self.list_lr_instrument = get_target_instruments(
            self.path_folder_targets, target_list[0], "LR", "Transmission", Path(__file__).name
        )

    def _create_tab_panel(self) -> None:
        """
        Create the main tab panel with parameter sections.
        
        This method creates a tab panel with sections for different parameter types
        as defined in ConstantVariables.list_tab_frame_parameter.
        """
        self.tab_manager = MyTabPanel(
            parent=self,
            tab_list=ConstantVariables.list_tab_frame_parameter,
            row=0,
            column=1
        )

    def get_index_arrays(self, param_name: str) -> Tuple[int, Optional[int]]:
        """
        Get indices for parameter arrays.

        Args:
            param_name: Name of the parameter

        Returns:
            Tuple containing:
                - Index in param_names_list
                - Index in multi_params_list (None if not found)
        """
        index_list_param = self.param_names_list.index(param_name)
        index_list_multi_param = (
            self.multi_params_list.index(param_name)
            if param_name in self.multi_params_list
            else None
        )
        return index_list_param, index_list_multi_param

    def update_molec_textfield(self) -> None:
        """
        Update the molecule text field with current molecule information.

        This method is called when a new molecule is added to the retrieval list.
        It formats and adds the molecule's information to the text field.
        """
        if self.molecs.checkbox_presence.get_value():
            last_text = self.textfield_molecs.get_text()
            prefix = "" if last_text == "" else "\n"
            new_line = (
                f"{prefix}{self.molecs.dropdown_molec.get_value()},"
                f"{self.molecs.dropdown_isotope.get_value()},"
                f"{self.molecs.dropdown_opacity_line_list_HR.get_value()},"
                f"{self.molecs.dropdown_opacity_line_list_LR.get_value()},"
                f"{self.molecs.checkbox_presence.get_value()},"
                f"{self.molecs.is_molec},"
                f"{self.molecs.input_value.get_value()},"
                f"{self.molecs.input_scale.get_value()},"
                f"{self.molecs.input_range_min.get_value()},"
                f"{self.molecs.input_range_max.get_value()},"
                f"{self.molecs.get_rayleigh_value()},"
                f"{self.molecs.checkbox_bestpars.get_value()},"
                f"{self.molecs.get_mass_value()},"
                f"{self.molecs.input_sigma_prior.get_value()},"
                f"{self.molecs.get_constant_vmr_value()},"
                f"{self.molecs.chemical_formula}\n"
            )
            self.textfield_molecs.insert_text(last_text + new_line)

    def update_condensed_molec_textfield(self) -> None:
        """
        Update the condensed molecule text field with current information.

        This method is called when a new condensed molecule is added to the retrieval list.
        It formats and adds the molecule's information to the text field.
        """
        if self.condensed_molecs.checkbox_presence.get_value():
            last_text = self.textfield_condensed_molecs.get_text()
            if last_text == "":
                prefix = ""
            else:
                prefix = "\n"
            namem, _ = self.condensed_molecs.get_name()
            new_line = (
                    prefix +
                    namem + "," +
                    str(self.condensed_molecs.checkbox_presence.get_value()) + "," +
                    str(self.condensed_molecs.is_molec) + "," +
                    str(self.condensed_molecs.input_value.get_value()) + "," +
                    str(self.condensed_molecs.input_scale.get_value()) + "," +
                    str(self.condensed_molecs.input_range_min.get_value()) + "," +
                    str(self.condensed_molecs.input_range_max.get_value()) + "," +
                    str(self.condensed_molecs.get_rayleigh_value()) + "," +
                    str(self.condensed_molecs.checkbox_bestpars.get_value()) + "," +
                    str(self.condensed_molecs.get_mass_value()) + "," +
                    str(self.condensed_molecs.input_sigma_prior.get_value()) + "," +
                    str(self.condensed_molecs.get_constant_vmr_value()) + "," +
                    self.condensed_molecs.chemical_formula + "\n"
            )
            self.textfield_condensed_molecs.insert_text(last_text + new_line)

    def update_elem_textfield(self) -> None:
        """
        Update the element text field with current element information.

        This method is called when a new element is added to the hybrid chemical equilibrium.
        It formats and adds the element's information to the text field.
        """
        if self.elems.checkbox_presence.get_value():
            last_text = self.textfield_hce.get_text()
            prefix = "" if last_text == "" else "\n"
            new_line = (
                f"{prefix}{self.elems.dropdown_elems.get_value()},"
                f"{self.elems.checkbox_presence.get_value()},"
                f"{self.elems.is_molec},"
                f"{self.elems.input_value.get_value()},"
                f"{self.elems.input_scale.get_value()},"
                f"{self.elems.input_range_min.get_value()},"
                f"{self.elems.input_range_max.get_value()},"
                f"{self.elems.get_rayleigh_value()},"
                f"{self.elems.checkbox_bestpars.get_value()},"
                f"{self.elems.get_mass_value()},"
                f"{self.elems.input_sigma_prior.get_value()},"
                f"{self.elems.get_constant_vmr_value()},"
                f"{self.elems.dropdown_elems.get_value().replace('_hybrid', '')}\n"
            )
            self.textfield_hce.insert_text(last_text + new_line)

    def update_params_vmr_func(self) -> None:
        """
        Update VMR (Volume Mixing Ratio) parameters.

        This method updates the VMR parameters based on the current molecule list.
        It calculates and sets values for vmr_peak, pressure_peak, and width_peak parameters.
        """
        counter_0 = ""
        counter_1 = ""
        counter_2 = ""
        str_molec = ""
        sigmas = ""
        molec_list = self.textfield_molecs.get_text()
        if molec_list == "":
            return
        molec_list = molec_list.split("\n")
        for elem in molec_list:
            string_comp = elem.split(",")
            if int(string_comp[3]) and not int(string_comp[13]):
                counter_0 += "-3,"
                counter_1 += "-5,"
                counter_2 += "2,"
                str_molec += string_comp[2] + ","
                sigmas += "-999,"
        if len(counter_0) > 0:
            counter_0 = counter_0[:-1]
            counter_1 = counter_1[:-1]
            counter_2 = counter_2[:-1]
            str_molec = str_molec[:-1]
            sigmas = sigmas[:-1]
        #
        index_single, index_multi = self.get_index_arrays("vmr_peak")
        self.list_params_widget[index_single].input_value.set_value(counter_0)
        self.list_param_multiple_values[index_multi].input_value.set_value(counter_0)
        self.list_params_widget[index_single].input_sigma_prior.set_value(sigmas)
        self.list_param_multiple_values[index_multi].input_sigma_prior.set_value(sigmas)
        #
        index_single, index_multi = self.get_index_arrays("pressure_peak")
        self.list_params_widget[index_single].input_value.set_value(counter_1)
        self.list_param_multiple_values[index_multi].input_value.set_value(counter_1)
        self.list_params_widget[index_single].input_sigma_prior.set_value(sigmas)
        self.list_param_multiple_values[index_multi].input_sigma_prior.set_value(sigmas)
        #
        index_single, index_multi = self.get_index_arrays("width_peak")
        self.list_params_widget[index_single].input_value.set_value(counter_2)
        self.list_param_multiple_values[index_multi].input_value.set_value(counter_2)
        self.list_params_widget[index_single].input_sigma_prior.set_value(sigmas)
        self.list_param_multiple_values[index_multi].input_sigma_prior.set_value(sigmas)
        #
        self.list_molec_selected.insert_text(str_molec)

    def update_LR(self) -> None:
        """
        Update low-resolution offset parameter based on resolution mode.

        This method enables/disables the low-resolution offset parameter based on
        whether high+low resolution mode is selected.
        """
        if self.global_exc == 0:
            return

        index_single, _ = self.get_index_arrays("offsetLR")
        status = "normal" if (
            self.parent.panel_info.dropdown_resolution.get_value() !=
            ConstantVariables.LIST_RESOLUTION_TABLE[0]  # When Low
        ) else "disabled"
        self.list_params_widget[index_single].disable_param_status(status)

    def update_chemistry(self) -> None:
        """
        Update chemistry parameters based on chemistry mode.

        This method enables/disables chemistry-related parameters (met and co_ratio)
        based on the selected chemistry mode in the interface.
        """
        if self.global_exc == 0:
            return

        index_met, _ = self.get_index_arrays("met")
        index_co_ratio, _ = self.get_index_arrays("co_ratio")
        index_co_ratio_linear, _ = self.get_index_arrays("co_ratio_linear")
        index_sio_ratio_linear, _ = self.get_index_arrays("sio_ratio_linear")

        # Disable both parameters initially
        self.list_params_widget[index_met].disable_param_status("disabled")
        self.list_params_widget[index_co_ratio].disable_param_status("disabled")
        self.list_params_widget[index_co_ratio_linear].disable_param_status("disabled")
        self.list_params_widget[index_sio_ratio_linear].disable_param_status("disabled")

        # Enable parameters based on chemistry mode
        chemistry_mode = self.parent.panel_info.dropdown_chemistry.get_value()
        if chemistry_mode in [
            ConstantVariables.LIST_CHEMISTRY_TABLE[0],
            ConstantVariables.LIST_CHEMISTRY_TABLE[2]
        ]:
            self.list_params_widget[index_met].disable_param_status("normal")
            self.list_params_widget[index_co_ratio].disable_param_status("normal")
            self.list_params_widget[index_co_ratio_linear].disable_param_status("normal")
            self.list_params_widget[index_sio_ratio_linear].disable_param_status("normal")

    def update_target(self) -> None:
        """
        Update target information and related parameters.

        This method updates the target information and all related parameters
        when a new target is selected. It also triggers an update of the
        radiation mode settings.
        """
        if self.global_exc == 0:
            return
        target_id = self.parent.panel_info.dropdown_target.get_value()
        self.target_information = get_target_info(self.path_folder_targets, target_id, self.parent.panel_info.dropdown_rad_mode.get_value())
        self.parent.panel_info.target_information = self.target_information
        index_kp, _ = self.get_index_arrays("kp")
        index_T0, _ = self.get_index_arrays("T0")
        index_T_high, _ = self.get_index_arrays("T_high")
        index_T_low, _ = self.get_index_arrays("T_low")
        index_rp, _ = self.get_index_arrays("rp")
        index_h_ecc, _ = self.get_index_arrays("h_ecc")
        index_k_ecc, _ = self.get_index_arrays("k_ecc")
        index_T0_node, _ = self.get_index_arrays("T0_node")
        index_T1_node, _ = self.get_index_arrays("T1_node")
        index_T2_node, _ = self.get_index_arrays("T2_node")
        index_T3_node, _ = self.get_index_arrays("T3_node")
        index_omega, _ = self.get_index_arrays("omega")
        #
        self.list_params_widget[index_kp].input_value.set_value(self.parent.panel_info.target_information.kp)
        self.list_params_widget[index_T0].input_value.set_value(self.parent.panel_info.target_information.equilibrium_temperature)
        self.list_params_widget[index_T_high].input_value.set_value(self.parent.panel_info.target_information.equilibrium_temperature)
        self.list_params_widget[index_T_low].input_value.set_value(self.parent.panel_info.target_information.equilibrium_temperature)
        self.list_params_widget[index_T0_node].input_value.set_value(self.parent.panel_info.target_information.equilibrium_temperature)
        self.list_params_widget[index_T1_node].input_value.set_value(self.parent.panel_info.target_information.equilibrium_temperature)
        self.list_params_widget[index_T2_node].input_value.set_value(self.parent.panel_info.target_information.equilibrium_temperature)
        self.list_params_widget[index_T3_node].input_value.set_value(self.parent.panel_info.target_information.equilibrium_temperature)
        self.list_params_widget[index_omega].input_value.set_value(np.log10(2 * np.pi / self.parent.panel_info.target_information.period))
        self.list_params_widget[index_rp].input_range_min.set_value(
            self.parent.panel_info.target_information.radius - 0.1 * self.parent.panel_info.target_information.radius
        )
        self.list_params_widget[index_rp].input_range_max.set_value(
            self.parent.panel_info.target_information.radius + 0.1 * self.parent.panel_info.target_information.radius
        )
        self.list_params_widget[index_rp].input_value.set_value(self.parent.panel_info.target_information.radius)
        self.list_params_widget[index_h_ecc].input_value.set_value(np.sqrt(self.parent.panel_info.target_information.eccentricity) * np.sin(self.parent.panel_info.target_information.argument_of_periastron))
        self.list_params_widget[index_k_ecc].input_value.set_value(np.sqrt(self.parent.panel_info.target_information.eccentricity) * np.cos(self.parent.panel_info.target_information.argument_of_periastron))
        self.update_from_rad_mode()

    def update_hr_pixeldv(self) -> None:
        """
        Update high-resolution instrument pixel information.

        This method retrieves and updates the high-resolution instrument settings
        from the database when the instrument selection changes.
        """
        instrumenti = self.parent.panel_info.dropdown_hr_instrument.get_value()
        DB = DBSQLite3(self.path_default)
        self.parent.panel_info.instrument_hr_obj = DB.get_instrument_by_key(instrumenti)
        DB.close_DB()
        self.update_night()

    def update_lr_pixeldv(self) -> None:
        """
        Update low-resolution instrument pixel information.

        This method retrieves and updates the low-resolution instrument settings
        from the database when the instrument selection changes.
        """
        instrumenti = self.parent.panel_info.dropdown_lr_instrument.get_value()
        DB = DBSQLite3(self.path_default)
        self.parent.panel_info.instrument_lr_obj = DB.get_instrument_by_key(instrumenti)
        DB.close_DB()

    def update_night(self) -> None:
        """
        Update night information for the current target.

        This method retrieves and updates the available nights for the current
        target and instrument configuration.
        """
        target_id = self.parent.panel_info.dropdown_target.get_value()
        if self.parent.panel_info.instrument_hr_obj is not None:
            nights = get_target_nights(
                self.path_folder_targets,
                target_id,
                self.parent.panel_info.dropdown_rad_mode.get_value(),
                self.parent.panel_info.instrument_hr_obj.name,
                self.parent.panel_info.check_nights_sim.get_value()
            )
        else:
            nights = "None"
        self.parent.panel_info.textfield_nights.insert_text(nights)
        # self.update_f_rot(nights)

    def update_tp_params(self) -> None:
        """
        Update temperature profile parameters based on selected profile type.

        This method enables/disables temperature profile parameters based on the
        selected profile type (isothermal, Madhu, Guillot, etc.).
        """
        if self.global_exc == 0:
            return

        # Get indices for all temperature profile parameters
        indices = {
            'T0': self.get_index_arrays("T0"),
            'p1': self.get_index_arrays("p1"),
            'p2': self.get_index_arrays("p2"),
            'p3': self.get_index_arrays("p3"),
            'alpha1': self.get_index_arrays("alpha1"),
            'alpha2': self.get_index_arrays("alpha2"),
            'kappa_IR': self.get_index_arrays("kappa_IR"),
            'gamma_g': self.get_index_arrays("gamma_g"),
            'T_int': self.get_index_arrays("T_int"),
            'T_low': self.get_index_arrays("T_low"),
            'T_high': self.get_index_arrays("T_high"),
            'P_low': self.get_index_arrays("P_low"),
            'P_high': self.get_index_arrays("P_high"),
            'T0_node': self.get_index_arrays("T0_node"),
            'T1_node': self.get_index_arrays("T1_node"),
            'T2_node': self.get_index_arrays("T2_node"),
            'T3_node': self.get_index_arrays("T3_node"),
            'P1_node': self.get_index_arrays("P1_node"),
            'P2_node': self.get_index_arrays("P2_node")
        }

        # Disable all parameters initially
        for index, _ in indices.values():
            self.list_params_widget[index].disable_param_status("disabled")

        # Enable parameters based on profile type
        profile_type = self.parent.panel_info.dropdown_t_p_profile.get_value()
        if profile_type == ConstantVariables.LIST_PT_PROFILE_TABLE[0]:  # isothermal
            self.list_params_widget[indices['T0'][0]].disable_param_status("normal")
        elif profile_type == ConstantVariables.LIST_PT_PROFILE_TABLE[1]:  # Madhu
            for param in ['T0', 'p1', 'p2', 'p3', 'alpha1', 'alpha2']:
                self.list_params_widget[indices[param][0]].disable_param_status("normal")
        elif profile_type == ConstantVariables.LIST_PT_PROFILE_TABLE[2]:  # Guillot
            for param in ['T0', 'kappa_IR', 'gamma_g', 'T_int']:
                self.list_params_widget[indices[param][0]].disable_param_status("normal")
        elif profile_type == ConstantVariables.LIST_PT_PROFILE_TABLE[3]:  # personalized
            for param in ['T_low', 'T_high', 'P_low', 'P_high']:
                self.list_params_widget[indices[param][0]].disable_param_status("normal")
        elif profile_type == ConstantVariables.LIST_PT_PROFILE_TABLE[4]:  # nodes
            for param in ['T0_node', 'T1_node', 'T2_node', 'T3_node', 'P1_node', 'P2_node']:
                self.list_params_widget[indices[param][0]].disable_param_status("normal")
        else:  # all parameters enabled
            for index, _ in indices.values():
                self.list_params_widget[index].disable_param_status("normal")

    def scattering_check(self) -> None:
        """
        Update scattering parameters based on scattering checkbox state.

        This method enables/disables scattering-related parameters (k0 and gamma)
        based on whether scattering is enabled in the interface.
        """
        index_k0, _ = self.get_index_arrays("k0")
        index_gamma, _ = self.get_index_arrays("gamma")
        status = "normal" if self.parent.panel_info.check_scattering.get_value() else "disabled"
        self.list_params_widget[index_k0].disable_param_status(status)
        self.list_params_widget[index_gamma].disable_param_status(status)

    def ecc_opi_check(self) -> None:
        """
        Update eccentricity parameters based on eccentricity checkbox state.

        This method enables/disables eccentricity-related parameters (h_ecc and k_ecc)
        based on whether eccentricity is enabled in the interface.
        """
        index_h_ecc, _ = self.get_index_arrays("h_ecc")
        index_k_ecc, _ = self.get_index_arrays("k_ecc")
        status = "normal" if self.parent.panel_info.check_ecc_opi.get_value() else "disabled"
        self.list_params_widget[index_h_ecc].disable_param_status(status)
        self.list_params_widget[index_k_ecc].disable_param_status(status)

    def update_from_rad_mode(self) -> None:
        """
        Update instrument lists and dropdowns based on radiation mode.

        This method updates the high and low resolution instrument lists and
        recreates their dropdown menus when the radiation mode changes.
        """
        target_id = self.parent.panel_info.dropdown_target.get_value()
        rad_mode = self.parent.panel_info.dropdown_rad_mode.get_value()

        # Update instrument lists
        self.list_hr_instrument = get_target_instruments(
            self.path_folder_targets, target_id, "HR", rad_mode, Path(__file__).name
        )
        self.list_lr_instrument = get_target_instruments(
            self.path_folder_targets, target_id, "LR", rad_mode, Path(__file__).name
        )

        # Update parent panel info
        self.parent.panel_info.list_hr_instrument = self.list_hr_instrument
        self.parent.panel_info.list_lr_instrument = self.list_lr_instrument

        # Recreate dropdown menus
        self.parent.panel_info.dropdown_hr_instrument.clean_widget()
        self.parent.panel_info.dropdown_lr_instrument.clean_widget()

        # Create new dropdowns
        self.parent.panel_info.dropdown_hr_instrument = MyDropdown(
            self.parent.panel_info.row_instruments,
            0, 1,
            self.list_hr_instrument,
            "HR Instrument:",
            color=self.parent.panel_info.color,
            columnspan=2
        )

        self.parent.panel_info.dropdown_lr_instrument = MyDropdown(
            self.parent.panel_info.row_instruments,
            1, 1,
            self.list_lr_instrument,
            "LR instrument:",
            color=self.parent.panel_info.color,
            columnspan=2
        )

        # Set up callbacks
        self.parent.panel_info.dropdown_hr_instrument.chosen_var.trace(
            "w", lambda *args: self.update_hr_pixeldv()
        )
        self.parent.panel_info.dropdown_lr_instrument.chosen_var.trace(
            "w", lambda *args: self.update_lr_pixeldv()
        )

        # Update initial values
        self.update_hr_pixeldv()
        self.update_lr_pixeldv()

    def include_h_m(self) -> None:
        """
        Update hydrogen-related parameters and continuum opacity.

        This method updates the continuum opacity text field and enables/disables
        hydrogen-related parameters (H, H-, e-) based on the include_h_m checkbox state.
        """
        index_H, _ = self.get_index_arrays("H")
        index_H_m, _ = self.get_index_arrays("H-")
        index_e_m, _ = self.get_index_arrays("e-")

        if self.parent.panel_info.checkbox_include_h_m.get_value():
            self.parent.panel_info.textfield_continuum_opacity.insert_text("H2-H2,H2-He,H-")
            status = "normal"
        else:
            self.parent.panel_info.textfield_continuum_opacity.insert_text("H2-H2,H2-He")
            status = "disabled"

        # Update parameter states
        for index in [index_H, index_H_m, index_e_m]:
            self.list_params_widget[index].disable_param_status(status)
            self.list_params_widget[index].checkbox_presence.set_value(1)

    def update_hydrogen_menus_btn(self) -> None:
        """
        Update hydrogen-related parameter values.

        This method calculates and updates the values for H, H-, and e- parameters
        based on the current H2 and He values.
        """
        index_H2, _ = self.get_index_arrays("H2")
        index_He, _ = self.get_index_arrays("He")
        index_H, _ = self.get_index_arrays("H")
        index_H_m, _ = self.get_index_arrays("H-")
        index_e_m, _ = self.get_index_arrays("e-")

        if self.parent.panel_info.checkbox_include_h_m.get_value():
            He = float(self.list_params_widget[index_H2].input_value.get_value())
            H2 = float(self.list_params_widget[index_He].input_value.get_value())

            # Calculate derived values
            H_m = He + H2
            e_m = He - H2
            H = He * H2

            # Update parameter values
            self.list_params_widget[index_H].input_value.set_value(H)
            self.list_params_widget[index_H_m].input_value.set_value(H_m)
            self.list_params_widget[index_e_m].input_value.set_value(e_m)

    def update_night_sim(self) -> None:
        """
        Update nights information list.

        This method retrieves and updates the nights on the textfield.
        """
        if self.global_exc == 0:
            return
        target_id = self.parent.panel_info.dropdown_target.get_value()
        nights = get_target_nights(
            self.path_folder_targets, target_id, self.parent.panel_info.dropdown_rad_mode.get_value(),
            self.parent.panel_info.dropdown_hr_instrument.get_value(),
            self.parent.panel_info.check_nights_sim.get_value()
        )
        self.parent.panel_info.textfield_nights.insert_text(nights)
