import unittest
from typing import List
from analogai.foundation.common.dtos.notion_expression import NotionExpression
from analogai.foundation.tests.functional.services.setup import ServicesTestConfig

class TestNotionServiceFunctional(unittest.TestCase):
    def setUp(self):
        self.config = ServicesTestConfig()
        self.notion_service = self.config.notion_service
        self.user = self.config.user
        self.agent = self.config.agent

    def tearDown(self):
        self.config.tear_down()

    def _create_expression(self, caption: str, context: List[NotionExpression] = None) -> NotionExpression:
        return NotionExpression(caption=caption, context=context or [])

    def test_find_or_create_idempotent(self):
        expr = self._create_expression("idea")
        first = self.notion_service.find_or_create(self.user.id, self.agent.id, expr)
        second = self.notion_service.find_or_create(self.user.id, self.agent.id, expr)
        self.assertEqual(first.id, second.id)

    def test_find_respects_agent_isolation(self):
        expr = self._create_expression("shared")
        notion_agent1 = self.notion_service.find_or_create(self.user.id, self.agent.id, expr)
        agent2 = self.config.agent_service.create(creator=self.user, id="agent-isolation-alt")
        found_agent2 = self.notion_service.find(agent2.id, expr)
        self.assertIsNone(found_agent2)
        found_agent1 = self.notion_service.find(self.agent.id, expr)
        self.assertEqual(found_agent1.id, notion_agent1.id)

    def test_stored_notion_omits_context_field(self):
        expr = self._create_expression("plain")
        notion = self.notion_service.find_or_create(self.user.id, self.agent.id, expr)
        stored = self.config.notion_repository.find_by_id(notion.id)
        self.assertIsNotNone(stored)
        self.assertEqual(stored.caption, "plain")
        self.assertEqual(stored.id, notion.id)

    def test_find_or_create_returns_existing_notion_when_same_caption(self):
        expr1 = self._create_expression("duplicate_test")
        first_notion = self.notion_service.find_or_create(self.user.id, self.agent.id, expr1)
        first_notion_id = first_notion.id
        
        expr2 = self._create_expression("duplicate_test")
        second_notion = self.notion_service.find_or_create(self.user.id, self.agent.id, expr2)
        
        self.assertEqual(first_notion_id, second_notion.id)
        self.assertEqual(first_notion.caption, second_notion.caption)
        self.assertEqual(first_notion.agent_id, second_notion.agent_id)
        
        found_notion = self.notion_service.find(self.agent.id, NotionExpression(caption="duplicate_test"))
        self.assertIsNotNone(found_notion)
        self.assertEqual(found_notion.id, first_notion_id)

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

