"""Analytics tools for code analysis."""

from emdash.agent.tools.base import BaseTool, ToolResult, ToolCategory
from emdash.analytics.engine import AnalyticsEngine


class GetAreaImportanceTool(BaseTool):
    """Get important areas (directories) by development activity."""

    name = "get_area_importance"
    description = (
        "Get important code areas (directories) ranked by development activity. "
        "Shows where the team spends their time. Sort by 'focus' for recent activity "
        "(hot spots) or 'importance' for overall historical importance."
    )
    category = ToolCategory.ANALYTICS

    def __init__(self, connection=None):
        super().__init__(connection)
        self.engine = AnalyticsEngine(self.connection)

    def execute(
        self,
        sort: str = "focus",
        depth: int = 2,
        days: int = 30,
        limit: int = 15,
    ) -> ToolResult:
        """Get area importance metrics.

        Args:
            sort: Sort by 'focus' (recent activity) or 'importance' (overall)
            depth: Directory depth for grouping (default 2)
            days: Time window for recency scoring (default 30)
            limit: Maximum number of areas to return

        Returns:
            ToolResult with ranked areas
        """
        try:
            areas = self.engine.compute_area_importance(
                depth=depth,
                days=days,
                limit=limit,
            )

            if not areas:
                return ToolResult.success_result(
                    data={"areas": [], "count": 0},
                    suggestions=[
                        "No file history found. Run 'emdash index --git' to analyze git history.",
                    ],
                )

            # Sort by the requested metric
            if sort == "focus":
                areas.sort(key=lambda x: x.get("focus_pct", 0), reverse=True)
            else:  # importance
                areas.sort(key=lambda x: x.get("importance", 0), reverse=True)

            # Format results
            formatted = []
            for area in areas[:limit]:
                formatted.append({
                    "path": area.get("path", ""),
                    "total_commits": area.get("total_commits", 0),
                    "file_count": area.get("file_count", 0),
                    "importance": round(area.get("importance", 0), 2),
                    "focus_pct": area.get("focus_pct", 0),
                    "unique_authors": area.get("unique_authors", 0),
                })

            suggestions = []
            if formatted:
                top = formatted[0]
                if sort == "focus":
                    suggestions.append(
                        f"Hot spot: {top['path']} ({top['focus_pct']}% of recent activity)"
                    )
                else:
                    suggestions.append(
                        f"Most important: {top['path']} ({top['total_commits']} commits)"
                    )
                suggestions.append(
                    "Use semantic_search or expand_node to explore these areas."
                )

            return ToolResult.success_result(
                data={
                    "areas": formatted,
                    "count": len(formatted),
                    "sort": sort,
                },
                suggestions=suggestions,
            )

        except Exception as e:
            return ToolResult.error_result(
                str(e),
                suggestions=[
                    "Run 'emdash index --git' to analyze git history first.",
                ],
            )

    def get_schema(self) -> dict:
        return self._make_schema(
            properties={
                "sort": {
                    "type": "string",
                    "enum": ["focus", "importance"],
                    "default": "focus",
                    "description": "Sort by 'focus' (recent hot spots) or 'importance' (overall activity)",
                },
                "depth": {
                    "type": "integer",
                    "default": 2,
                    "description": "Directory depth for grouping",
                },
                "days": {
                    "type": "integer",
                    "default": 30,
                    "description": "Time window for recent activity",
                },
                "limit": {
                    "type": "integer",
                    "default": 15,
                    "description": "Maximum number of areas to return",
                },
            },
        )


