"""Tests for run.chart() — defining visualizations for logged tables."""

from unittest.mock import MagicMock

import pytest

from tyko._types import Experiment, Project, Run


def _make_run() -> Run:
    mock_client = MagicMock()
    return Run(
        id="run-123",
        name="test-run",
        sequential=1,
        experiment=Experiment(name="default"),
        project=Project(name="test-project"),
        _client=mock_client,
        _client_uuid="test-uuid",
        _silent=True,
    )


class TestChart:
    def test_creates_line_chart(self) -> None:
        run = _make_run()

        run.chart("loss_curve", table="training", type="line", x="epoch", y="loss")

        run._client.create_chart.assert_called_once_with(
            "run-123",
            name="loss_curve",
            table="training",
            chart_type="line",
            x="epoch",
            y="loss",
            color=None,
        )

    def test_creates_scatter_chart(self) -> None:
        run = _make_run()

        run.chart("pred_vs_actual", table="predictions", type="scatter", x="actual", y="predicted")

        run._client.create_chart.assert_called_once_with(
            "run-123",
            name="pred_vs_actual",
            table="predictions",
            chart_type="scatter",
            x="actual",
            y="predicted",
            color=None,
        )

    def test_creates_bar_chart(self) -> None:
        run = _make_run()

        run.chart("class_dist", table="classes", type="bar", x="class", y="count")

        run._client.create_chart.assert_called_once_with(
            "run-123",
            name="class_dist",
            table="classes",
            chart_type="bar",
            x="class",
            y="count",
            color=None,
        )

    def test_creates_histogram(self) -> None:
        run = _make_run()

        run.chart("loss_dist", table="training", type="histogram", x="loss", y=None)

        run._client.create_chart.assert_called_once_with(
            "run-123",
            name="loss_dist",
            table="training",
            chart_type="histogram",
            x="loss",
            y=None,
            color=None,
        )

    def test_color_parameter(self) -> None:
        run = _make_run()

        run.chart("by_class", table="preds", type="scatter", x="x", y="y", color="label")

        run._client.create_chart.assert_called_once_with(
            "run-123",
            name="by_class",
            table="preds",
            chart_type="scatter",
            x="x",
            y="y",
            color="label",
        )

    def test_rejects_invalid_type(self) -> None:
        run = _make_run()

        with pytest.raises(ValueError, match="Invalid chart type"):
            run.chart("bad", table="t", type="pie", x="a", y="b")

        run._client.create_chart.assert_not_called()

    def test_y_optional_for_histogram(self) -> None:
        run = _make_run()

        run.chart("hist", table="data", type="histogram", x="values")

        run._client.create_chart.assert_called_once()
        call_kwargs = run._client.create_chart.call_args
        assert call_kwargs[1]["y"] is None
