import unittest
from datetime import datetime, timedelta
from analogai.foundation.common.enums.deontic_modality import DeonticModality
from analogai.foundation.common.utils.statement_serializers import StatementSerializer, serialize_statement
from analogai.foundation.core.value_objects.modifier import Modifier
from analogai.foundation.core.value_objects.relation import Relation
from analogai.foundation.core.value_objects.time import Time


class TestStatementSerializer(unittest.TestCase):
    
    def test_serialize_basic(self):
        serializer = StatementSerializer.create_default()
        result = serializer.serialize("Human", "is", "mortal", 0.8)
        self.assertIn("Human", result)
        self.assertIn("mortal", result)
    
    def test_serialize_negative_probability(self):
        serializer = StatementSerializer.create_default()
        result = serializer.serialize("Human", "is", "mortal", 0.2)
        self.assertIn("not", result.lower())
    
    def test_serialize_uncertain_probability(self):
        serializer = StatementSerializer.create_default()
        result = serializer.serialize("Human", "is", "mortal", 0.5)
        self.assertIn("might", result.lower())
    
    def test_serialize_statement_with_modifier(self):
        today = datetime.now()
        modifier = Modifier(
            location="Rome",
            from_time=Time(year=today.year, month=today.month, day=today.day)
        )
        result = serialize_statement(
            "Human",
            "mortal",
            Relation.from_string("is"),
            0.8,
            modifier
        )
        self.assertIn("human", result.lower())
        self.assertIn("mortal", result.lower())
        self.assertIn("rome", result.lower())
    
    def test_serialize_statement_with_timezone(self):
        today = datetime.now()
        modifier = Modifier(
            location="New York",
            from_time=Time(year=today.year, month=today.month, day=today.day)
        )
        result = serialize_statement(
            "Human",
            "mortal",
            Relation.from_string("is"),
            0.8,
            modifier,
            timezone="America/New_York"
        )
        self.assertIn("human", result.lower())
        self.assertIn("mortal", result.lower())
        self.assertIn("new york", result.lower())
    
    def test_serialize_statement_with_different_timezones(self):
        today = datetime.now()
        modifier = Modifier(
            from_time=Time(year=today.year, month=today.month, day=today.day)
        )
        
        result_ny = serialize_statement(
            "Human",
            "mortal",
            Relation.from_string("is"),
            0.8,
            modifier,
            timezone="America/New_York"
        )
        
        result_london = serialize_statement(
            "Human",
            "mortal",
            Relation.from_string("is"),
            0.8,
            modifier,
            timezone="Europe/London"
        )
        
        result_tokyo = serialize_statement(
            "Human",
            "mortal",
            Relation.from_string("is"),
            0.8,
            modifier,
            timezone="Asia/Tokyo"
        )
        
        self.assertIn("human", result_ny.lower())
        self.assertIn("mortal", result_ny.lower())
        self.assertIn("human", result_london.lower())
        self.assertIn("mortal", result_london.lower())
        self.assertIn("human", result_tokyo.lower())
        self.assertIn("mortal", result_tokyo.lower())
    
    def test_serialize_statement_without_timezone(self):
        today = datetime.now()
        modifier = Modifier(
            from_time=Time(year=today.year, month=today.month, day=today.day)
        )
        result = serialize_statement(
            "Human",
            "mortal",
            Relation.from_string("is"),
            0.8,
            modifier
        )
        self.assertIn("human", result.lower())
        self.assertIn("mortal", result.lower())
    
    def test_serialize_statement_with_obligatory_deontic_modality(self):
        modifier = Modifier(deontic_modality=DeonticModality.OBLIGATORY)
        result = serialize_statement(
            "aristotle",
            "iphone",
            Relation.from_string("do"),
            0.8,
            modifier
        )
        self.assertIn("aristotle", result.lower())
        self.assertIn("iphone", result.lower())
        self.assertIn("must", result.lower())
        self.assertNotIn("it is obligatory", result.lower())
    
    def test_serialize_statement_with_permitted_deontic_modality(self):
        modifier = Modifier(deontic_modality=DeonticModality.PERMITTED)
        result = serialize_statement(
            "aristotle",
            "iphone",
            Relation.from_string("do"),
            0.8,
            modifier
        )
        self.assertIn("aristotle", result.lower())
        self.assertIn("iphone", result.lower())
        self.assertIn("can", result.lower())
    
    def test_serialize_statement_with_forbidden_deontic_modality(self):
        modifier = Modifier(deontic_modality=DeonticModality.FORBIDDEN)
        result = serialize_statement(
            "aristotle",
            "iphone",
            Relation.from_string("do"),
            0.8,
            modifier
        )
        self.assertIn("aristotle", result.lower())
        self.assertIn("iphone", result.lower())
        self.assertIn("can not", result.lower())


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