"""Planning tool for exploration strategy."""

from emdash.agent.tools.base import BaseTool, ToolResult, ToolCategory


class PlanExplorationTool(BaseTool):
    """Generate an exploration strategy based on a goal."""

    name = "plan_exploration"
    description = (
        "Generate an exploration strategy for understanding code or planning implementation. "
        "Use this when you need to investigate a feature, understand a codebase area, "
        "or plan changes. Returns recommended tools and steps."
    )
    category = ToolCategory.PLANNING

    # Exploration strategies with recommended tool sequences
    STRATEGIES = {
        "feature_understanding": {
            "description": "Understand how a feature works",
            "steps": [
                {
                    "action": "semantic_search",
                    "rationale": "Find entry points related to the feature",
                    "params_template": {"query": "{goal}", "limit": 5},
                },
                {
                    "action": "expand_node",
                    "rationale": "Expand the most relevant result to understand context",
                    "params_template": {"node_type": "FROM_SEARCH", "identifier": "FROM_SEARCH"},
                },
                {
                    "action": "get_callers",
                    "rationale": "Find what calls this code to understand usage",
                    "params_template": {"qualified_name": "FROM_EXPAND"},
                },
                {
                    "action": "get_file_history",
                    "rationale": "Understand recent changes and who to ask",
                    "params_template": {"file_path": "FROM_EXPAND"},
                },
            ],
        },
        "impact_analysis": {
            "description": "Assess impact of making changes",
            "steps": [
                {
                    "action": "get_impact_analysis",
                    "rationale": "Find affected components and risk level",
                    "params_template": {"file_path": "{file_path}"},
                },
                {
                    "action": "get_callers",
                    "rationale": "Find all code that depends on this",
                    "params_template": {"qualified_name": "FROM_IMPACT"},
                },
                {
                    "action": "get_file_dependencies",
                    "rationale": "Check module dependencies",
                    "params_template": {"file_path": "{file_path}"},
                },
                {
                    "action": "detect_knowledge_silos",
                    "rationale": "Identify ownership risks",
                    "params_template": {},
                },
            ],
        },
        "codebase_orientation": {
            "description": "Get oriented in a new codebase",
            "steps": [
                {
                    "action": "get_communities",
                    "rationale": "Understand the high-level architecture",
                    "params_template": {"limit": 10, "include_members": True},
                },
                {
                    "action": "get_communities",
                    "rationale": "Find communities related to your area of interest",
                    "params_template": {"query": "{goal}", "limit": 5, "include_members": True},
                },
                {
                    "action": "get_top_pagerank",
                    "rationale": "Find the most important code entities",
                    "params_template": {"limit": 20},
                },
            ],
        },
        "find_implementation": {
            "description": "Find how something is implemented",
            "steps": [
                {
                    "action": "semantic_search",
                    "rationale": "Search for relevant code",
                    "params_template": {"query": "{goal}"},
                },
                {
                    "action": "find_similar_prs",
                    "rationale": "Find PRs that implemented similar features",
                    "params_template": {"description": "{goal}"},
                },
                {
                    "action": "expand_node",
                    "rationale": "Explore the implementation details",
                    "params_template": {"node_type": "FROM_SEARCH", "identifier": "FROM_SEARCH"},
                },
            ],
        },
        "find_experts": {
            "description": "Find domain experts for an area",
            "steps": [
                {
                    "action": "semantic_search",
                    "rationale": "Find relevant code files",
                    "params_template": {"query": "{goal}"},
                },
                {
                    "action": "get_file_history",
                    "rationale": "Find who has worked on this code",
                    "params_template": {"file_path": "FROM_SEARCH"},
                },
                {
                    "action": "detect_knowledge_silos",
                    "rationale": "Identify concentrated knowledge areas",
                    "params_template": {},
                },
            ],
        },
        # Use-case specific strategies
        "spec_exploration": {
            "description": "Explore codebase to write a feature specification",
            "steps": [
                {
                    "action": "get_communities",
                    "rationale": "Find code communities related to the feature area",
                    "params_template": {"query": "{goal}", "limit": 5, "include_members": True},
                },
                {
                    "action": "semantic_search",
                    "rationale": "Find existing code related to the feature",
                    "params_template": {"query": "{goal}", "limit": 10},
                },
                {
                    "action": "expand_node",
                    "rationale": "Deep dive into the most relevant code",
                    "params_template": {"node_type": "FROM_SEARCH", "identifier": "FROM_SEARCH"},
                },
                {
                    "action": "find_similar_prs",
                    "rationale": "See if similar features were implemented before",
                    "params_template": {"description": "{goal}", "state": "merged"},
                },
                {
                    "action": "find_similar_prs",
                    "rationale": "Check for open PRs working on related features",
                    "params_template": {"description": "{goal}", "state": "open"},
                },
                {
                    "action": "get_file_dependencies",
                    "rationale": "Understand module relationships",
                    "params_template": {"file_path": "FROM_SEARCH"},
                },
            ],
        },
        "implementation_planning": {
            "description": "Explore codebase to plan implementation tasks",
            "steps": [
                {
                    "action": "get_communities",
                    "rationale": "Find code communities related to the feature - understand architectural context",
                    "params_template": {"query": "{goal}", "limit": 5, "include_members": True},
                },
                {
                    "action": "find_similar_prs",
                    "rationale": "Find how the team implemented similar features - study patterns",
                    "params_template": {"description": "{goal}", "state": "merged", "limit": 5},
                },
                {
                    "action": "semantic_search",
                    "rationale": "Find existing code patterns to follow",
                    "params_template": {"query": "{goal}", "limit": 10},
                },
                {
                    "action": "expand_node",
                    "rationale": "Understand the code structure and patterns",
                    "params_template": {"node_type": "FROM_SEARCH", "identifier": "FROM_SEARCH"},
                },
                {
                    "action": "get_impact_analysis",
                    "rationale": "Identify files that need modification",
                    "params_template": {"file_path": "FROM_SEARCH"},
                },
                {
                    "action": "get_file_history",
                    "rationale": "Find code owner (person with most commits) for reviewer",
                    "params_template": {"file_path": "FROM_SEARCH", "limit": 20},
                },
                {
                    "action": "find_similar_prs",
                    "rationale": "Check for open PRs that might conflict",
                    "params_template": {"description": "{goal}", "state": "open"},
                },
            ],
        },
    }

    def execute(
        self,
        goal: str,
        context: str = "",
        constraints: list[str] = None,
        exploration_depth: str = "medium",
        use_case: str = "",
    ) -> ToolResult:
        """Generate an exploration plan.

        Args:
            goal: What you're trying to understand or accomplish
            context: Any context you already have
            constraints: Constraints on the exploration
            exploration_depth: How thorough (shallow, medium, deep)
            use_case: The agent use case - "spec" or "implementation" for tailored strategies

        Returns:
            ToolResult with exploration plan
        """
        try:
            # Determine the best strategy
            strategy_name = self._determine_strategy(goal, context, use_case)
            strategy = self.STRATEGIES[strategy_name]

            # Generate steps based on depth
            depth_limits = {"shallow": 2, "medium": 4, "deep": 10}
            max_steps = depth_limits.get(exploration_depth, 4)

            steps = []
            for i, step_template in enumerate(strategy["steps"][:max_steps], 1):
                step = {
                    "step": i,
                    "action": step_template["action"],
                    "rationale": step_template["rationale"],
                    "params": self._resolve_params(step_template["params_template"], goal),
                }
                steps.append(step)

            # Generate key questions to answer
            questions = self._generate_questions(goal, strategy_name)

            plan = {
                "goal": goal,
                "strategy": strategy_name,
                "strategy_description": strategy["description"],
                "exploration_depth": exploration_depth,
                "steps": steps,
                "estimated_steps": len(steps),
                "key_questions_to_answer": questions,
            }

            suggestions = [
                f"Start with: {steps[0]['action']} - {steps[0]['rationale']}",
                "Adjust the plan based on what you find in each step.",
            ]

            if context:
                suggestions.append(
                    "Consider the provided context when interpreting results."
                )

            return ToolResult.success_result(
                data={"plan": plan},
                suggestions=suggestions,
            )

        except Exception as e:
            return ToolResult.error_result(str(e))

    def _determine_strategy(self, goal: str, context: str, use_case: str = "") -> str:
        """Determine the best exploration strategy based on goal and use case."""
        goal_lower = goal.lower()
        use_case_lower = use_case.lower()

        # If use_case is specified, use the tailored strategy
        if use_case_lower == "spec":
            return "spec_exploration"
        if use_case_lower == "implementation":
            return "implementation_planning"

        # Fall back to keyword-based detection
        # Check for impact/change keywords
        if any(w in goal_lower for w in ["change", "modify", "impact", "affect", "refactor"]):
            return "impact_analysis"

        # Check for understanding keywords
        if any(w in goal_lower for w in ["understand", "how does", "explain", "what is", "learn"]):
            return "feature_understanding"

        # Check for orientation keywords
        if any(w in goal_lower for w in ["new", "orient", "overview", "structure", "architecture"]):
            return "codebase_orientation"

        # Check for implementation keywords
        if any(w in goal_lower for w in ["implement", "add", "create", "build", "find", "where"]):
            return "find_implementation"

        # Check for expert/who keywords
        if any(w in goal_lower for w in ["who", "expert", "author", "maintainer", "owner"]):
            return "find_experts"

        # Default to feature understanding
        return "feature_understanding"

    def _resolve_params(self, template: dict, goal: str) -> dict:
        """Resolve parameter templates."""
        resolved = {}
        for key, value in template.items():
            if isinstance(value, str):
                if value == "{goal}":
                    resolved[key] = goal
                elif value.startswith("FROM_"):
                    resolved[key] = f"<{value}>"  # Placeholder for dependent value
                elif "{" in value and "}" in value:
                    # Handle other placeholders - try to format with goal, keep placeholder if fails
                    try:
                        resolved[key] = value.format(goal=goal)
                    except KeyError:
                        # Placeholder like {file_path} - mark as dependent
                        resolved[key] = f"<FROM_INPUT:{key}>"
                else:
                    resolved[key] = value
            else:
                resolved[key] = value
        return resolved

    def _generate_questions(self, goal: str, strategy: str) -> list[str]:
        """Generate key questions to answer based on strategy."""
        base_questions = {
            "feature_understanding": [
                "What is the main entry point for this feature?",
                "How does the data flow through the system?",
                "What are the key functions/classes involved?",
                "Who are the domain experts for this code?",
            ],
            "impact_analysis": [
                "What code directly depends on this?",
                "What is the risk level of making changes?",
                "Are there tests covering this code?",
                "Who should review changes to this code?",
            ],
            "codebase_orientation": [
                "What are the main modules/components?",
                "Which communities are related to my area of interest?",
                "Where are the most important code entities?",
                "How is the codebase organized?",
            ],
            "find_implementation": [
                "Where is this implemented?",
                "Have similar features been implemented before?",
                "What patterns are used?",
                "What dependencies are needed?",
            ],
            "find_experts": [
                "Who has the most commits in this area?",
                "Are there knowledge silos?",
                "Who should be consulted for changes?",
            ],
            "spec_exploration": [
                "Which code communities are related to this feature?",
                "What existing code is related to this feature?",
                "Have similar features been built before?",
                "What are the key integration points?",
                "Are there open PRs working on related features?",
            ],
            "implementation_planning": [
                "Which code communities does this feature touch?",
                "What patterns does the team use for similar features?",
                "Which files need to be modified?",
                "Who is the code owner (most commits) for the reviewer?",
                "Are there open PRs that might conflict?",
            ],
        }

        return base_questions.get(strategy, base_questions["feature_understanding"])

    def get_schema(self) -> dict:
        return self._make_schema(
            properties={
                "goal": {
                    "type": "string",
                    "description": "What you're trying to understand or accomplish",
                },
                "context": {
                    "type": "string",
                    "description": "Any context you already have (file names, function names, etc.)",
                },
                "constraints": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Constraints on the exploration (e.g., 'focus on Python files')",
                },
                "exploration_depth": {
                    "type": "string",
                    "enum": ["shallow", "medium", "deep"],
                    "default": "medium",
                    "description": "How thoroughly to explore",
                },
                "use_case": {
                    "type": "string",
                    "enum": ["spec", "implementation", ""],
                    "default": "",
                    "description": "Agent use case for tailored strategies: 'spec' for specification writing, 'implementation' for implementation planning",
                },
            },
            required=["goal"],
        )
