"""Prompt templates for criteria generation agents."""

SCENARIO_ANALYZER_PROMPT = """You are an expert at developing evaluation criteria and identifying what constitutes excellence in AI responses. \n\n**Role**: Scenario analyzer. \n\n**Input**: {question}. \n\n**Goal**: produce a minimal, non-redundant set of distinct scenarios that materially change evaluation criteria.\n\n **Method**: infer key context dimensions from the question; merge overlaps\n\n**Web Context**: If retrieved web context is provided (marked as [Retrieved Web Context]), reference the factual information within it to inform your analysis. However, do not limit yourself to only this content — also apply your own knowledge and reasoning.\n\n**Output**: a JSON array; each object has 'scenario_name' and a 3-5 sentence 'scenario_description', explaining why this context changes what 'good' means.The output looks like {{'scenarios': [\n{{'scenario_name': name_A, 'scenario_description': description_A}}, {{'scenario_name': name_B, 'scenario_description': description_B}},...]}}"""

SCENARIO_EXPANDER_PROMPT = """You are an expert at developing evaluation criteria and identifying what constitutes excellence in AI responses.\n\n**Role**: Scenario expander. \n\n**Input**: \n{question} \nCurrent Scenarios Analysis:\n {scenarios}. \n\n**Goal**: Ask 'what else' question. Generate NEW high-impact, non-overlapping scenarios that differ materially from existing ones. \n\n**Method**: Review existing scenarios; identify coverage gaps along context axes that would change evaluation criteria; propose scenarios that differ along multiple axes. The scenarios should be as specific as possible. \n\n**Web Context**: If retrieved web context is provided (marked as [Retrieved Web Context]), reference the factual information within it to inform your analysis. However, do not limit yourself to only this content — also apply your own knowledge and reasoning.\n\n**Output**: a JSON array containing ONLY NEW scenarios (do not include existing scenarios). Each element is an object with:\n- 'scenario_name': A short, descriptive name for this scenario type\n- 'scenario_description': A 3-5 sentence description explaining what is unique about this scenario and the specific axes/settings it assumes. The output looks like {{'scenarios': [\n{{'scenario_name': name_A, 'scenario_description': description_A}}, {{'scenario_name': name_B, 'scenario_description': description_B}},...]}}"""

PERSPECTIVE_ANALYZER_PROMPT = """You are an expert at developing evaluation criteria and identifying what constitutes excellence in AI responses. \n\n**Role**: Evaluation perspective designer.\n\n**Input**: \n{question} \n\nScenario Analysis:\n {scenario_analysis}. \n\n**Goal**: Produce 4-7 scenario-specific, non-overlapping evaluation perspectives that capture what truly matters for this question.\n\n**Method**: Use the scenario analysis to surface key quality dimensions; propose maximally diverse major themes (including unconventional angles); for each theme, specify 3-5 sub-aspects; keep themes high-level enough to spawn multiple criteria yet narrow enough to avoid overlap; tie all points to this scenario.\n\n**Web Context**: If retrieved web context is provided (marked as [Retrieved Web Context]), reference the factual information within it to inform your analysis. However, do not limit yourself to only this content — also apply your own knowledge and reasoning.\n\n**Output**: a JSON array where each element is an object with:\n- 'perspective_name': A short, descriptive name for this evaluation perspective (2-5 words)\n- 'perspective_description': A 3-5 sentence description that explains what this perspective evaluates, lists the specific sub-aspects it covers. The output looks like {{'perspectives': [\n{{'perspective_name': name_A, 'perspective_description': description_A}}, {{'perspective_name': name_B, 'perspective_description': description_B}},...]}}"""

PERSPECTIVE_EXPANDER_PROMPT = """You are an expert at developing evaluation criteria and identifying what constitutes excellence in AI responses. \n\n**Role**: Perspective expander.\n\n**Input**: \n{question} \n\nCurrent Perspectives: {perspectives}.\n\n**Goal**: Ask 'what else' question. Generate ONLY new high-impact, non-overlapping perspectives that provide materially different evaluation angles from existing ones.\n\n**Method**: Review existing perspectives; map coverage across various quality dimensions; identify gaps; propose only new perspectives that would yield different criteria. The perspectives should be as scenario-specific as possible.\n\n**Web Context**: If retrieved web context is provided (marked as [Retrieved Web Context]), reference the factual information within it to inform your analysis. However, do not limit yourself to only this content — also apply your own knowledge and reasoning.\n\n**Output**: JSON array containing ONLY NEW perspectives (do not include existing perspectives). Each object has:\n- 'perspective_name': A short name (2-5 words)\n- 'perspective_description': A 3-5 sentence description listing 3-5 sub-aspects and explaining what makes this perspective unique. The output looks like {{'perspectives': [\n{{'perspective_name': name_A, 'perspective_description': description_A}}, {{'perspective_name': name_B, 'perspective_description': description_B}},...]}}"""

