"""Bar chart block implementation."""

from __future__ import annotations

from collections.abc import Sequence
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    import pandas as pd

from yera.events.blocks.base import _ChartBlockFactory
from yera.events.blocks.base.chart import _ChartConversionData
from yera.events.models import BarChartData
from yera.events.stream import push_output


class _BarChartBlockFactory(_ChartBlockFactory):
    """Factory for creating bar chart blocks, matching Streamlit's st.bar_chart API."""

    def __init__(self):
        super().__init__("bar_chart")

    def _create_chart_data_from_conversion(
        self,
        conversion_data: _ChartConversionData,
        chart_specific_params: dict,
    ) -> BarChartData:
        """Convert intermediate data to BarChartData."""
        return BarChartData(
            x_label=conversion_data.x_label,
            x_categories=conversion_data.x_categories or [],
            y_label=conversion_data.y_label,
            y_values=conversion_data.y_values,
            colour_label=conversion_data.colour_label,
            colour_categories=conversion_data.colour_categories,
            colour_values=conversion_data.colour_values,
            horizontal=chart_specific_params.get("horizontal", False),
            stack=chart_specific_params.get("stack", True),
        )

    def __call__(
        self,
        data: pd.DataFrame,
        *,
        x: str | None = None,
        y: str | Sequence[str] | None = None,
        colour: str | Sequence[str] | None = None,
        horizontal: bool = False,
        stack: bool = True,
    ) -> None:
        """Create a bar chart block, matching Streamlit's st.bar_chart() signature.

        Args:
            data: DataFrame to plot
            x: Column name for x-axis (None = use index)
            y: Column name(s) for y-axis (None = use all columns except x)
            colour: Column name for colour grouping, or list of colors
            horizontal: Whether bars are horizontal
            stack: Whether bars are stacked

        Returns:
            None (informational block)

        """
        chart_specific_params = {"horizontal": horizontal, "stack": stack}

        if x is None and y is None:
            conversion_data = self._convert_default_format(data)
        elif x is not None and isinstance(y, str):
            conversion_data = self._convert_long_format(data, x, y, colour)
        elif x is not None and isinstance(y, Sequence) and not isinstance(y, str):
            conversion_data = self._convert_wide_format(data, x, y, colour)
        else:
            raise ValueError(
                f"Unsupported bar_chart parameter combination: x={x}, y={y}"
            )

        chart_data = self._create_chart_data_from_conversion(
            conversion_data, chart_specific_params
        )

        event = self._create_block_output_event(
            chart_data, message_type="informational"
        )
        push_output(event)
        return


# Create the bar_chart callable
bar_chart = _BarChartBlockFactory()

__all__ = ["bar_chart"]
