"""
Context Assembler for MCAL

Assembles context from retrieved memories, goals, and decisions
for LLM input. Part of Pillar 3 (Goal-Aware Context Retrieval).

Note: The original GoalRetriever class with multi-factor scoring
(α×semantic + β×goal + γ×recency + δ×frequency + ε×decision_impact)
has been removed (Issue #97). The scoring concept will be integrated
into UnifiedGraph.search() in a future enhancement.
"""

from __future__ import annotations

import logging
from typing import Optional

from .models import (
    DecisionTrail,
    IntentNode,
    RetrievalResult,
)


logger = logging.getLogger(__name__)


# =============================================================================
# Context Assembler
# =============================================================================

class ContextAssembler:
    """
    Assembles context from retrieved memories for LLM input.
    
    Handles:
    - Token budget management
    - Priority ordering
    - Format optimization
    - Deduplication
    """
    
    def __init__(self, max_tokens: int = 4000):
        """
        Initialize the context assembler.
        
        Args:
            max_tokens: Maximum tokens for assembled context
        """
        self.max_tokens = max_tokens
    
    def assemble(
        self,
        retrieved: list[RetrievalResult],
        active_goals: Optional[list[IntentNode]] = None,
        decisions: Optional[list[DecisionTrail]] = None,
        include_goals: bool = True,
        include_decisions: bool = True
    ) -> str:
        """
        Assemble context from retrieved memories and structured data.
        
        Args:
            retrieved: Retrieved memory results
            active_goals: Active goals to include
            decisions: Relevant decisions to include
            include_goals: Whether to include goal summary
            include_decisions: Whether to include decision summary
            
        Returns:
            Assembled context string
        """
        sections = []
        
        # 1. Active goals section
        if include_goals and active_goals:
            goal_section = self._format_goals(active_goals)
            sections.append(("ACTIVE GOALS", goal_section))
        
        # 2. Relevant decisions section
        if include_decisions and decisions:
            decision_section = self._format_decisions(decisions)
            sections.append(("KEY DECISIONS", decision_section))
        
        # 3. Retrieved memories section
        if retrieved:
            memory_section = self._format_memories(retrieved)
            sections.append(("RELEVANT CONTEXT", memory_section))
        
        # Assemble with headers
        output = []
        for header, content in sections:
            output.append(f"### {header} ###")
            output.append(content)
            output.append("")
        
        return "\n".join(output)
    
    def _format_goals(self, goals: list[IntentNode]) -> str:
        """Format goals for context."""
        lines = []
        for goal in goals:
            status_marker = {
                "active": "🔵",
                "completed": "✅",
                "pending": "⏳"
            }.get(goal.status.value, "")
            
            lines.append(f"- {status_marker} [{goal.type.value}] {goal.content}")
        
        return "\n".join(lines)
    
    def _format_decisions(self, decisions: list[DecisionTrail]) -> str:
        """Format decisions for context."""
        lines = []
        for decision in decisions[:5]:  # Limit to top 5
            lines.append(f"DECISION: {decision.decision}")
            lines.append(f"  Rationale: {decision.rationale}")
            if decision.alternatives:
                alt_names = [a.option for a in decision.alternatives[:3]]
                lines.append(f"  Alternatives considered: {', '.join(alt_names)}")
            lines.append("")
        
        return "\n".join(lines)
    
    def _format_memories(self, results: list[RetrievalResult]) -> str:
        """Format retrieved memories for context."""
        lines = []
        for result in results:
            memory = result.memory
            score = result.score
            
            lines.append(f"[{memory.type.value}] (relevance: {score:.2f})")
            lines.append(f"  {memory.content}")
            lines.append("")
        
        return "\n".join(lines)
