from __future__ import annotations

import json
import sys
from pathlib import Path
from typing import Any, Optional

ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

from planner.planner import PlanContext, PlanRequest, PlannerService


class MockLLMClient:
    """A deterministic mock that returns an invalid plan, then a corrected plan."""

    def __init__(self) -> None:
        self.calls = 0

    def generate(
        self,
        intent: str,
        context: Optional[Any] = None,
        feedback: Optional[str] = None,
        temperature: float = 0.3,
    ) -> str:
        self.calls += 1
        if feedback:
            print("\n--- Feedback received by MockLLMClient ---")
            print(feedback)
            print("--- End feedback ---\n")

        if self.calls == 1:
            plan = {
                "intent": intent,
                "workflow_topology": "DAG",
                "plan_id": "plan_demo_bad",
                "steps": [
                    {
                        "step_id": "s1",
                        "type": "EXECUTION",
                        "agent_role": "robot",
                        "action": "NAVIGATE",
                        "params": {"destination": "lobby"},
                    },
                    {
                        "step_id": "s2",
                        "type": "EXECUTION",
                        "agent_role": "robot",
                        "action": "SCAN_AREA",
                        "dependencies": ["s1"],
                        "params": {"target": "people"},
                    },
                    {
                        "step_id": "s3",
                        "type": "EXECUTION",
                        "agent_role": "robot",
                        "action": "SPEAK",
                        "dependencies": ["s2"],
                        "params": {"message": "Scan complete"},
                    },
                ],
            }
        else:
            plan = {
                "intent": intent,
                "workflow_topology": "DAG",
                "plan_id": "plan_demo_ok",
                "steps": [
                    {
                        "step_id": "s1",
                        "type": "EXECUTION",
                        "agent_role": "robot",
                        "action": "CHECK_BATTERY",
                        "params": {"min_level": 30},
                    },
                    {
                        "step_id": "s2",
                        "type": "EXECUTION",
                        "agent_role": "robot",
                        "action": "NAVIGATE",
                        "dependencies": ["s1"],
                        "params": {"destination": "lobby", "speed": "normal"},
                    },
                    {
                        "step_id": "s3",
                        "type": "EXECUTION",
                        "agent_role": "robot",
                        "action": "SCAN_AREA",
                        "dependencies": ["s2"],
                        "params": {"target": "people"},
                    },
                    {
                        "step_id": "s4",
                        "type": "EXECUTION",
                        "agent_role": "robot",
                        "action": "SPEAK",
                        "dependencies": ["s3"],
                        "params": {"message": "Scan complete"},
                    },
                ],
            }

        return json.dumps(plan)


def main() -> None:
    context = PlanContext(
        robot_id="demo_bot",
        current_location="charging_dock",
        battery_level=85,
        available_actions=[
            "CHECK_BATTERY",
            "NAVIGATE",
            "SCAN_AREA",
            "VERIFY_OBJECT",
            "SPEAK",
            "WAIT",
            "IDENTIFY_PERSON",
            "ALERT_OPERATOR",
        ],
        venue_id="lobby",
        mission_type="demo",
    )
    request = PlanRequest(
        intent="Go to the lobby and scan for people.",
        context=context,
        request_id="demo-request",
    )

    service = PlannerService(llm_client=MockLLMClient())
    result = service.plan(request)

    print("=== Dry Run Result ===")
    print(f"success: {result.success}")
    print(f"attempts: {result.attempts}")
    print(f"is_safe_noop: {result.is_safe_noop}")
    print(f"failure_reason: {result.failure_reason}")
    print("plan:")
    print(json.dumps(result.plan, indent=2))


if __name__ == "__main__":
    main()
