import unittest
from analogai.deepthink.presentation.postprocessing.postprocessors.pronoun_postprocessior import (
    postprocesses_pronouns,
    AgentMessagePronounPostprocessor,
    PlaceholderPronounReplacer,
    _lowercase_first_letter,
    _uppercase_first_letter,
)
from analogai.deepthink.presentation.enums.pronoun_placeholder import PronounPlaceholder


class TestPronounPostprocessorTemplate(unittest.TestCase):
    def test_lowercase_first_letter_empty(self):
        self.assertEqual(_lowercase_first_letter(""), "")
        self.assertEqual(_lowercase_first_letter("   "), "   ")

    def test_lowercase_first_letter_single_word(self):
        self.assertEqual(_lowercase_first_letter("Hello"), "hello")

    def test_lowercase_first_letter_leading_space(self):
        self.assertEqual(_lowercase_first_letter("  Hello world"), "  hello world")

    def test_uppercase_first_letter_single_word(self):
        self.assertEqual(_uppercase_first_letter("hello"), "Hello")

    def test_uppercase_first_letter_leading_space(self):
        self.assertEqual(_uppercase_first_letter("  hello world"), "  Hello world")


class TestPronounPostprocessorToPronoun(unittest.TestCase):
    def test_agent_placeholder_to_i(self):
        agent = PronounPlaceholder.AGENT_PLACEHOLDER.value
        result = postprocesses_pronouns(f"{agent} think so")
        self.assertEqual(result, "I think so")

    def test_agent_placeholder_is_to_i_am(self):
        agent = PronounPlaceholder.AGENT_PLACEHOLDER.value
        result = postprocesses_pronouns(f"{agent} is great")
        self.assertEqual(result, "I am great")

    def test_respondent_placeholder_to_you(self):
        respondent = PronounPlaceholder.RESPONDENT_PLACEHOLDER.value
        result = postprocesses_pronouns(f"{respondent} are here")
        self.assertEqual(result, "You are here")

    def test_respondent_placeholder_is_to_you_are(self):
        respondent = PronounPlaceholder.RESPONDENT_PLACEHOLDER.value
        result = postprocesses_pronouns(f"{respondent} is smart")
        self.assertEqual(result, "You are smart")

    def test_respondent_placeholder_with_identifier(self):
        respondent = PronounPlaceholder.RESPONDENT_PLACEHOLDER.value
        result = postprocesses_pronouns(f"{respondent} is founder")
        self.assertEqual(result, "You are founder")

    def test_company_placeholder_to_we(self):
        company = PronounPlaceholder.COMPANY_PLACEHOLDER.value
        result = postprocesses_pronouns(f"{company} sell iphones")
        self.assertEqual(result, "We sell iphones")

    def test_company_placeholder_is_to_we_are(self):
        company = PronounPlaceholder.COMPANY_PLACEHOLDER.value
        result = postprocesses_pronouns(f"{company} is ready")
        self.assertEqual(result, "We are ready")

    def test_i_does_to_i_do(self):
        result = postprocesses_pronouns("I does think so")
        self.assertEqual(result, "I do think so")

    def test_you_does_to_you_do(self):
        result = postprocesses_pronouns("you does know")
        self.assertEqual(result, "You do know")


class TestPronounPostprocessorFirstLetterCase(unittest.TestCase):
    def test_uppercase_restored_after_replace(self):
        agent = PronounPlaceholder.AGENT_PLACEHOLDER.value
        result = postprocesses_pronouns(f"{agent} is happy")
        self.assertEqual(result[0], "I")
        self.assertEqual(result, "I am happy")

    def test_leading_space_preserves_uppercase_restore(self):
        agent = PronounPlaceholder.AGENT_PLACEHOLDER.value
        result = postprocesses_pronouns(f"  {agent} is here")
        self.assertEqual(result, "  I am here")


class TestPronounPostprocessorNoDuplicateReplacement(unittest.TestCase):
    def test_single_pass_agent(self):
        agent = PronounPlaceholder.AGENT_PLACEHOLDER.value
        result = postprocesses_pronouns(agent)
        self.assertEqual(result, "I")

    def test_agent_placeholder_s_to_my(self):
        agent = PronounPlaceholder.AGENT_PLACEHOLDER.value
        result = postprocesses_pronouns(f"{agent}'s voice")
        self.assertEqual(result, "My voice")

    def test_respondent_placeholder_s_to_your(self):
        respondent = PronounPlaceholder.RESPONDENT_PLACEHOLDER.value
        result = postprocesses_pronouns(f"{respondent}'s name")
        self.assertEqual(result, "Your name")
