"""
Dynamic Prompt Builder — generated by aiwg nlp new
Pattern: dynamic-prompt
Dependencies: anthropic, jinja2

Install: pip install anthropic jinja2
"""

from __future__ import annotations

import json
import time
from pathlib import Path
from typing import Any

import anthropic
from jinja2 import Environment, FileSystemLoader, select_autoescape

TEMPLATES_DIR = Path(__file__).parent.parent / "prompts"
MODEL = "claude-haiku-4-5"
MAX_TOKENS = 1024
TIMEOUT_SECONDS = 30
MAX_RETRIES = 3
BACKOFF_SECONDS = 1.0

# ---------------------------------------------------------------------------
# Jinja2 environment
# ---------------------------------------------------------------------------

_jinja_env = Environment(
    loader=FileSystemLoader(str(TEMPLATES_DIR)),
    autoescape=select_autoescape([]),
    trim_blocks=True,
    lstrip_blocks=True,
)


def build_prompt(template_name: str, variables: dict[str, Any]) -> tuple[str, str]:
    """Render the Jinja2 prompt template and return (system, user) sections."""
    template = _jinja_env.get_template(template_name)
    rendered = template.render(**variables)

    system, user, section = "", "", None
    for line in rendered.splitlines():
        if line.strip() == "## System":
            section = "system"
        elif line.strip() == "## User":
            section = "user"
        elif section == "system":
            system += line + "\n"
        elif section == "user":
            user += line + "\n"

    return system.strip(), user.strip()


# ---------------------------------------------------------------------------
# LLM call
# ---------------------------------------------------------------------------

def call_llm(client: anthropic.Anthropic, system: str, user: str) -> str:
    last_error = None
    for attempt in range(MAX_RETRIES):
        try:
            response = client.messages.create(
                model=MODEL,
                max_tokens=MAX_TOKENS,
                system=system,
                messages=[{"role": "user", "content": user}],
                timeout=TIMEOUT_SECONDS,
            )
            return response.content[0].text
        except (anthropic.RateLimitError, anthropic.APIStatusError) as e:
            last_error = e
            time.sleep(BACKOFF_SECONDS * (2 ** attempt))
    raise RuntimeError(f"LLM call failed after {MAX_RETRIES} attempts") from last_error


# ---------------------------------------------------------------------------
# Pipeline
# ---------------------------------------------------------------------------

def run(user_input: str, prompt_config: dict[str, Any] | None = None) -> str:
    """Render and run the dynamic prompt pipeline.

    Args:
        user_input: The user's input text.
        prompt_config: Optional dict of Jinja2 template variables to override defaults.
                      Supported keys: role, persona, output_format, constraints,
                      few_shot_examples, context.

    Returns:
        Generated text output.
    """
    config = prompt_config or {}
    variables = {
        "user_input": user_input,
        "role": config.get("role", "helpful assistant"),
        "persona": config.get("persona"),
        "output_format": config.get("output_format", "Plain text response"),
        "constraints": config.get("constraints", []),
        "few_shot_examples": config.get("few_shot_examples", []),
        "context": config.get("context"),
    }

    system, user = build_prompt("template.prompt.md.j2", variables)
    client = anthropic.Anthropic()
    return call_llm(client, system, user)


if __name__ == "__main__":
    import sys
    config_file = sys.argv[2] if len(sys.argv) > 2 else None
    config = json.loads(Path(config_file).read_text()) if config_file else {}
    if len(sys.argv) < 2:
        print("Usage: python prompt_builder.py '<input>' [config.json]")
        sys.exit(1)
    print(run(sys.argv[1], config))
