"""Tests for src/pygui/backend/visualization/graph_view.py."""
import json
from unittest.mock import MagicMock


def _make_plot_widget():
    """Create a mock PlotWidget with the interface GraphView expects."""
    widget = MagicMock()
    widget.removeItem = MagicMock()
    widget.plot = MagicMock(return_value=MagicMock())
    widget.setYRange = MagicMock()
    widget.clear = MagicMock()
    return widget


class TestUpdateTrend:
    def test_parses_valid_json(self):
        from pygui.backend.visualization.graph_view import GraphView

        gv = GraphView()
        gv._plot_widget = _make_plot_widget()

        gv.updateTrend(json.dumps([20.0, 25.0, 30.0]))

        assert gv._plot_widget.plot.called
        gv._plot_widget.setYRange.assert_called_once()

    def test_rejects_invalid_json(self):
        from pygui.backend.visualization.graph_view import GraphView

        gv = GraphView()
        gv._plot_widget = _make_plot_widget()

        gv.updateTrend("not json")

        assert not gv._plot_widget.plot.called

    def test_rejects_none(self):
        from pygui.backend.visualization.graph_view import GraphView

        gv = GraphView()
        gv._plot_widget = _make_plot_widget()

        gv.updateTrend(None)

        assert not gv._plot_widget.plot.called

    def test_empty_list(self):
        from pygui.backend.visualization.graph_view import GraphView

        gv = GraphView()
        gv._plot_widget = _make_plot_widget()

        gv.updateTrend("[]")

        # Empty list means nothing to plot, but clear IS called
        assert gv._plot_widget.plot.called is False

    def test_no_plot_widget(self):
        from pygui.backend.visualization.graph_view import GraphView

        gv = GraphView()
        assert gv._plot_widget is None

        # Should not crash
        gv.updateTrend("[1, 2, 3]")


class TestUpdateChart:
    def test_plots_one_series_per_sensor(self):
        from pygui.backend.visualization.graph_view import GraphView

        gv = GraphView()
        gv._plot_widget = _make_plot_widget()

        series = [[150.0, 151.0, 152.0], [148.5, 148.4, 148.6]]
        gv.updateChart("Sensor 1,Sensor 2", json.dumps(series))

        assert gv._plot_widget.clear.called
        assert gv._plot_widget.plot.call_count == 2
        assert gv._sensor_names == ["Sensor 1", "Sensor 2"]

    def test_rejects_invalid_json(self):
        from pygui.backend.visualization.graph_view import GraphView

        gv = GraphView()
        gv._plot_widget = _make_plot_widget()

        gv.updateChart("Sensor 1", "not json")

        assert not gv._plot_widget.plot.called

    def test_empty_series_clears_without_plotting(self):
        from pygui.backend.visualization.graph_view import GraphView

        gv = GraphView()
        gv._plot_widget = _make_plot_widget()

        gv.updateChart("", "[]")

        assert gv._plot_widget.clear.called
        assert not gv._plot_widget.plot.called

    def test_no_plot_widget(self):
        from pygui.backend.visualization.graph_view import GraphView

        gv = GraphView()
        assert gv._plot_widget is None

        # Should not crash
        gv.updateChart("Sensor 1", json.dumps([[1.0, 2.0]]))


class TestUpdateComparison:
    def test_parses_valid_json(self):
        from pygui.backend.visualization.graph_view import GraphView

        gv = GraphView()
        gv._plot_widget = _make_plot_widget()

        a = [10.0, 20.0, 30.0]
        b = [12.0, 22.0, 32.0]
        path = [[0, 0], [1, 1], [2, 2]]

        gv.updateComparison(json.dumps(a), json.dumps(b), json.dumps(path))

        assert gv._plot_widget.clear.called
        assert gv._plot_widget.plot.call_count == 2

    def test_rejects_invalid_json(self):
        """clear() is called before parsing, so it always fires on valid widget."""
        from pygui.backend.visualization.graph_view import GraphView

        gv = GraphView()
        gv._plot_widget = _make_plot_widget()

        gv.updateComparison("bad", json.dumps([1]), json.dumps([]))

        # clear() is called before parsing — it always fires
        assert gv._plot_widget.clear.called
        # But plot() should NOT be called since parsing fails
        assert not gv._plot_widget.plot.called

    def test_no_plot_widget(self):
        from pygui.backend.visualization.graph_view import GraphView

        gv = GraphView()
        assert gv._plot_widget is None

        # Should not crash
        gv.updateComparison("[1,2]", "[3,4]", "[[0,0]]")
