"""
Unit tests for shared.prompts.system_prompt_builder.

Tests verify:
- Full prompt with all fields produces expected sections
- Minimal prompt (name + role only) still includes AI transparency clause
- Empty tools and escalation_rules omit those sections
- AI transparency clause is always present regardless of inputs
"""

from __future__ import annotations

import pytest

from shared.prompts.system_prompt_builder import build_system_prompt

AI_TRANSPARENCY_CLAUSE = "When directly asked if you are an AI, always disclose that you are an AI assistant."


class TestBuildSystemPromptFull:
    """Test build_system_prompt with all fields populated."""

    def test_contains_name(self) -> None:
        prompt = build_system_prompt(
            name="Mara",
            role="Customer Support",
            persona="Friendly and helpful",
            tool_assignments=["knowledge_base_search"],
            escalation_rules=[{"condition": "billing_dispute AND attempts > 2", "action": "handoff_human"}],
        )
        assert "You are Mara" in prompt

    def test_contains_role(self) -> None:
        prompt = build_system_prompt(
            name="Mara",
            role="Customer Support",
            persona="Friendly and helpful",
            tool_assignments=["knowledge_base_search"],
            escalation_rules=[{"condition": "billing_dispute AND attempts > 2", "action": "handoff_human"}],
        )
        assert "Customer Support" in prompt

    def test_contains_persona(self) -> None:
        prompt = build_system_prompt(
            name="Mara",
            role="Customer Support",
            persona="Friendly and helpful",
            tool_assignments=["knowledge_base_search"],
            escalation_rules=[{"condition": "billing_dispute AND attempts > 2", "action": "handoff_human"}],
        )
        assert "Friendly and helpful" in prompt

    def test_contains_tool(self) -> None:
        prompt = build_system_prompt(
            name="Mara",
            role="Customer Support",
            persona="Friendly and helpful",
            tool_assignments=["knowledge_base_search"],
            escalation_rules=[{"condition": "billing_dispute AND attempts > 2", "action": "handoff_human"}],
        )
        assert "knowledge_base_search" in prompt

    def test_contains_escalation_rule(self) -> None:
        prompt = build_system_prompt(
            name="Mara",
            role="Customer Support",
            persona="Friendly and helpful",
            tool_assignments=["knowledge_base_search"],
            escalation_rules=[{"condition": "billing_dispute AND attempts > 2", "action": "handoff_human"}],
        )
        assert "billing_dispute AND attempts > 2" in prompt

    def test_contains_ai_transparency_clause(self) -> None:
        prompt = build_system_prompt(
            name="Mara",
            role="Customer Support",
            persona="Friendly and helpful",
            tool_assignments=["knowledge_base_search"],
            escalation_rules=[{"condition": "billing_dispute AND attempts > 2", "action": "handoff_human"}],
        )
        assert AI_TRANSPARENCY_CLAUSE in prompt


class TestBuildSystemPromptMinimal:
    """Test build_system_prompt with only name and role provided."""

    def test_minimal_contains_name(self) -> None:
        prompt = build_system_prompt(name="Alex", role="Sales Assistant")
        assert "You are Alex" in prompt

    def test_minimal_contains_role(self) -> None:
        prompt = build_system_prompt(name="Alex", role="Sales Assistant")
        assert "Sales Assistant" in prompt

    def test_minimal_contains_ai_transparency_clause(self) -> None:
        prompt = build_system_prompt(name="Alex", role="Sales Assistant")
        assert AI_TRANSPARENCY_CLAUSE in prompt

    def test_minimal_is_string(self) -> None:
        prompt = build_system_prompt(name="Alex", role="Sales Assistant")
        assert isinstance(prompt, str)
        assert len(prompt) > 0


class TestBuildSystemPromptEmptySections:
    """Test that empty tools and escalation_rules omit those sections."""

    def test_empty_tools_omits_tools_section(self) -> None:
        prompt = build_system_prompt(
            name="Bob",
            role="Office Manager",
            persona="Organized and efficient",
            tool_assignments=[],
            escalation_rules=[],
        )
        # Should not contain a tools header/section
        assert "tools:" not in prompt.lower() or "tools" not in prompt.split("\n")[0]

    def test_empty_escalation_omits_escalation_section(self) -> None:
        prompt = build_system_prompt(
            name="Bob",
            role="Office Manager",
            persona="Organized and efficient",
            tool_assignments=[],
            escalation_rules=[],
        )
        # Should not contain an escalation section
        assert "Escalation" not in prompt

    def test_none_tools_omits_tools_section(self) -> None:
        prompt = build_system_prompt(
            name="Bob",
            role="Office Manager",
            tool_assignments=None,
            escalation_rules=None,
        )
        assert "Escalation" not in prompt

    def test_empty_still_has_ai_transparency(self) -> None:
        prompt = build_system_prompt(
            name="Bob",
            role="Office Manager",
            tool_assignments=[],
            escalation_rules=[],
        )
        assert AI_TRANSPARENCY_CLAUSE in prompt


class TestBuildSystemPromptAIClauseAlwaysPresent:
    """AI transparency clause must always be present — non-negotiable."""

    def test_ai_clause_present_full_args(self) -> None:
        prompt = build_system_prompt(
            name="Mara",
            role="Support",
            persona="Helpful",
            tool_assignments=["kb_search"],
            escalation_rules=[{"condition": "x", "action": "handoff_human"}],
        )
        assert AI_TRANSPARENCY_CLAUSE in prompt

    def test_ai_clause_present_name_role_only(self) -> None:
        prompt = build_system_prompt(name="Z", role="Y")
        assert AI_TRANSPARENCY_CLAUSE in prompt

    def test_ai_clause_present_with_persona_only(self) -> None:
        prompt = build_system_prompt(name="Sam", role="Analyst", persona="Detail-oriented")
        assert AI_TRANSPARENCY_CLAUSE in prompt


class TestLanguageInstruction:
    """LANGUAGE_INSTRUCTION must be present in all system prompts before AI transparency clause."""

    LANGUAGE_INSTRUCTION = (
        "Detect the language of each user message and respond in that same language. "
        "You support English, Spanish, and Portuguese."
    )

    def test_language_instruction_present_in_default_prompt(self) -> None:
        """build_system_prompt with name+role includes LANGUAGE_INSTRUCTION."""
        prompt = build_system_prompt(name="Mara", role="Support Rep")
        assert self.LANGUAGE_INSTRUCTION in prompt

    def test_language_instruction_present_with_full_args(self) -> None:
        """build_system_prompt with all args includes LANGUAGE_INSTRUCTION."""
        prompt = build_system_prompt(
            name="Mara",
            role="Support Rep",
            persona="Helpful and professional",
            tool_assignments=["knowledge_base_search"],
            escalation_rules=[{"condition": "billing_dispute", "action": "handoff_human"}],
        )
        assert self.LANGUAGE_INSTRUCTION in prompt

    def test_language_instruction_before_transparency_clause(self) -> None:
        """LANGUAGE_INSTRUCTION appears before AI_TRANSPARENCY_CLAUSE in the prompt."""
        prompt = build_system_prompt(
            name="Mara",
            role="Support Rep",
            persona="Helpful",
            tool_assignments=["kb_search"],
            escalation_rules=[{"condition": "x", "action": "handoff_human"}],
        )
        lang_pos = prompt.index(self.LANGUAGE_INSTRUCTION)
        transparency_pos = prompt.index(AI_TRANSPARENCY_CLAUSE)
        assert lang_pos < transparency_pos, (
            "LANGUAGE_INSTRUCTION must appear before AI_TRANSPARENCY_CLAUSE"
        )
