"""AI-based frame selection using Anthropic Claude Vision."""

import json

DEFAULT_CLAUDE_MODEL = "claude-opus-4-5"
MAX_DESCRIPTION_LENGTH = 1000

from .ai_utils import encode_image_base64, call_claude_vision_with_retry


def select_frame_with_ai(
    mosaic_path: str,
    api_key: str,
    model: str = DEFAULT_CLAUDE_MODEL,
    description: str | None = None,
) -> tuple[int, str]:
    """
    Ask Claude Vision to select the best frame from a mosaic image.

    Parameters
    ----------
    mosaic_path:
        Path to the mosaic JPEG image.
    api_key:
        Anthropic API key.
    model:
        Claude model name.
    description:
        Optional description of the video content for context (max 1000 chars).

    Returns
    -------
    (frame_index, reasoning)
        ``frame_index`` is an integer 0–19.
        ``reasoning`` is the AI explanation.

    Raises
    ------
    RuntimeError
        If the AI call fails after all retries or returns an invalid response.
    """
    try:
        import anthropic
    except ImportError:
        raise RuntimeError(
            "The 'anthropic' package is required for AI selection. "
            "Install it with: pip install anthropic"
        )

    if description:
        description = description[:MAX_DESCRIPTION_LENGTH]

    image_data = encode_image_base64(mosaic_path)

    context_block = ""
    if description:
        context_block = (
            f"\n\nVideo description provided by the user:\n{description}"
        )

    prompt = (
        "You are shown a mosaic of 20 video frames arranged in a 4-column × 5-row grid. "
        "Each frame is labelled 'BILD 0' through 'BILD 19' (top-left to bottom-right). "
        "Select the single best frame to use as a video thumbnail poster image.\n\n"
        "MAIN CHARACTER RULE (highest priority): Scan all 20 frames and check whether "
        "one person appears repeatedly across many frames — this recurring person is the "
        "main presenter or host. If such a main character exists, you MUST prefer a frame "
        "that prominently features that person with a positive, engaging facial expression "
        "(e.g. smiling, confident, looking toward the camera). Do NOT choose a frame that "
        "shows only objects, graphics, slides, or secondary subjects when a frame with the "
        "main character is available.\n\n"
        "SECONDARY CRITERIA (apply only when the main-character rule does not decide): "
        "prefer frames that are sharp, well-lit, and visually interesting; "
        "avoid frames with motion blur, closed eyes, or transitional content."
        f"{context_block}\n\n"
        "Respond ONLY with a valid JSON object on a single line, with no additional text:\n"
        '{"image_number": <integer 0-19>, "reasoning": "<brief explanation including whether a main character was identified and how the main-character rule was applied>"}'
    )

    client = anthropic.Anthropic(api_key=api_key)

    def _parse(raw: str) -> tuple[int, str]:
        data = json.loads(raw)
        frame_index = int(data["image_number"])
        reasoning = str(data["reasoning"])
        if not (0 <= frame_index <= 19):
            raise ValueError(f"frame_index {frame_index} is out of range 0–19.")
        return frame_index, reasoning

    return call_claude_vision_with_retry(client, model, image_data, prompt, _parse, "AI frame selection")
