"""Prompt templates for LLM judges."""

from dataclasses import dataclass
from typing import List
import hashlib

@dataclass
class PromptTemplate:
    """
    Template for judge prompts.
    
    Supports variable substitution and versioning for reproducibility.
    
    Examples:
        >>> template = PromptTemplate(
        ...     template="Rate this: {output}",
        ...     variables=["output"],
        ...     version="1.0"
        ... )
        >>> prompt = template.render(output="Great work!")
        'Rate this: Great work!'
    """
    template: str
    variables: List[str]
    version: str = "1.0"

    def render(self, **kwargs) -> str:
        """
        Render template with variables

        Args:
            **kwargs: Variable values

        Returns:
            Rendered prompt string
        
        Raises:
            KeyError: If required variable is missing
        """

        # Check all required variables provided
        missing = set(self.variables) - set(kwargs.keys())

        if missing:
            raise KeyError(f"Missing required variables: {missing}")
        
        return self.template.format(**kwargs)
    
    def hash(self) ->str:
        """
        Generate stable hash for caching/reproducibility.

        Returns:
            SHA256 hash of template + version
        """

        content = f"{self.template}|{self.version}"
        return hashlib.sha256(content.encode()).hexdigest()[:16]
        


# Default prompt template for LLM judges
DEFAULT_JUDGE_TEMPLATE = PromptTemplate(
    template="""You are an expert evaluator. Assess the following output based on the given criteria.

INPUT: {input}
OUTPUT: {output}
REFERENCE: {reference}

{rubric}

Provide your assessment in the following JSON format:
{{
  "criteria_scores": {{"criterion_1": score, "criterion_2": score, ...}},
  "criteria_explanations": {{"criterion_1": "explanation", "criterion_2": "explanation", ...}},
  "criteria_confidences": {{"criterion_1": confidence, "criterion_2": confidence, ...}},
  "explanation": "overall summary of the evaluation"
}}

IMPORTANT NOTES:
1. Provide scores for EACH criterion based on the scale specified
2. Provide brief explanations for EACH criterion (1-2 sentences)
3. Provide confidence for EACH criterion (0-1 scale, where 1 is completely confident)
4. Do NOT compute an overall score - only provide per-criterion scores
5. Your explanation should be a brief summary, not a repeat of criterion explanations
6. Return ONLY valid JSON, no markdown formatting or code blocks
""",
    variables=["input", "output", "reference", "rubric"],
    version="1.0"
)


# Template with few-shot examples
FEWSHOT_JUDGE_TEMPLATE = PromptTemplate(
    template="""You are an expert evaluator. Assess the following output based on the given criteria.

{rubric}

EXAMPLES:
{examples}

NOW EVALUATE:
INPUT: {input}
OUTPUT: {output}
REFERENCE: {reference}

Provide your assessment in the following JSON format:
{{
  "criteria_scores": {{"criterion_1": score, "criterion_2": score, ...}},
  "criteria_explanations": {{"criterion_1": "explanation", "criterion_2": "explanation", ...}},
  "criteria_confidences": {{"criterion_1": confidence, "criterion_2": confidence, ...}},
  "explanation": "overall summary"
}}

Return ONLY valid JSON, no markdown or code blocks.
""",
    variables=["input", "output", "reference", "rubric", "examples"],
    version="1.0"
)