"""
ChunkHive Context Engine
========================

Builds intelligent multi-chunk context for downstream usage.

Pipeline:
Search → Rank → Dependency Expand → Context Build
"""

from typing import List, Any


class ContextEngine:
    """
    Builds multi-chunk contextual result sets.
    """

    def __init__(
        self,
        ranking_engine,
        dependency_expander=None,
        max_context_chunks: int = 8,
        max_total_chars: int = 12000,
    ):
        """
        ranking_engine: RankingEngine instance
        dependency_expander: Optional DependencyExpander
        """
        self.ranking_engine = ranking_engine
        self.dependency_expander = dependency_expander
        self.max_context_chunks = max_context_chunks
        self.max_total_chars = max_total_chars

    def build_context(
        self,
        query: str,
        candidates: List[Any],
        top_k: int = 5,
        expand: bool = True,
        explain: bool = False,
    ) -> List[Any]:
        """
        Returns intelligently expanded context chunks.
        """

        # 1️⃣ Rank
        ranked = self.ranking_engine.rank(
            query=query,
            candidates=candidates,
            top_k=top_k,
            explain=explain,
        )

        base_chunks = [r.chunk for r in ranked]

        # 2️⃣ Dependency expansion (optional)
        if expand and self.dependency_expander:
            expanded_chunks = self.dependency_expander.expand(
                base_chunks,
                max_expansion=self.max_context_chunks,
            )
        else:
            expanded_chunks = base_chunks

        # 3️⃣ Apply size control (context compression)
        final_chunks = []
        total_chars = 0

        for chunk in expanded_chunks:
            code = getattr(chunk, "code", "")
            size = len(code)

            if total_chars + size > self.max_total_chars:
                break

            final_chunks.append(chunk)
            total_chars += size

        return final_chunks


# """
# ChunkHive Context Engine
# ========================

# Builds intelligent contextual bundles around ranked search results.

# Expands:
# - Same class methods
# - Same file neighbors
# - Structural parents
# - Lightweight dependency signals

# This transforms simple search into full context retrieval.
# """

# from typing import List, Any, Dict
# from dataclasses import dataclass


# @dataclass
# class ContextBundle:
#     primary_chunk: Any
#     expanded_chunks: List[Any]
#     metadata: Dict


# class ContextEngine:
#     """
#     Builds contextual expansion around ranked results.
#     """

#     def __init__(
#         self,
#         max_expansion: int = 5,
#         include_same_file: bool = True,
#         include_class_siblings: bool = True,
#     ):
#         self.max_expansion = max_expansion
#         self.include_same_file = include_same_file
#         self.include_class_siblings = include_class_siblings

#     # --------------------------------------------------
#     # Public API
#     # --------------------------------------------------

#     def build_context(
#         self,
#         primary_chunk: Any,
#         all_chunks: List[Any],
#     ) -> ContextBundle:

#         expanded = []

#         # 1️⃣ Same file expansion
#         if self.include_same_file:
#             same_file_chunks = self._get_same_file_chunks(
#                 primary_chunk, all_chunks
#             )
#             expanded.extend(same_file_chunks)

#         # 2️⃣ Class sibling expansion
#         if self.include_class_siblings:
#             class_related = self._get_class_related_chunks(
#                 primary_chunk, all_chunks
#             )
#             expanded.extend(class_related)

#         # Remove duplicates & primary
#         unique = []
#         seen_ids = set()

#         for chunk in expanded:
#             chunk_id = id(chunk)
#             if chunk_id not in seen_ids and chunk != primary_chunk:
#                 unique.append(chunk)
#                 seen_ids.add(chunk_id)

#         # Limit expansion
#         final_expansion = unique[: self.max_expansion]

#         return ContextBundle(
#             primary_chunk=primary_chunk,
#             expanded_chunks=final_expansion,
#             metadata={
#                 "primary_file": getattr(primary_chunk, "file_path", None),
#                 "expansion_count": len(final_expansion),
#             },
#         )

#     # --------------------------------------------------
#     # Expansion Methods
#     # --------------------------------------------------

#     def _get_same_file_chunks(
#         self,
#         primary_chunk: Any,
#         all_chunks: List[Any],
#     ) -> List[Any]:

#         file_path = getattr(primary_chunk, "file_path", None)

#         if not file_path:
#             return []

#         return [
#             chunk
#             for chunk in all_chunks
#             if getattr(chunk, "file_path", None) == file_path
#         ]

#     def _get_class_related_chunks(
#         self,
#         primary_chunk: Any,
#         all_chunks: List[Any],
#     ) -> List[Any]:

#         if not hasattr(primary_chunk, "ast"):
#             return []

#         primary_name = getattr(primary_chunk.ast, "name", None)
#         primary_type = getattr(primary_chunk, "chunk_type", "")

#         # If primary is class → get its methods
#         if primary_type == "class":
#             return [
#                 chunk
#                 for chunk in all_chunks
#                 if getattr(chunk, "parent_name", None) == primary_name
#             ]

#         # If primary is method → get its class
#         if primary_type == "method":
#             parent_name = getattr(primary_chunk, "parent_name", None)

#             return [
#                 chunk
#                 for chunk in all_chunks
#                 if getattr(chunk.ast, "name", None) == parent_name
#             ]

#         return []