class GetTopPageRankTool(BaseTool):
    """Get most important entities by PageRank."""

    name = "get_top_pagerank"
    description = (
        "Get the most important code entities by PageRank score. High scores indicate "
        "code that is heavily referenced by other code. Use this to find key components."
    )
    category = ToolCategory.ANALYTICS

    def __init__(self, connection=None):
        super().__init__(connection)
        self.engine = AnalyticsEngine(self.connection)

    def execute(
        self,
        limit: int = 20,
        entity_type: str = None,
    ) -> ToolResult:
        """Get top PageRank entities.

        Args:
            limit: Number of results
            entity_type: Filter by type (Function, Class)

        Returns:
            ToolResult with ranked entities
        """
        try:
            results = self.engine.get_top_pagerank(limit=limit)

            # Filter by type if specified
            if entity_type:
                results = [
                    (name, etype, score)
                    for name, etype, score in results
                    if etype == entity_type
                ]

            formatted = [
                {
                    "qualified_name": name,
                    "type": etype,
                    "pagerank_score": score,
                }
                for name, etype, score in results
            ]

            suggestions = []
            if formatted:
                top = formatted[0]
                score = top['pagerank_score']
                score_str = f"{score:.4f}" if score is not None else "N/A"
                suggestions.append(
                    f"Top entity: {top['qualified_name']} (score: {score_str}). "
                    "Use expand_node to explore it."
                )

            return ToolResult.success_result(
                data={
                    "results": formatted,
                    "count": len(formatted),
                },
                suggestions=suggestions,
            )

        except Exception as e:
            return ToolResult.error_result(
                str(e),
                suggestions=["Run 'emdash analyze pagerank' first to compute scores"],
            )

    def get_schema(self) -> dict:
        return self._make_schema(
            properties={
                "limit": {
                    "type": "integer",
                    "default": 20,
                    "description": "Number of results to return",
                },
                "entity_type": {
                    "type": "string",
                    "enum": ["Function", "Class"],
                    "description": "Filter by entity type",
                },
            },
        )


class GetCommunitiesTool(BaseTool):
    """Get detected code communities."""

    name = "get_communities"
    description = (
        "Get detected code communities/modules. Communities are clusters of tightly-coupled "
        "code entities. Use this to understand the architectural structure. "
        "Optionally search for communities related to a query using semantic search."
    )
    category = ToolCategory.ANALYTICS

    def __init__(self, connection=None):
        super().__init__(connection)
        self.engine = AnalyticsEngine(self.connection)
        self._similarity = None

    @property
    def similarity(self):
        """Lazy load similarity search."""
        if self._similarity is None:
            from emdash.planning.similarity import SimilaritySearch
            self._similarity = SimilaritySearch(self.connection)
        return self._similarity

    def execute(
        self,
        limit: int = 10,
        include_members: bool = False,
        max_members: int = 5,
        query: str = None,
        compact: bool = False,
    ) -> ToolResult:
        """Get community summaries.

        Args:
            limit: Number of communities to return
            include_members: Whether to include sample members
            max_members: Maximum members per community
            query: Semantic search query to find related communities
            compact: Return compact output format (useful with query)

        Returns:
            ToolResult with communities
        """
        try:
            # If query is provided, use semantic search to find related communities
            if query:
                # First, find relevant code entities
                search_results = self.similarity.find_similar_code(
                    query=query,
                    entity_types=["Function", "Class"],
                    limit=20,
                    min_score=0.3,
                )

                if not search_results:
                    return ToolResult.success_result(
                        data={
                            "query": query,
                            "communities": [],
                            "count": 0,
                        },
                        suggestions=["No matching code found. Try a different query."],
                    )

                # Get qualified names of matching entities
                qualified_names = [r["qualified_name"] for r in search_results if r.get("qualified_name")]

                # Find communities containing these entities
                communities = self.engine.search_communities(
                    qualified_names=qualified_names,
                    limit=limit,
                    max_members=max_members if include_members else 5,
                )

                # Compact format: just community IDs and sizes
                if compact:
                    compact_communities = [
                        {
                            "id": c["community_id"],
                            "size": c["member_count"],
                        }
                        for c in communities
                    ]
                    return ToolResult.success_result(
                        data={
                            "query": query,
                            "communities": compact_communities,
                            "count": len(compact_communities),
                            "matched_entities": len(qualified_names),
                        },
                        suggestions=[
                            f"Found {len(communities)} communities related to '{query}'.",
                            "Use get_community_members with community_id to explore.",
                        ],
                    )

                suggestions = []
                if communities:
                    suggestions.append(
                        f"Found {len(communities)} communities related to '{query}'."
                    )
                    suggestions.append(
                        "Use get_community_members to explore any community."
                    )

                return ToolResult.success_result(
                    data={
                        "query": query,
                        "communities": communities,
                        "count": len(communities),
                        "matched_entities": len(qualified_names),
                    },
                    suggestions=suggestions,
                )

            # Original behavior: return communities by size
            communities = self.engine.get_communities_summary(
                max_members=max_members if include_members else 0
            )[:limit]

            # Compact format
            if compact:
                compact_communities = [
                    {
                        "id": c["community_id"],
                        "size": c["member_count"],
                    }
                    for c in communities
                ]
                return ToolResult.success_result(
                    data={
                        "communities": compact_communities,
                        "count": len(compact_communities),
                    },
                    suggestions=["Use get_community_members with id to explore."],
                )

            suggestions = []
            if communities:
                largest = max(communities, key=lambda c: c.get("member_count", 0))
                suggestions.append(
                    f"Largest community has {largest['member_count']} members. "
                    "Use get_community_members to explore it."
                )

            return ToolResult.success_result(
                data={
                    "communities": communities,
                    "count": len(communities),
                },
                suggestions=suggestions,
            )

        except Exception as e:
            error_msg = str(e)
            # Check if this is a missing table error
            if "does not exist" in error_msg.lower() or "community" in error_msg.lower():
                return ToolResult.error_result(
                    "Community detection not available - analytics not run on this codebase.",
                    suggestions=[
                        "Use semantic_search or text_search instead to find related code.",
                        "Use get_callers/get_callees to trace code relationships.",
                        "Communities require running 'emdash analyze community' first.",
                    ],
                )
            return ToolResult.error_result(
                error_msg,
                suggestions=["Run 'emdash analyze community' first"],
            )

    def get_schema(self) -> dict:
        return self._make_schema(
            properties={
                "limit": {
                    "type": "integer",
                    "default": 10,
                    "description": "Maximum number of communities",
                },
                "include_members": {
                    "type": "boolean",
                    "default": False,
                    "description": "Include sample member names",
                },
                "max_members": {
                    "type": "integer",
                    "default": 5,
                    "description": "Maximum members to show per community",
                },
                "query": {
                    "type": "string",
                    "description": "Semantic search query to find related communities (e.g., 'authentication', 'database')",
                },
                "compact": {
                    "type": "boolean",
                    "default": False,
                    "description": "Return compact output (just id and size)",
                },
            },
        )


