import re
from abc import ABC, abstractmethod
from analogai.deepthink.presentation.enums.pronoun_placeholder import PronounPlaceholder


def _lowercase_first_letter(text: str) -> str:
    if not text or not text.strip():
        return text
    stripped = text.lstrip()
    if not stripped:
        return text
    first = stripped[0].lower()
    return text[: len(text) - len(stripped)] + first + stripped[1:]


def _uppercase_first_letter(text: str) -> str:
    if not text or not text.strip():
        return text
    stripped = text.lstrip()
    if not stripped:
        return text
    first = stripped[0].upper()
    return text[: len(text) - len(stripped)] + first + stripped[1:]


class PronounReplacementStep(ABC):
    @abstractmethod
    def apply(self, text: str) -> str:
        pass


class PlaceholderPronounReplacer(PronounReplacementStep):
    def apply(self, text: str) -> str:
        company = PronounPlaceholder.COMPANY_PLACEHOLDER.value
        agent = PronounPlaceholder.AGENT_PLACEHOLDER.value
        respondent = PronounPlaceholder.RESPONDENT_PLACEHOLDER.value

        result = text
        result = re.sub(rf"{respondent}[:#-][\w-]+", respondent, result, flags=re.IGNORECASE)
        patterns = [
            (f"an {agent}", "I"),
            (f"the {agent}", "I"),
            (f"a {respondent}", "you"),
            (f"the {respondent}", "you"),
            ("the company", "company"),
            ("a company", "company"),
            (f"{agent} is", "I am"),
            (f"{agent}'s", "my"),
            (f"{agent}s", "I"),
            (agent, "I"),
            ("I does", "I do"),
            (f"{respondent} is", "you are"),
            (f"{respondent}'s", "your"),
            (f"{respondent}s", "you"),
            (respondent, "you"),
            ("you does", "you do"),
            (f"{company} is", "we are"),
            (f"{company}'s", "our"),
            (f"{company} does", "we do"),
            (company, "we"),
        ]
        for pattern, replacement in patterns:
            result = re.sub(re.escape(pattern), replacement, result, flags=re.IGNORECASE)
        return result


class AgentMessagePronounPostprocessor:
    def __init__(self, replacer: PronounReplacementStep):
        self._replacer = replacer

    def format(self, text: str) -> str:
        if not text or not text.strip():
            return text
        lower = _lowercase_first_letter(text)
        replaced = self._replacer.apply(lower)
        return _uppercase_first_letter(replaced)


_default_postprocessor = AgentMessagePronounPostprocessor(PlaceholderPronounReplacer())


def postprocesses_pronouns(text: str) -> str:
    return _default_postprocessor.format(text)
