import unittest
from unittest.mock import Mock

from analogai.foundation.extensions.contradictions.contradictions_service import ContradictionsService
from analogai.foundation.modules.belief.belief import Belief
from analogai.foundation.modules.categorical_deduction.categorical_deduction import CategoricalDeduction
from analogai.foundation.modules.direct_statement.direct_statement import DirectStatement
from analogai.foundation.modules.notion.notion import Notion
from analogai.foundation.core.value_objects.relation import Relation


class TestContradictionsService(unittest.TestCase):
    def setUp(self):
        self.agent_id = "agent-1"
        self.user_id = "user-1"
        self.subject_notion = Notion(user_id=self.user_id, agent_id=self.agent_id, caption="S")
        self.complement_notion = Notion(user_id=self.user_id, agent_id=self.agent_id, caption="O")
        self.relation = Relation.from_string("is")

        self.statement = DirectStatement(
            user_id=self.user_id,
            agent_id=self.agent_id,
            subject_notion=self.subject_notion,
            complement_notion=self.complement_notion,
            relation=self.relation,
            probability=0.9,
            validity=0.9,
        )

        major = Belief(agent_id=self.agent_id)
        major.add_statement(self.statement)
        minor = Belief(agent_id=self.agent_id)
        minor.add_statement(self.statement)

        self.deduction = CategoricalDeduction(
            agent_id=self.agent_id,
            major_premise=major,
            minor_premise=minor,
            subject_notion=self.subject_notion,
            complement_notion=self.complement_notion,
            relation=self.relation,
        )

    def _build_belief(self, probability_values):
        belief = Belief(agent_id=self.agent_id)
        for prob in probability_values:
            belief.add_statement(
                DirectStatement(
                    user_id=self.user_id,
                    agent_id=self.agent_id,
                    subject_notion=self.subject_notion,
                    complement_notion=self.complement_notion,
                    relation=self.relation,
                    probability=prob,
                    validity=1.0,
                )
            )
        belief.add_statement(self.deduction)
        return belief

    def test_find_contradictory_beliefs_applies_pagination(self):
        belief_service = Mock()
        belief_service.get_all_for_agent.return_value = [
            self._build_belief([1.0, 0.0]),
            self._build_belief([0.95, 0.05]),
            self._build_belief([0.9, 0.1]),
        ]
        service = ContradictionsService(belief_service)

        results = service.find_contradictory_beliefs(
            agent_id=self.agent_id,
            limit=1,
            offset=1,
        )

        self.assertEqual(len(results), 1)

    def test_find_contradictory_beliefs_skips_without_deduction(self):
        belief_service = Mock()
        belief = Belief(agent_id=self.agent_id)
        belief.add_statement(self.statement)
        belief_service.get_all_for_agent.return_value = [belief]
        service = ContradictionsService(belief_service)

        results = service.find_contradictory_beliefs(agent_id=self.agent_id)

        self.assertEqual(results, [])


if __name__ == "__main__":
    unittest.main()
