"""Abstract base for LLM-driven summarizers."""

from abc import ABC, abstractmethod

from langchain_core.language_models.chat_models import BaseChatModel
from loguru import logger

from ...utilities.search_utilities import remove_think_tags


class BaseSummarizer(ABC):
    """Common machinery for invoking an LLM to summarize text.

    Subclasses provide the prompt via :meth:`_build_prompt`. The base class
    handles the model invocation, think-tag stripping, and length truncation.

    On LLM-invocation failure (network error, rate limit, malformed response)
    :meth:`summarize` returns an empty string. This is a deliberate choice for
    callers that aggregate the summary into a larger context update — losing
    one summary turn should not abort the rest of the update.
    """

    INPUT_TRUNCATE_CHARS = 8000

    def __init__(
        self,
        model: BaseChatModel,
        max_sentences: int = 3,
        max_chars: int = 300,
    ):
        self.model = model
        self.max_sentences = max_sentences
        self.max_chars = max_chars

    def summarize(self, content: str) -> str:
        if not content:
            return ""

        prompt = self._build_prompt(content[: self.INPUT_TRUNCATE_CHARS])

        try:
            response = self.model.invoke(prompt)
        except Exception:
            logger.opt(exception=True).debug("LLM summarization failed")
            return ""

        summary = remove_think_tags(str(response.content)).strip()
        return self._truncate(summary)

    @abstractmethod
    def _build_prompt(self, content: str) -> str:
        """Return the prompt sent to the LLM for ``content``."""

    def _truncate(self, summary: str) -> str:
        if len(summary) > self.max_chars:
            return summary[: self.max_chars].rstrip() + "..."
        return summary
