"""Tests for conceptual_model.py."""

import pytest
from rtisanepy import (
    Unit, continuous, categories, causes, relates, equals, increases,
    ConceptualModel,
)


class TestAssumeHypothesize:
    def test_assume_returns_self(self):
        u = Unit("s", cardinality=10)
        x = continuous(u, "X")
        y = continuous(u, "Y")
        cm = ConceptualModel()
        result = cm.assume(causes(x, y))
        assert result is cm

    def test_hypothesize_returns_self(self):
        u = Unit("s", cardinality=10)
        x = continuous(u, "X")
        y = continuous(u, "Y")
        cm = ConceptualModel()
        result = cm.hypothesize(causes(x, y))
        assert result is cm

    def test_chaining(self):
        u = Unit("s", cardinality=10)
        x = continuous(u, "X")
        y = continuous(u, "Y")
        z = continuous(u, "Z")
        cm = (
            ConceptualModel()
            .assume(causes(x, y))
            .hypothesize(causes(y, z))
        )
        assert len(cm.relationships) == 2

    def test_variables_auto_tracked(self):
        u = Unit("s", cardinality=10)
        x = continuous(u, "X")
        y = continuous(u, "Y")
        cm = ConceptualModel().assume(causes(x, y))
        assert "X" in cm.variables
        assert "Y" in cm.variables

    def test_graph_built(self):
        u = Unit("s", cardinality=10)
        x = continuous(u, "X")
        y = continuous(u, "Y")
        cm = ConceptualModel().assume(causes(x, y))
        assert cm.graph.has_edge("X", "Y")


class TestInteracts:
    def test_interacts_annotation(self):
        u = Unit("s", cardinality=10)
        x = continuous(u, "X")
        z = continuous(u, "Z")
        y = continuous(u, "Y")
        cm = (
            ConceptualModel()
            .assume(causes(x, y))
            .assume(causes(z, y))
            .hypothesize(causes(x, y))
            .interacts(x, z, dv=y)
        )
        assert len(cm.interactions) == 1
        assert cm.interactions[0].dv.name == "Y"


class TestQueryValidation:
    def test_must_have_hypothesis(self):
        u = Unit("s", cardinality=10)
        x = continuous(u, "X")
        y = continuous(u, "Y")
        cm = ConceptualModel().assume(causes(x, y))
        with pytest.raises(ValueError, match="hypothesized"):
            cm.query(iv=x, dv=y)

    def test_hypothesis_must_connect_iv_dv(self):
        u = Unit("s", cardinality=10)
        x = continuous(u, "X")
        y = continuous(u, "Y")
        z = continuous(u, "Z")
        cm = ConceptualModel().hypothesize(causes(x, z))
        with pytest.raises(ValueError, match="No hypothesis connects"):
            cm.query(iv=x, dv=y)

    def test_relates_hypothesis_ok(self):
        u = Unit("s", cardinality=10)
        x = continuous(u, "X")
        y = continuous(u, "Y")
        cm = ConceptualModel().hypothesize(relates(x, y))
        model = cm.query(iv=x, dv=y)
        assert model.iv == "X"
        assert model.dv == "Y"