PERSPECTIVE_REVIEWER_PROMPT = """You are an expert at developing evaluation criteria and identifying what constitutes excellence in AI responses. \n\n**Role**: Perspective reviewer and consolidator.\n\n**Input**: \n {question}\n\nall perspectives under different scenarios: \n{all_perspectives}\n\n**Goal**: Review, deduplicate, and consolidate perspectives.\n\n**Rules**:\n- If perspectives aim for same evaluation angle but under different scenario, combine comprehensive scenario detailed information into the reviewed perspective description and keep them as separate perspectives.\n- Remove perspectives that are off-topic, redundant with others, or too vague to guide criteria.\n- Each kept perspective must contribute unique value for this scenario.\n- Make sure the final perspectives are as scenario-specific as possible.\n\n**Web Context**: If retrieved web context is provided (marked as [Retrieved Web Context]), reference the factual information within it to inform your analysis. However, do not limit yourself to only this content — also apply your own knowledge and reasoning.\n\n**Output**: Return a JSON array containing ONLY the perspectives to keep (after review and consolidation). Each item has:\n- 'perspective_name': name of the perspective (refined if needed)\n- 'perspective_description': description of the perspective (refined if needed). The output looks like {{'perspectives': [\n{{'perspective_name': name_A, 'perspective_description': description_A}}, {{'perspective_name': name_B, 'perspective_description': description_B}},...]}}"""

CRITERIA_GENERATOR_PROMPT = """You are an expert at developing evaluation criteria and identifying what constitutes excellence in AI responses. \n\n**Role**: evaluation criteria designer.\n**Input**: {question}\n\n; focus perspective {perspective_description}.\n\n**Goal**: Generate only scenario- and perspective-specific evaluation criteria.\n**Rules**:\n1) **Binary**: Each criterion must be answerable YES/NO.\n2) **Scenario-specific**: Explicitly reference features of THIS scenario and perspective. Make is as detailed as possible.\n3) **Balanced**: Include positive criteria (required content) and negative criteria (harmful content). Add negative criteria only when the issue represents harmful, misleading, or critically wrong behavior that could significantly reduce answer quality or safety. Do not include minor or stylistic negatives.\n4) **Form**: [Verb + Specific Requirements]; start with one clear action verb, then the exact required/forbidden content with qualifiers; each criterion is self-contained.\n5) **Diversity**: Cover all sub-aspects of the perspective. \n6) **Negative criteria requirements**: Only include if the behavior is harmful, dangerous, or a major factual or ethical error. Must directly describe the wrong action — e.g., 'Provides false or misleading information,' or 'Omits a critical safety warning.' If X is a bad behavior, do not use phrasing like 'Avoid doing X'; instead, state the actual bad behavior ('Does X').\n**Scoring**: Positive = 1-10 (10 critical safety/core; 8-9 important completeness; 5-7 quality enhancers; 1-4 minor). Negative = -1 to -10 (-10 dangerous; -8 to-9 major omission; -5 to -7 quality issue; -1 to -4 minor).\n**Web Context**: If retrieved web context is provided (marked as [Retrieved Web Context]), reference the factual information within it to inform your criteria. However, do not limit yourself to only this content — also apply your own knowledge and reasoning.\n**Output**: JSON array; each element has 'criterion', 'points' (integer), and 'reasoning' (2-3 sentences on why it matters for THIS scenario and why the weight). The output looks like {{'criteria': [\n{{'criterion': criterion_A, 'points': points_A, 'reasoning': reasoning_A}}, {{'criterion': criterion_B, 'points': points_B, 'reasoning': reasoning_B}},...]}}"""

CRITERIA_EXPANDER_PROMPT = """You are an expert at developing evaluation criteria and identifying what constitutes excellence in AI responses. \n\n**Role**: Criteria expander.\n\n**Input**: \n{question}\n\nExisting criteria: {all_criteria}.\n\n**Goal**: Ask 'what else' question. Generate ONLY new high-impact, scenario-specific binary criteria that are not covered by existing ones.\n\n**Rules**: \n- Write each as [Verb + specific requirement]\n- Add only non-overlapping items that could change pass/fail\n- Think: if answering this question, what concrete content would make the response excellent?\n- The criteria should be as scenario-specific as possible.\n- Add negative criteria only when the issue represents harmful, misleading, or critically wrong behavior that could significantly reduce answer quality or safety. \n- **Scoring**: Positive 1-10 (10 critical, 8-9 important, 5-7 quality, 1-4 minor); Negative -1 to -10 (-10 dangerous, -8 to -9 major omission, -5 to -7 quality issue, -1 to -4 minor).\n\n**Web Context**: If retrieved web context is provided (marked as [Retrieved Web Context]), reference the factual information within it to inform your criteria. However, do not limit yourself to only this content — also apply your own knowledge and reasoning.\n\n**Output**: JSON array containing ONLY NEW criteria (exclude existing criteria). Each element has:\n- 'criterion': the criterion text\n- 'points': integer score\n- 'reasoning': 2-3 sentences tied to THIS scenario and weight. The output looks like {{'criteria': [\n{{'criterion': criterion_A, 'points': points_A, 'reasoning': reasoning_A}}, {{'criterion': criterion_B, 'points': points_B, 'reasoning': reasoning_B}},...]}}"""

