"""LLM-powered thread title generation."""

from __future__ import annotations

import logging
import re
from typing import TYPE_CHECKING

from icarus.session.threads import _MAX_TITLE_LENGTH

if TYPE_CHECKING:
    from langchain_core.language_models import BaseChatModel

logger = logging.getLogger(__name__)

_MAX_RESPONSE_CONTEXT = 200
_MAX_TITLE_WORDS = 6
_MARKDOWN_RE = re.compile(r"[*_`#~\[\]]")

_SYSTEM_PROMPT = (
    "Generate a short title (max 6 words) for this conversation. "
    "Reply with ONLY the title, no quotes or punctuation."
)


def _truncate_title(title: str) -> str:
    """Enforce word and character limits and strip markdown from a generated title."""
    title = _MARKDOWN_RE.sub("", title).strip()
    words = title.split()
    if len(words) > _MAX_TITLE_WORDS:
        title = " ".join(words[:_MAX_TITLE_WORDS])
    if len(title) > _MAX_TITLE_LENGTH:
        title = title[:_MAX_TITLE_LENGTH].rstrip() + "..."
    return title


async def generate_title(
    model: BaseChatModel,
    user_message: str,
    assistant_response: str,
) -> str | None:
    """Generate a concise thread title from the first exchange.

    Uses the active model without provider-specific parameters so it
    works with any backend (OpenAI, Anthropic, Ollama, Azure).
    The result is truncated in Python to guarantee a short title.

    Args:
        model: The LLM to use (user's active model).
        user_message: The first human message in the thread.
        assistant_response: The first assistant response (will be truncated).

    Returns:
        A short title string, or ``None`` if generation fails.
    """
    from langchain_core.messages import HumanMessage, SystemMessage

    truncated = assistant_response[:_MAX_RESPONSE_CONTEXT]
    if len(assistant_response) > _MAX_RESPONSE_CONTEXT:
        truncated += "..."

    messages = [
        SystemMessage(content=_SYSTEM_PROMPT),
        HumanMessage(
            content=f"User: {user_message}\nAssistant: {truncated}"
        ),
    ]

    try:
        result = await model.ainvoke(messages)
        title = result.content
        if isinstance(title, str):
            title = title.strip().strip('"').strip("'").strip()
            if title:
                return _truncate_title(title)
        return None
    except Exception:
        logger.debug("Title generation failed; falling back to default", exc_info=True)
        return None
