from statsmodels.regression.linear_model import RegressionResults

from src.analysis_functions.regression import Regression

from src.data_classes.parameters_analysis_regression import (
    RegressionParameters,
    BayesianRegressionParameters,
    LinearRegressionParameters,
    GroupedLinearRegressionParameters,
)
from src.utils.helper_logging import log_regression_details


def run_regression(
    regression: Regression, analyses_list: list[RegressionParameters]
) -> dict[str, RegressionResults]:
    """
    Run regression analyses based on a list of parameter objects.

    This function iterates over a list of RegressionParameters objects,
    and then performs the appropriate regression analysis based on the
    type of the RegressionParameters object.

    Parameters
    ----------
    regression: Regression
        An instance of the Regression class.
    analyses_list: list[RegressionParameters]
        A list of RegressionParameters objects.
        Each object contains the parameters for a single regression analysis.

    Raises
    ------
    ValueError: If the type of the RegressionParameters object is not recognized.

    Returns
    -------
    dict[str, RegressionResults]
        A dictionary of regression results, where the key is the name of the analysis
        and the value is the regression results.
    """

    regression_results: dict = {}

    for analysis_config in analyses_list:
        result = None

        if isinstance(analysis_config, LinearRegressionParameters):
            log_regression_details(analysis_config, "Linear")

            result = regression.linear_regression(
                data=analysis_config.data,
                x_vector=analysis_config.independent_variables,
                y=analysis_config.dependent_variable,
                standardize=analysis_config.standardize,
                name_save_file=analysis_config.name_save_file,
            )
        elif isinstance(analysis_config, BayesianRegressionParameters):
            log_regression_details(analysis_config, "Bayesian")

            regression.bayesian_regression(
                data=analysis_config.data,
                x_vector=analysis_config.independent_variables,
                y=analysis_config.dependent_variable,
                name_save_file=analysis_config.name_save_file,
            )
        elif isinstance(analysis_config, GroupedLinearRegressionParameters):
            log_regression_details(analysis_config, "Grouped")

            result = regression.linear_regression_grouped(
                data=analysis_config.data,
                x_vector=analysis_config.independent_variables,
                y=analysis_config.dependent_variable,
                dictionary_aggregation_methods_for_data_columns=analysis_config.dictionary_aggregation_methods,
                column_to_group_by=analysis_config.group_by,
                standardize=analysis_config.standardize,
                print_detailed_coefficients=analysis_config.print_detailed_coefficients,
                name_save_file=analysis_config.name_save_file,
            )
        else:
            raise ValueError(f"Unknown parameter type: {type(analysis_config)}")

        regression_results[analysis_config.name]: RegressionResults = result

    return regression_results
