import unittest
from unittest.mock import Mock
from analogai.foundation.common.enums import RelationshipType
from analogai.foundation.common.dtos.notion_expression import NotionExpression
from analogai.foundation.core.value_objects import Relation
from analogai.deepthink.application.usecases.learning.make_direct_statement.states.context.learner_context_handler import LearnerContextHandler
from analogai.deepthink.application.usecases.learning.make_direct_statement.states.context.learner_context import LearnerContext
from analogai.deepthink.application.value_objects.user_agent import UserAgent
from analogai.deepthink.application.usecases.learning.make_direct_statement.models import MakeDirectStatementRequest


class TestLearnerContextCreator(unittest.TestCase):
    def setUp(self):
        self.mock_notion_service = Mock()
        self.context = LearnerContext()
        self.factory = LearnerContextHandler(self.context, self.mock_notion_service)

        self.subject_expression = NotionExpression(caption="subject_notion")
        self.object_expression = NotionExpression(caption="complement_notion")
        self.relation = Relation.from_type(RelationshipType.IS_A)
        self.probability_value = 0.8

        self.user_agent = UserAgent(
            user_id="test-user",
            agent_id="test-agent",
            user_authority=0.9
        )

        self.mock_request = MakeDirectStatementRequest(
            user_agent=self.user_agent,
            subject_notion_expression=self.subject_expression,
            complement_notion_expression=self.object_expression,
            relation=self.relation,
            probability=self.probability_value,
            modifier=None,
        )

        self.mock_subject_notion = Mock()
        self.mock_complement_notion = Mock()

    def test_init_with_notion_service(self):
        context = LearnerContext()
        factory = LearnerContextHandler(context, self.mock_notion_service)
        self.assertEqual(factory.notion_service, self.mock_notion_service)

    def test_create(self):
        self.mock_notion_service.find_or_create.side_effect = [
            self.mock_subject_notion,
            self.mock_complement_notion
        ]

        context = self.factory.create_from_request(self.mock_request)

        self.assertIsInstance(context, LearnerContext)
        self.assertEqual(context.user_agent.user_id, "test-user")
        self.assertEqual(context.user_agent.agent_id, "test-agent")
        self.assertEqual(context.user_agent.user_authority, 0.9)
        self.assertEqual(context.subject_notion, self.mock_subject_notion)
        self.assertEqual(context.complement_notion, self.mock_complement_notion)
        self.assertEqual(context.relation, self.relation)
        self.assertEqual(context.proposed_probability, self.probability_value)

        self.mock_notion_service.find_or_create.assert_any_call(
            self.user_agent.user_id, self.user_agent.agent_id, self.subject_expression
        )
        self.mock_notion_service.find_or_create.assert_any_call(
            self.user_agent.user_id, self.user_agent.agent_id, self.object_expression
        )

    def test_get_proposed_validity(self):
        self.mock_notion_service.find_or_create.side_effect = [
            self.mock_subject_notion,
            self.mock_complement_notion
        ]
        self.factory.create_from_request(self.mock_request)
        validity = self.factory._get_proposed_validity()
        self.assertIsNotNone(validity)

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




