from openlog.datamodel.assay.generic_assay import (
    AssayDataExtent,
    AssayDefinition,
    AssaySeriesType,
)
from openlog.gui.assay_visualization.config.assay_column_visualization_config import (
    AssayColumnVisualizationConfig,
)
from openlog.gui.assay_visualization.discrete.config import (
    DiscreteAssayColumnVisualizationConfig,
    DiscreteCategoricalAssayColumnVisualizationConfig,
)
from openlog.gui.assay_visualization.extended.config import (
    ExtendedCategoricalAssayColumnVisualizationConfig,
    ExtendedImageryColumnVisualizationConfig,
    ExtendedNominalAssayColumnVisualizationConfig,
    ExtendedNumericalAssayColumnVisualizationConfig,
)


class AssayColumnVisualizationConfigFactory:
    """Factory class for assay column visualization creation"""

    def create_config(
        self, assay_definition: AssayDefinition, column: str
    ) -> AssayColumnVisualizationConfig:
        """
        Create an assay column visualization config from assay definition

        Args:
            assay_definition: AssayDefinition
            column: assay column

        Returns: (AssayColumnVisualizationConfig)

        """
        if assay_definition.data_extent == AssayDataExtent.EXTENDED:
            return self.create_extended_config(assay_definition, column)
        else:
            return self.create_discrete_config(assay_definition, column)

    @staticmethod
    def create_extended_config(
        assay_definition: AssayDefinition, column: str
    ) -> AssayColumnVisualizationConfig:
        """
        Create an assay column visualization config from extended assay definition

        Args:
            assay_definition: AssayDefinition
            column: assay column

        Returns: (AssayColumnVisualizationConfig)

        """
        if (
            assay_definition.columns[column].series_type == AssaySeriesType.NUMERICAL
            or assay_definition.columns[column].series_type == AssaySeriesType.DATETIME
        ):
            return ExtendedNumericalAssayColumnVisualizationConfig(
                column=assay_definition.columns[column],
                discrete_configuration=DiscreteAssayColumnVisualizationConfig(
                    assay_definition.columns[column], extended_config=None
                ),
            )
        elif (
            assay_definition.columns[column].series_type == AssaySeriesType.CATEGORICAL
        ):
            return ExtendedCategoricalAssayColumnVisualizationConfig(
                column=assay_definition.columns[column]
            )
        elif assay_definition.columns[column].series_type == AssaySeriesType.NOMINAL:
            return ExtendedNominalAssayColumnVisualizationConfig(
                column=assay_definition.columns[column]
            )
        elif assay_definition.columns[column].series_type == AssaySeriesType.IMAGERY:
            return ExtendedImageryColumnVisualizationConfig(
                column=assay_definition.columns[column]
            )

    @staticmethod
    def create_discrete_config(
        assay_definition: AssayDefinition, column: str
    ) -> AssayColumnVisualizationConfig:
        """
        Create an assay column visualization config from discrete assay definition

        Args:
            assay_definition: AssayDefinition
            column: assay column

        Returns: (AssayColumnVisualizationConfig)

        """
        if assay_definition.columns[column].series_type == AssaySeriesType.CATEGORICAL:
            return DiscreteCategoricalAssayColumnVisualizationConfig(
                column=assay_definition.columns[column]
            )

        else:

            return DiscreteAssayColumnVisualizationConfig(
                column=assay_definition.columns[column],
                extended_config=ExtendedNumericalAssayColumnVisualizationConfig(
                    assay_definition.columns[column], discrete_configuration=None
                ),
            )
