"""Mistral AI integration for chapter summarization."""

from __future__ import annotations

import os
import sys
import time

from mistralai import Mistral
from mistralai.models import SDKError

SYSTEM_PROMPT = """\
You are a book summarizer. You produce clear, structured summaries in Markdown format.
Rules:
- Summarize the key ideas, arguments, and conclusions
- Keep the summary under 500 words
- Use bullet points for lists of key points
- Preserve important names, dates, and figures
- Do not add information not present in the source text
- Write in the same language as the source text — if the chapter is in French, reply in French; if in English, reply in English
- Do not start with phrases like "Summary of", "Ce chapitre", "This chapter covers", or any meta-commentary about summarizing; go straight to the content"""

USER_PROMPT = """\
Summarize the following chapter.

Chapter title: {title}

Chapter text:
{text}"""

MAX_TEXT_LENGTH = 100_000
_RATE_LIMIT_COOLDOWN = 60  # seconds to wait on 429 before retrying


def summarize_text(
    text: str,
    chapter_title: str,
    model: str = "mistral-small-latest",
    api_key: str | None = None,
) -> str:
    """Summarize a chapter's text using Mistral AI.

    Args:
        text: The chapter's full text content.
        chapter_title: Title of the chapter being summarized.
        model: Mistral model name (default: "mistral-small-latest").
        api_key: Mistral API key. Falls back to MISTRAL_API_KEY env var if None.

    Returns:
        Markdown summary string.
    """
    if len(text) > MAX_TEXT_LENGTH:
        print(
            f"Warning: Chapter '{chapter_title}' text exceeds {MAX_TEXT_LENGTH} "
            f"characters ({len(text)}). Truncating.",
            file=sys.stderr,
        )
        text = text[:MAX_TEXT_LENGTH]

    resolved_key = api_key or os.environ.get("MISTRAL_API_KEY")
    client = Mistral(api_key=resolved_key)

    messages = [
        {"role": "system", "content": SYSTEM_PROMPT},
        {
            "role": "user",
            "content": USER_PROMPT.format(title=chapter_title, text=text),
        },
    ]

    try:
        response = client.chat.complete(
            model=model, messages=messages, temperature=0.3,
        )
    except SDKError as exc:
        if "429" not in str(exc):
            raise
        print(
            f"Rate limited on '{chapter_title}'. "
            f"Waiting {_RATE_LIMIT_COOLDOWN}s before retrying...",
            file=sys.stderr,
        )
        time.sleep(_RATE_LIMIT_COOLDOWN)
        try:
            response = client.chat.complete(
                model=model, messages=messages, temperature=0.3,
            )
        except SDKError as retry_exc:
            if "429" not in str(retry_exc):
                raise
            raise RuntimeError(
                "Rate limited twice in a row — aborting."
            ) from retry_exc

    content = response.choices[0].message.content
    if content is None:
        raise ValueError(
            f"Mistral returned empty content for chapter '{chapter_title}'."
        )
    return content
