import unittest
from types import SimpleNamespace
from unittest.mock import AsyncMock, patch

from app.services.profile_preferences import (
    extract_profile_naming_update,
    persist_profile_naming_update,
)


class ProfilePreferenceTests(unittest.IsolatedAsyncioTestCase):
    def test_extract_character_name_from_english_phrase(self):
        update = extract_profile_naming_update("I'll call you Moon.")

        self.assertEqual(update.character_name, "Moon")
        self.assertIsNone(update.user_call_name)

    def test_extract_user_call_name_from_vietnamese_phrase(self):
        update = extract_profile_naming_update("Em gọi anh là cưng.")

        self.assertIsNone(update.character_name)
        self.assertEqual(update.user_call_name, "cưng")

    async def test_persist_profile_naming_update_saves_detected_values(self):
        profile = SimpleNamespace(name="Mochi", user_call_name=None)

        with patch(
            "app.services.profile_preferences.agent_profile_repo.update_profile",
            new=AsyncMock(),
        ) as update_profile:
            changed = await persist_profile_naming_update(profile, "You can call me honey.")

        self.assertTrue(changed)
        self.assertEqual(profile.name, "Mochi")
        self.assertEqual(profile.user_call_name, "honey")
        update_profile.assert_awaited_once_with(profile)

    async def test_persist_profile_naming_update_skips_ambiguous_messages(self):
        profile = SimpleNamespace(name="Mochi", user_call_name=None)

        with patch(
            "app.services.profile_preferences.agent_profile_repo.update_profile",
            new=AsyncMock(),
        ) as update_profile:
            changed = await persist_profile_naming_update(profile, "You are very sweet today.")

        self.assertFalse(changed)
        self.assertEqual(profile.name, "Mochi")
        self.assertIsNone(profile.user_call_name)
        update_profile.assert_not_awaited()


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