import yaml

from src.data_classes.parameters_analysis_comparison_variance_in_and_between_group import (
    ComparisonVarianceInAndBetweenGroupParameters,
)
from src.data_classes.parameters_analysis_get_function_inverse_bayes_transformed_regression import (
    GetFunctionInverseBayesTransformedRegressionParameters,
)
from src.data_classes.parameters_analysis_influence_of_up_and_downvotes import (
    InfluenceOfVotesParameters,
)
from src.data_classes.parameters_analysis_regression import (
    BayesianRegressionParameters,
    LinearRegressionParameters,
    GroupedLinearRegressionParameters,
)
from src.data_classes.parameters_analysis_ttest import (
    TTestParameters,
    PairedTTestParameters,
)
from src.data_classes.parameters_analysis_pearson_correlation import (
    PearsonCorrelationParameters,
)
from src.data_classes.parameters_descriptive_aggregated import (
    DescriptiveAggregatedParameters,
)
from src.data_classes.parameters_descriptive_overview import (
    DescriptiveOverviewParameters,
)
from src.data_classes.parameters_descriptive_percentage_of_dataset_under_condition import (
    DescriptivePercentageOfDatasetUnderConditionParameters,
)
from src.data_classes.parameters_plot_barchart import BarChartPlotParameters

from src.data_classes.parameters_plot_boxplot import BoxPlotParameters
from src.data_classes.parameters_plot_contourplot import ContourPlotParameters
from src.data_classes.parameters_plot_count_distribution import (
    CountDistributionPlotParameters,
)
from src.data_classes.parameters_plot_densityplot import DensityPlotParameters
from src.data_classes.parameters_plot_forestplot import ForestPlotParameters
from src.data_classes.parameters_plot_forestplot_paired_ttest import ForestPlotPairedTTestParameters
from src.data_classes.parameters_plot_grouped_histogram import (
    GroupedHistogramParameters,
)
from src.data_classes.parameters_plot_heatmap import HeatmapParameters
from src.data_classes.parameters_plot_hexbinplot import HexbinPlotParameters
from src.data_classes.parameters_plot_histogram import HistogramPlotParameters
from src.data_classes.parameters_plot_percentage_stacked_barchart import (
    PercentageStackedBarChartPlotParameters,
)
from src.data_classes.parameters_plot_ridgelineplot import RidgelineParameters
from src.data_classes.parameters_plot_simple_scatterplot import (
    SimpleScatterPlotParameters,
)
from src.data_classes.parameters_plot_stacked_barchart import (
    StackedBarChartPlotParameters,
)
from src.data_classes.parameters_plot_surfaceplot import SurfacePlotParameters
from src.data_classes.parameters_plot_violinplot import ViolinPlotParameters


def custom_constructor(loader: yaml.Loader, tag_suffix: str, node: yaml.Node):
    """
    This function handles custom YAML tags and creates an instance of the appropriate class based on the tag suffix.

    Parameters:
    loader (yaml.Loader): The YAML loader instance.
    tag_suffix (str): The suffix of the YAML tag. This determines the class to be instantiated.
    node (yaml.Node): The YAML node to be transformed into a Python dictionary.

    Returns:
    _class: An instance of either LinearRegressionParameters or BayesianRegressionParameters class,
        depending on the tag suffix.

    Raises:
    ValueError: If the tag suffix is not a supported type of analysis or visualization.
    """
    if tag_suffix == "descriptive_aggregated":
        _class = DescriptiveAggregatedParameters
    elif tag_suffix == "descriptive_overview":
        _class = DescriptiveOverviewParameters
    elif tag_suffix == "percentage_of_dataset_under_condition":
        _class = DescriptivePercentageOfDatasetUnderConditionParameters
    elif tag_suffix == "comparison_variance_in_and_between_group":
        _class = ComparisonVarianceInAndBetweenGroupParameters
    elif tag_suffix == "linear_regression":
        _class = LinearRegressionParameters
    elif tag_suffix == "bayesian_regression":
        _class = BayesianRegressionParameters
    elif tag_suffix == "linear_regression_grouped":
        _class = GroupedLinearRegressionParameters
    elif tag_suffix == "increase_per_up_and_downvote_from_totalvotes_and_valence":
        _class = InfluenceOfVotesParameters
    elif tag_suffix == "function_inverse_bayes_transformed_regression":
        _class = GetFunctionInverseBayesTransformedRegressionParameters
    elif tag_suffix == "ttest":
        _class = TTestParameters
    elif tag_suffix == "paired_ttest":
        _class = PairedTTestParameters
    elif tag_suffix == "pearson_correlation":
        _class = PearsonCorrelationParameters
    elif tag_suffix == "barchart":
        _class = BarChartPlotParameters
    elif tag_suffix == "boxplot":
        _class = BoxPlotParameters
    elif tag_suffix == "contourplot":
        _class = ContourPlotParameters
    elif tag_suffix == "histogram":
        _class = HistogramPlotParameters
    elif tag_suffix == "count_distribution":
        _class = CountDistributionPlotParameters
    elif tag_suffix == "densityplot":
        _class = DensityPlotParameters
    elif tag_suffix == "forestplot":
        _class = ForestPlotParameters
    elif tag_suffix == "forestplot_paired_ttest":
        _class = ForestPlotPairedTTestParameters
    elif tag_suffix == "grouped_histogram":
        _class = GroupedHistogramParameters
    elif tag_suffix == "heatmap":
        _class = HeatmapParameters
    elif tag_suffix == "hexbinplot":
        _class = HexbinPlotParameters
    elif tag_suffix == "percentage_stacked_barchart":
        _class = PercentageStackedBarChartPlotParameters
    elif tag_suffix == "ridgelineplot":
        _class = RidgelineParameters
    elif tag_suffix == "simple_scatterplot":
        _class = SimpleScatterPlotParameters
    elif tag_suffix == "stacked_barchart":
        _class = StackedBarChartPlotParameters
    elif tag_suffix == "surfaceplot":
        _class = SurfacePlotParameters
    elif tag_suffix == "violinplot":
        _class = ViolinPlotParameters
    else:
        raise ValueError(
            f"Unexpected tag suffix: {tag_suffix}. Please check for typos or if the analysis is not supported"
        )

    instance_data = loader.construct_mapping(node, deep=True)
    return _class(**instance_data)