class GetCommunityMembersTool(BaseTool):
    """Get members of a specific community."""

    name = "get_community_members"
    description = (
        "Get all members of a specific code community. Use this to understand "
        "what code belongs to a particular module or subsystem."
    )
    category = ToolCategory.ANALYTICS

    def __init__(self, connection=None):
        super().__init__(connection)
        self.engine = AnalyticsEngine(self.connection)

    def execute(self, community_id: int, limit: int = 20) -> ToolResult:
        """Get community members.

        Args:
            community_id: ID of the community
            limit: Maximum members to return (default 20)

        Returns:
            ToolResult with member list
        """
        try:
            all_members = self.engine.get_community_members(community_id)

            # Count by type (on all members)
            by_type = {}
            for m in all_members:
                t = m.get("type", "Unknown")
                by_type[t] = by_type.get(t, 0) + 1

            # Limit returned members
            members = all_members[:limit]
            total_count = len(all_members)

            suggestions = []
            if all_members:
                type_summary = ", ".join(f"{v} {k}s" for k, v in by_type.items())
                suggestions.append(f"Community contains: {type_summary}")
                if total_count > limit:
                    suggestions.append(f"Showing {limit} of {total_count} members. Increase limit for more.")
            else:
                suggestions.append("No members found for this community ID.")

            return ToolResult.success_result(
                data={
                    "community_id": community_id,
                    "members": members,
                    "total_count": total_count,
                    "returned_count": len(members),
                    "types_summary": by_type,
                },
                suggestions=suggestions,
            )

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

    def get_schema(self) -> dict:
        return self._make_schema(
            properties={
                "community_id": {
                    "type": "integer",
                    "description": "ID of the community to get members for",
                },
                "limit": {
                    "type": "integer",
                    "default": 20,
                    "description": "Maximum members to return (default 20)",
                },
            },
            required=["community_id"],
        )


