"""
reflect — structured multi-perspective thinking tool.

Runs three parallel AIHelper calls with distinct advisor roles
(Critic, Pragmatist, Detailer) and returns their independent perspectives.
Use before planning a complex task or when stuck on a problem.

Designed to force explicit articulation of assumptions — the most common
source of planning errors — and get fresh perspectives unclouded by
accumulated conversation context.
"""

import asyncio

from navi.tools.base import Tool, ToolResult

# ── Advisor system prompts ─────────────────────────────────────────────────

_CRITIC_SYSTEM = """\
You are a critical advisor. Your role is to challenge the situation description and expose weaknesses.

Focus on:
- Which stated assumptions are likely wrong or unverified?
- What risks and failure modes are being ignored?
- What logical gaps or contradictions exist in the approach?
- What is being taken for granted that should be questioned?

Be direct and specific. Do not be encouraging. Name concrete problems, not abstract concerns.
Keep your response concise — 3 to 6 sharp points."""

_PRAGMATIST_SYSTEM = """\
You are a pragmatic advisor. Your role is to find the simplest, most direct path to the goal.

Focus on:
- What is the minimal viable approach that actually solves the problem?
- What complexity can be eliminated without losing the core outcome?
- What alternatives or shortcuts have not been considered?
- Is the stated goal actually the real goal, or is there a simpler reframing?

Challenge over-engineering. Propose concrete simplifications.
Keep your response concise — 3 to 6 actionable points."""

_DETAILER_SYSTEM = """\
You are a detail-oriented advisor. Your role is to find what is missing, ambiguous, or underspecified.

Focus on:
- What edge cases or failure scenarios have not been addressed?
- What requirements or constraints are implied but not stated?
- What implementation details will become blockers later if not resolved now?
- What information is missing before a good decision can be made?

Be specific about what is absent, not just that something might be missing.
Keep your response concise — 3 to 6 concrete gaps."""

# ── Prompt builder ─────────────────────────────────────────────────────────

def _build_user_prompt(situation: str, assumptions: list[str], tried: str | None) -> str:
    parts = [f"## Situation\n{situation.strip()}"]

    if assumptions:
        bullet_assumptions = "\n".join(f"- {a.strip()}" for a in assumptions if a.strip())
        parts.append(f"## Assumptions being made\n{bullet_assumptions}")
    else:
        parts.append("## Assumptions being made\n(none stated)")

    if tried and tried.strip():
        parts.append(f"## Already attempted\n{tried.strip()}")

    return "\n\n".join(parts)


# ── Tool ───────────────────────────────────────────────────────────────────

class ReflectTool(Tool):
    name = "reflect"
    description = (
        "Get three independent expert perspectives on a situation before planning or when stuck.\n\n"
        "Call this when:\n"
        "- About to plan a complex or ambiguous task\n"
        "- Stuck on a problem and need a fresh angle\n"
        "- Unsure whether your approach is right\n\n"
        "Three advisors analyse your situation in parallel:\n"
        "· Critic — challenges assumptions, surfaces risks and flaws\n"
        "· Pragmatist — finds the simplest path, cuts unnecessary complexity\n"
        "· Detailer — spots missing requirements, edge cases, and gaps\n\n"
        "IMPORTANT: The `assumptions` field is mandatory and is the most valuable input. "
        "List every belief you are acting on without having verified it. "
        "The act of listing assumptions often reveals the problem itself."
    )
    parameters = {
        "type": "object",
        "properties": {
            "situation": {
                "type": "string",
                "description": (
                    "Describe the goal and the current situation clearly. "
                    "Include: what you are trying to achieve, the approach you are considering, "
                    "and what specifically you are unsure about."
                ),
            },
            "assumptions": {
                "type": "array",
                "items": {"type": "string"},
                "description": (
                    "List every assumption you are making — things you believe are true "
                    "but have not verified. Be honest and thorough. "
                    "Example: 'the API returns data in this format', "
                    "'the user wants X not Y', 'this file will always exist'."
                ),
            },
            "tried": {
                "type": "string",
                "description": (
                    "Optional. What you have already attempted and why it did not work. "
                    "Provide this when you are stuck, not when planning from scratch."
                ),
            },
        },
        "required": ["situation", "assumptions"],
    }

    def __init__(self, ai_helper) -> None:
        self._ai = ai_helper

    async def execute(self, params: dict) -> ToolResult:
        situation  = (params.get("situation") or "").strip()
        assumptions = params.get("assumptions") or []
        tried      = (params.get("tried") or "").strip() or None

        if not situation:
            return ToolResult(success=False, output="", error="situation is required")

        user_prompt = _build_user_prompt(situation, assumptions, tried)

        # Run all three advisors in parallel
        critic_task     = self._ai.ask(_CRITIC_SYSTEM,     user_prompt)
        pragmatist_task = self._ai.ask(_PRAGMATIST_SYSTEM, user_prompt)
        detailer_task   = self._ai.ask(_DETAILER_SYSTEM,   user_prompt)

        critic, pragmatist, detailer = await asyncio.gather(
            critic_task, pragmatist_task, detailer_task
        )

        output = (
            "# Reflection\n\n"
            "## 🔴 Critic\n"
            f"{critic}\n\n"
            "## 🟡 Pragmatist\n"
            f"{pragmatist}\n\n"
            "## 🔵 Detailer\n"
            f"{detailer}\n\n"
            "---\n"
            "Integrate these perspectives into your plan. "
            "Prioritise addressing points raised by the Critic before proceeding."
        )

        return ToolResult(success=True, output=output)