CRITERIA_REVIEWER_PROMPT = """You are an expert at developing evaluation criteria and identifying what constitutes excellence in AI responses. **Role**: Final rubric consolidator.\n**Input**: {question}\n\n; all criteria {all_criteria}.\n \nIf one or more image are provided, focus on the image content as well.\n\n**Goal**: Produce a concise, non-redundant, scenario-specific final rubric.\n**Rules**:\n- **Deduplicate & merge**: Combine criteria that assess the same aspect; keep the most precise wording and include all distinct details. Treat positives as required content and negatives as harmful content or key omissions; if a positive and a negative cover the same aspect, keep only the positive.\n- **Neutralize fixed facts**: Replace hard-coded numbers/dates/versions/limits/placeholders with requirements that the response states the current/official/latest value/standard.\n- **Balance & diversity**: Keep both positive and negative criteria, ensure total positive points outweigh negatives, and retain all distinct (non-overlapping) items.\n**Web Context**: If retrieved web context is provided (marked as [Retrieved Web Context]), reference the factual information within it to inform your consolidation. However, do not limit yourself to only this content — also apply your own knowledge and reasoning.\n**Output**: JSON array; each element has 'criterion', 'points' (integer), and 'reasoning' (why retained and why weighted). The output looks like {{'criteria': [\n{{'criterion': criterion_A, 'points': points_A, 'reasoning': reasoning_A}}, {{'criterion': criterion_B, 'points': points_B, 'reasoning': reasoning_B}},...]}}"""

POLARITY_CHECKER_PROMPT = """You are an expert at developing evaluation criteria and identifying what constitutes excellence in AI responses. \n\n**Role**: Criterion polarity classifier.\n**Input**: {question} \n\n; all criteria {all_criteria}.\n\n**Goal**: Determine whether each criterion represents a positive (good behavior / desirable response) or negative (bad behavior / harmful response) evaluation aspect.\n\n**Rules**:\n- A positive criterion describes correct, effective, or desirable behavior — meeting it improves response quality.\n- A negative criterion describes wrong, harmful, missing, or undesirable behavior — meeting it reduces response quality.\n If X is a bad behavior, phrasing like 'Avoid doing X' is considered as positive, since meeting it improves response quality. Instead, state the actual bad behavior ('Does X') is negative. \n-  Do not modify or repeat any criterion text.\n- The output order and length must exactly match the input criteria.\n\n**Output**:\nReturn a JSON array where each element corresponds to one input criterion (in the same order). The output looks like: {{'criteria': [{{'positive': true/false, 'reasoning': 'brief explanation of why it's classified as positive or negative'}},  …]}}"""

SCORE_ASSIGNER_PROMPT = """You are an expert at developing evaluation criteria and identifying what constitutes excellence in AI responses. \n\n**Role**: Score reasonableness and importance checker.\nInput: {question}\n\n; all criteria {all_criteria}.\nIf one or more image are provided, focus on the image content as well.\n\nGoal: Verify that each criterion's score correctly reflects its importance, ensuring that score magnitude (absolute value) strictly matches importance level.\n\nScoring standard:\n- Positive (1-10): 10 = critical; 8-9 = important; 5-7 = quality; 1-4 = minor.\n- Negative (-1 to -10): -10 = dangerous/harmful; -8 to -9 = major omission; -5 to -7 = quality issue; -1 to -4 = minor.\n\nRules:\n- Do not change or rewrite any criterion text.\n- Only review and adjust scores so their absolute value aligns with importance.\n- A more important or severe issue must always have a higher absolute score.\n**Important**: - Keep direction (positive/negative) the same, do not change the positive/negative polarity of the criterion — only adjust magnitude if needed.\n\nOutput:\nReturn a JSON array where each item has:\n- 'criterion': same text as input.\n- 'points': reviewed or corrected score based on importance.\n- 'reasoning': short note on why the score was kept or adjusted.\n The output looks like {{'criteria': [\n{{'criterion': criterion_A, 'points': adjusted_points_A, 'reasoning': reasoning_A}}, {{'criterion': criterion_B, 'points': adjusted_points_B, 'reasoning': reasoning_B}},...]}}"""

CRITERIA_ALIGNMENT_JUDGER_PROMPT = """You are a rubric alignment auditor. You will be given the original scenario, model-created criteria under several contexts, expert-created criteria, you need to compare expert criteria and model criteria to determine coverage.\n\nOriginal Scenario: {question}\n\nExpert Criteria (array):\n{expert_criteria}\n\nModel Criteria Under different perspectives:\n{model_criteria}\n\n**Objectives:**For each expert criterion, decide if it is covered by at least one model criterion.\n\n**Coverage Rules (core):**\n- Coverage = approximate semantic equivalence of the main intent/dimension. If a reasonable grader would make the same pass/fail decision on the same response, treat as covered. \n- Minor differences in wording, scope, qualifiers, or verb choice are acceptable if the core intent is preserved.\n- Ignore concrete numbers/dates/versions/limits: since model criteria maynot include exact factual value, treat 'current/official/latest requirement/standard' as equivalent semantics. \n- If an expert criterion is general while a model criterion expresses the same intent with scenario/question-specific details, treat it as covered.\n- Positive/negative inversion: Consider the conversion between positive and negative criteria. For instance, if an expert negative says fails to provide/avoid X, and a model positive requires provides/avoids X, treat as covered (same aspect).\n - Judgments must be binary (yes/no) with concise reasons.\n\n**Procedure:**\nFor every expert criterion, scan all model criteria and model perspective analysis. If any criteria or perspecitve contains approximate semantic equivalence (Minor differences in wording, detail/general can be ignored) → is covered = yes; else no. Give a 1-3 sentence reason citing key matches or missing elements.\n\n\n\n**OUTPUT FORMAT (strict):**\nReturn a single JSON object with array:\n- expert_criteria: each item has 'criterion' (original expert text), 'is_covered' ('yes' | 'no'), 'comment' (1-3 sentences).\n\n**IMPORTANT:**\n- Do not rewrite, merge, or invent any criterion text.\n- Output only the specified JSON structure—no extra commentary, examples, or tables. \n- You should strictly check the amount of input expert criteria is equal to output expert criteria\n"""

MODEL_UNIQUE_CRITERIA_JUDGER_PROMPT = """You are a rubric gap auditor. You will be given a scenario, expert criteria, and model criteria. Your task is to find which model criteria are not covered by expert criteria and judge if they are meaningful.\n\nOriginal Scenario: {question}\n\nExpert Criteria:\n{expert_criteria}\n\nModel Criteria:\n{model_criteria}\n\nGoals: For each model criterion, decide:\n1. Is it covered by any expert criterion? (semantic equivalence of intent)\n2. If not, is it valuable (useful, distinct, relevant)?\n\nCoverage Rules:\n- Covered = same intent or judgment as an expert criterion.\n- Minor differences in detail/wording are fine.\n- General vs specific, or positive vs negative phrasing → still covered.\n\nValuability Rules:\n- Valuable = distinct, relevant, and assessable.\n- Not valuable = vague, redundant, off-topic, or tautological.\n\nOutput Format:\nReturn only this JSON:\n{{'model_criteria': [{{'criterion': , 'is_covered': 'yes' | 'no', 'is_valuable': 'yes' | 'no', 'reason': <1-2 sentence explanation>}}, …]}}\n\nNotes:\n- Keep the exact same number of model criteria in output.\n- No extra commentary or formatting beyond the JSON."""

AGENT_PROMPTS = {
    "ScenarioAnalyzer": SCENARIO_ANALYZER_PROMPT,
    "ScenarioExpander": SCENARIO_EXPANDER_PROMPT,
    "PerspectiveAnalyzer": PERSPECTIVE_ANALYZER_PROMPT,
    "PerspectiveExpander": PERSPECTIVE_EXPANDER_PROMPT,
    "PerspectiveReviewer": PERSPECTIVE_REVIEWER_PROMPT,
    "CriteriaGenerator": CRITERIA_GENERATOR_PROMPT,
    "CriteriaExpander": CRITERIA_EXPANDER_PROMPT,
    "CriteriaReviewer": CRITERIA_REVIEWER_PROMPT,
    "NegativeCriteriaChecker": POLARITY_CHECKER_PROMPT,
    "CriteriaScoreAssigner": SCORE_ASSIGNER_PROMPT,
    "CriteriaAlignmentJudger": CRITERIA_ALIGNMENT_JUDGER_PROMPT,
    "ModelUniqueCriteriaJudger": MODEL_UNIQUE_CRITERIA_JUDGER_PROMPT,
}


def get_prompt(agent_name: str, **kwargs) -> str:
    """Get formatted prompt for an agent."""
    template = AGENT_PROMPTS.get(agent_name)
    if not template:
        raise ValueError(f"Unknown agent: {agent_name}")
    return template.format(**kwargs)
