#!/usr/bin/env python3
"""
Contextual Pattern Activation System
===================================

This module implements MIRA's contextual pattern activation system that
dynamically activates different pattern sets based on project type, user
behavior, conversation themes, and temporal context. This enables
intelligent adaptation to different scenarios and use cases.

Key Features:
- Project-type based pattern activation (web dev, AI/ML, mobile, etc.)
- User behavior pattern sets (debugging, exploring, building, optimizing)
- Conversation theme activation (technical, planning, troubleshooting)
- Temporal context awareness (time of day, session length, work patterns)
- Dynamic pattern set composition and weighting
- Real-time activation/deactivation based on context changes

Contextual Intelligence:
- Patterns are activated/deactivated based on current context
- Different pattern weights for different scenarios
- Context-aware confidence thresholds
- Pattern set composition adapts to user needs
- Intelligent fallback mechanisms for unknown contexts

Author: MIRA Contextual Intelligence System
Version: 1.0 (Dynamic Pattern Activation)
"""

import os
import json
import datetime
import time
from typing import Dict, List, Set, Optional, Tuple, Union
from dataclasses import dataclass, asdict
from enum import Enum
from pathlib import Path
import logging

logger = logging.getLogger(__name__)

class ProjectType(Enum):
    """Different project types that require different pattern sets."""
    WEB_DEVELOPMENT = "web_development"
    AI_ML = "ai_ml"
    MOBILE_DEVELOPMENT = "mobile_development"
    DESKTOP_APPLICATION = "desktop_application"
    DATA_SCIENCE = "data_science"
    DEVOPS_INFRASTRUCTURE = "devops_infrastructure"
    GAME_DEVELOPMENT = "game_development"
    BLOCKCHAIN = "blockchain"
    IOT_EMBEDDED = "iot_embedded"
    RESEARCH = "research"
    DOCUMENTATION = "documentation"
    GENERAL = "general"

class UserBehaviorContext(Enum):
    """Different user behaviors that require different pattern approaches."""
    EXPLORING = "exploring"  # Learning, investigating, reading code
    BUILDING = "building"    # Creating new features, implementing
    DEBUGGING = "debugging"  # Fixing bugs, troubleshooting issues
    OPTIMIZING = "optimizing"  # Performance, refactoring, improving
    PLANNING = "planning"    # Architecture, design, strategy
    LEARNING = "learning"    # Documentation, tutorials, understanding
    COLLABORATING = "collaborating"  # Team work, code review, discussions
    EXPERIMENTING = "experimenting"  # Prototyping, testing ideas

class ConversationTheme(Enum):
    """Different conversation themes that activate specific patterns."""
    TECHNICAL_IMPLEMENTATION = "technical_implementation"
    PROBLEM_SOLVING = "problem_solving"
    ARCHITECTURAL_DESIGN = "architectural_design"
    CODE_REVIEW = "code_review"
    PERFORMANCE_OPTIMIZATION = "performance_optimization"
    BUG_INVESTIGATION = "bug_investigation"
    FEATURE_PLANNING = "feature_planning"
    USER_EXPERIENCE = "user_experience"
    SECURITY_CONCERNS = "security_concerns"
    DEPLOYMENT_OPERATIONS = "deployment_operations"
    GENERAL_DISCUSSION = "general_discussion"

class TemporalContext(Enum):
    """Time-based contexts that influence pattern activation."""
    MORNING_FRESH = "morning_fresh"      # Early morning, high focus
    MIDDAY_PRODUCTIVE = "midday_productive"  # Peak productivity hours
    AFTERNOON_COLLABORATIVE = "afternoon_collaborative"  # Team interaction time
    EVENING_REFLECTIVE = "evening_reflective"  # End of day, planning
    LATE_NIGHT_CREATIVE = "late_night_creative"  # Creative/experimental time
    WEEKEND_EXPLORATORY = "weekend_exploratory"  # Learning, side projects

@dataclass
class ContextualEnvironment:
    """Complete contextual environment for pattern activation."""
    project_type: ProjectType
    user_behavior: UserBehaviorContext
    conversation_theme: ConversationTheme
    temporal_context: TemporalContext
    session_duration: float  # Minutes since session start
    recent_commands: List[str]  # Last 10 commands used
    error_context: bool  # True if user recently encountered errors
    complexity_level: float  # 0.0-1.0, current task complexity
    collaboration_mode: bool  # True if working with others
    urgency_level: float  # 0.0-1.0, how urgent the current task is
    
    def __post_init__(self):
        if not self.recent_commands:
            self.recent_commands = []

@dataclass
class PatternSet:
    """A set of patterns activated for a specific context."""
    set_id: str
    name: str
    description: str
    pattern_ids: List[str]
    base_confidence_threshold: float
    context_weight: float  # How strongly this set applies to current context
    activation_conditions: Dict[str, Union[str, List[str], float]]
    deactivation_conditions: Dict[str, Union[str, List[str], float]]
    fallback_sets: List[str]  # Other sets to try if this one fails
    
    def matches_context(self, context: ContextualEnvironment) -> float:
        """Calculate how well this pattern set matches the current context."""
        match_score = 0.0
        total_conditions = 0
        
        # Check project type match
        if "project_types" in self.activation_conditions:
            total_conditions += 1
            if context.project_type.value in self.activation_conditions["project_types"]:
                match_score += 1.0
        
        # Check user behavior match
        if "user_behaviors" in self.activation_conditions:
            total_conditions += 1
            if context.user_behavior.value in self.activation_conditions["user_behaviors"]:
                match_score += 1.0
        
        # Check conversation theme match
        if "conversation_themes" in self.activation_conditions:
            total_conditions += 1
            if context.conversation_theme.value in self.activation_conditions["conversation_themes"]:
                match_score += 1.0
        
        # Check temporal context match
        if "temporal_contexts" in self.activation_conditions:
            total_conditions += 1
            if context.temporal_context.value in self.activation_conditions["temporal_contexts"]:
                match_score += 1.0
        
        # Check session duration
        if "min_session_duration" in self.activation_conditions:
            total_conditions += 1
            if context.session_duration >= self.activation_conditions["min_session_duration"]:
                match_score += 1.0
        
        # Check complexity level
        if "min_complexity" in self.activation_conditions:
            total_conditions += 1
            if context.complexity_level >= self.activation_conditions["min_complexity"]:
                match_score += 1.0
        
        # Check recent commands
        if "required_commands" in self.activation_conditions:
            total_conditions += 1
            required_commands = self.activation_conditions["required_commands"]
            if any(cmd in context.recent_commands for cmd in required_commands):
                match_score += 1.0
        
        # Check error context
        if "error_context" in self.activation_conditions:
            total_conditions += 1
            if context.error_context == self.activation_conditions["error_context"]:
                match_score += 1.0
        
        return match_score / total_conditions if total_conditions > 0 else 0.0

@dataclass
class PatternActivationEvent:
    """Records when patterns are activated/deactivated."""
    timestamp: str
    context: ContextualEnvironment
    activated_sets: List[str]
    deactivated_sets: List[str]
    pattern_ids: List[str]
    total_patterns_active: int
    activation_reason: str
    
    def __post_init__(self):
        if not self.timestamp:
            self.timestamp = datetime.datetime.now().isoformat()

class ContextualPatternActivation:
    """
    Manages contextual pattern activation based on dynamic environment analysis.
    """
    
    def __init__(self, memory_dir: str):
        self.memory_dir = memory_dir
        self.activation_dir = os.path.join(memory_dir, "contextual_activation")
        os.makedirs(self.activation_dir, exist_ok=True)
        
        # Storage files
        self.pattern_sets_file = os.path.join(self.activation_dir, "pattern_sets.json")
        self.activation_log_file = os.path.join(self.activation_dir, "activation_events.jsonl")
        self.context_history_file = os.path.join(self.activation_dir, "context_history.jsonl")
        
        # Initialize pattern sets and other systems
        self.pattern_sets: Dict[str, PatternSet] = {}
        self.current_context: Optional[ContextualEnvironment] = None
        self.active_pattern_sets: Set[str] = set()
        self.session_start_time = time.time()
        
        # Load existing data
        self._load_pattern_sets()
        self._initialize_default_pattern_sets()
        
        # Connect to other systems
        self.adaptive_pattern_system = None
        self.confidence_system = None
        self._initialize_system_connections()
    
    def _initialize_system_connections(self):
        """Initialize connections to other MIRA systems."""
        try:
            from intelligence.adaptive_pattern_evolution import get_adaptive_pattern_evolution
            self.adaptive_pattern_system = get_adaptive_pattern_evolution(self.memory_dir)
        except Exception as e:
            logger.debug(f"Failed to connect to adaptive pattern system: {e}")
        
        try:
            from intelligence.pattern_confidence_system import get_pattern_confidence_system
            self.confidence_system = get_pattern_confidence_system(self.memory_dir)
        except Exception as e:
            logger.debug(f"Failed to connect to confidence system: {e}")
    
    def _load_pattern_sets(self):
        """Load existing pattern sets from storage."""
        if not os.path.exists(self.pattern_sets_file):
            return
        
        try:
            with open(self.pattern_sets_file, 'r') as f:
                data = json.load(f)
                for set_id, set_data in data.items():
                    self.pattern_sets[set_id] = PatternSet(**set_data)
            logger.debug(f"🎯 Loaded {len(self.pattern_sets)} contextual pattern sets")
        except Exception as e:
            logger.error(f"Failed to load pattern sets: {e}")
    
    def _save_pattern_sets(self):
        """Save pattern sets to storage."""
        try:
            data = {}
            for set_id, pattern_set in self.pattern_sets.items():
                data[set_id] = asdict(pattern_set)
            
            with open(self.pattern_sets_file, 'w') as f:
                json.dump(data, f, indent=2)
        except Exception as e:
            logger.error(f"Failed to save pattern sets: {e}")
    
    def _initialize_default_pattern_sets(self):
        """Initialize default pattern sets if none exist."""
        if self.pattern_sets:
            return  # Already have pattern sets
        
        default_sets = [
            # Web Development Patterns
            PatternSet(
                set_id="web_dev_building",
                name="Web Development - Building",
                description="Patterns for building web applications",
                pattern_ids=["react_component_creation", "api_endpoint_design", "frontend_optimization"],
                base_confidence_threshold=0.6,
                context_weight=1.0,
                activation_conditions={
                    "project_types": ["web_development"],
                    "user_behaviors": ["building", "experimenting"],
                    "conversation_themes": ["technical_implementation", "feature_planning"]
                },
                deactivation_conditions={
                    "user_behaviors": ["debugging"],
                    "error_context": True
                },
                fallback_sets=["general_building", "technical_implementation"]
            ),
            
            # AI/ML Development Patterns  
            PatternSet(
                set_id="ai_ml_research",
                name="AI/ML - Research & Development",
                description="Patterns for AI/ML research and model development",
                pattern_ids=["model_architecture_design", "data_pipeline_optimization", "experiment_tracking"],
                base_confidence_threshold=0.7,
                context_weight=1.0,
                activation_conditions={
                    "project_types": ["ai_ml", "data_science"],
                    "user_behaviors": ["experimenting", "learning", "building"],
                    "conversation_themes": ["technical_implementation", "performance_optimization"]
                },
                deactivation_conditions={},
                fallback_sets=["research_exploration", "technical_implementation"]
            ),
            
            # Debugging Patterns (Cross-Project)
            PatternSet(
                set_id="debugging_investigation",
                name="Debugging & Investigation",
                description="Patterns for debugging and problem investigation",
                pattern_ids=["error_analysis", "log_investigation", "stack_trace_analysis"],
                base_confidence_threshold=0.5,
                context_weight=1.2,  # Higher weight during debugging
                activation_conditions={
                    "user_behaviors": ["debugging"],
                    "conversation_themes": ["bug_investigation", "problem_solving"],
                    "error_context": True
                },
                deactivation_conditions={
                    "user_behaviors": ["building", "planning"]
                },
                fallback_sets=["problem_solving", "technical_implementation"]
            ),
            
            # Planning & Architecture Patterns
            PatternSet(
                set_id="planning_architecture",
                name="Planning & Architecture",
                description="Patterns for system design and planning",
                pattern_ids=["system_architecture", "requirement_analysis", "technology_selection"],
                base_confidence_threshold=0.6,
                context_weight=1.0,
                activation_conditions={
                    "user_behaviors": ["planning", "exploring"],
                    "conversation_themes": ["architectural_design", "feature_planning"],
                    "temporal_contexts": ["morning_fresh", "evening_reflective"]
                },
                deactivation_conditions={
                    "urgency_level": 0.8  # Deactivate during urgent situations
                },
                fallback_sets=["general_planning", "technical_implementation"]
            ),
            
            # Performance Optimization Patterns
            PatternSet(
                set_id="performance_optimization",
                name="Performance Optimization",
                description="Patterns for optimizing performance and efficiency",
                pattern_ids=["performance_monitoring", "bottleneck_analysis", "caching_strategies"],
                base_confidence_threshold=0.7,
                context_weight=1.0,
                activation_conditions={
                    "user_behaviors": ["optimizing"],
                    "conversation_themes": ["performance_optimization"],
                    "min_complexity": 0.6
                },
                deactivation_conditions={},
                fallback_sets=["technical_implementation"]
            ),
            
            # Collaborative Work Patterns
            PatternSet(
                set_id="collaborative_work",
                name="Collaborative Work",
                description="Patterns for team collaboration and code review",
                pattern_ids=["code_review_feedback", "team_communication", "documentation_standards"],
                base_confidence_threshold=0.6,
                context_weight=0.9,
                activation_conditions={
                    "user_behaviors": ["collaborating"],
                    "conversation_themes": ["code_review"],
                    "collaboration_mode": True,
                    "temporal_contexts": ["midday_productive", "afternoon_collaborative"]
                },
                deactivation_conditions={
                    "collaboration_mode": False
                },
                fallback_sets=["general_discussion", "technical_implementation"]
            ),
            
            # Learning & Exploration Patterns
            PatternSet(
                set_id="learning_exploration",
                name="Learning & Exploration",
                description="Patterns for learning new technologies and exploration",
                pattern_ids=["technology_learning", "concept_explanation", "tutorial_guidance"],
                base_confidence_threshold=0.5,
                context_weight=1.0,
                activation_conditions={
                    "user_behaviors": ["learning", "exploring"],
                    "conversation_themes": ["general_discussion"],
                    "temporal_contexts": ["weekend_exploratory", "evening_reflective"]
                },
                deactivation_conditions={
                    "urgency_level": 0.7
                },
                fallback_sets=["general_discussion"]
            ),
            
            # Late Night Creative Patterns
            PatternSet(
                set_id="late_night_creative",
                name="Late Night Creative",
                description="Patterns for creative and experimental work",
                pattern_ids=["creative_problem_solving", "experimental_approaches", "innovative_solutions"],
                base_confidence_threshold=0.4,  # Lower threshold for creative work
                context_weight=0.8,
                activation_conditions={
                    "temporal_contexts": ["late_night_creative"],
                    "user_behaviors": ["experimenting", "building"],
                    "min_session_duration": 120  # Long sessions
                },
                deactivation_conditions={
                    "temporal_contexts": ["morning_fresh", "midday_productive"]
                },
                fallback_sets=["experimenting", "general_building"]
            ),
            
            # General Fallback Patterns
            PatternSet(
                set_id="general_fallback",
                name="General Fallback",
                description="Default patterns when context is unclear",
                pattern_ids=["general_assistance", "context_clarification", "basic_support"],
                base_confidence_threshold=0.3,
                context_weight=0.5,
                activation_conditions={},  # Always available as fallback
                deactivation_conditions={},
                fallback_sets=[]
            )
        ]
        
        for pattern_set in default_sets:
            self.pattern_sets[pattern_set.set_id] = pattern_set
        
        self._save_pattern_sets()
        logger.info(f"🎯 Initialized {len(default_sets)} default contextual pattern sets")
    
    def analyze_current_context(self, message: str, command_history: List[str] = None, 
                              user_feedback: Dict = None) -> ContextualEnvironment:
        """Analyze current context from message and environment."""
        if command_history is None:
            command_history = []
        if user_feedback is None:
            user_feedback = {}
        
        # Determine project type
        project_type = self._detect_project_type(message)
        
        # Determine user behavior
        user_behavior = self._detect_user_behavior(message, command_history)
        
        # Determine conversation theme
        conversation_theme = self._detect_conversation_theme(message)
        
        # Determine temporal context
        temporal_context = self._determine_temporal_context()
        
        # Calculate session duration
        session_duration = (time.time() - self.session_start_time) / 60.0
        
        # Detect error context
        error_context = self._detect_error_context(message, command_history)
        
        # Estimate complexity level
        complexity_level = self._estimate_complexity_level(message, user_feedback)
        
        # Detect collaboration mode
        collaboration_mode = self._detect_collaboration_mode(message)
        
        # Estimate urgency level
        urgency_level = self._estimate_urgency_level(message, user_feedback)
        
        context = ContextualEnvironment(
            project_type=project_type,
            user_behavior=user_behavior,
            conversation_theme=conversation_theme,
            temporal_context=temporal_context,
            session_duration=session_duration,
            recent_commands=command_history[-10:],  # Last 10 commands
            error_context=error_context,
            complexity_level=complexity_level,
            collaboration_mode=collaboration_mode,
            urgency_level=urgency_level
        )
        
        # Save context history
        self._save_context_to_history(context, message)
        
        return context
    
    def activate_patterns_for_context(self, context: ContextualEnvironment) -> Dict[str, List[str]]:
        """Activate appropriate pattern sets for the given context."""
        self.current_context = context
        
        # Calculate match scores for all pattern sets
        set_scores = {}
        for set_id, pattern_set in self.pattern_sets.items():
            match_score = pattern_set.matches_context(context)
            if match_score > 0:
                set_scores[set_id] = match_score * pattern_set.context_weight
        
        # Sort by score and select top pattern sets
        sorted_sets = sorted(set_scores.items(), key=lambda x: x[1], reverse=True)
        
        # Activate top pattern sets (up to 5 sets to avoid overwhelming)
        new_active_sets = set()
        activated_patterns = []
        
        for set_id, score in sorted_sets[:5]:
            if score >= 0.3:  # Minimum activation threshold
                new_active_sets.add(set_id)
                activated_patterns.extend(self.pattern_sets[set_id].pattern_ids)
        
        # Always include general fallback if no specific sets activate
        if not new_active_sets and "general_fallback" in self.pattern_sets:
            new_active_sets.add("general_fallback")
            activated_patterns.extend(self.pattern_sets["general_fallback"].pattern_ids)
        
        # Determine what changed
        previously_active = self.active_pattern_sets.copy()
        activated_sets = new_active_sets - previously_active
        deactivated_sets = previously_active - new_active_sets
        
        # Update active sets
        self.active_pattern_sets = new_active_sets
        
        # Log activation event
        activation_event = PatternActivationEvent(
            timestamp=datetime.datetime.now().isoformat(),
            context=context,
            activated_sets=list(activated_sets),
            deactivated_sets=list(deactivated_sets),
            pattern_ids=activated_patterns,
            total_patterns_active=len(activated_patterns),
            activation_reason=f"Context match - top scores: {dict(sorted_sets[:3])}"
        )
        
        self._log_activation_event(activation_event)
        
        # Get confidence-filtered patterns if confidence system is available
        filtered_patterns = self._apply_confidence_filtering(activated_patterns, context)
        
        result = {
            "activated_sets": list(activated_sets),
            "deactivated_sets": list(deactivated_sets),
            "active_pattern_ids": filtered_patterns,
            "total_active_sets": len(new_active_sets),
            "context_scores": dict(sorted_sets[:5])
        }
        
        if activated_sets or deactivated_sets:
            logger.info(f"🎯 CONTEXT ACTIVATION: {len(activated_sets)} sets activated, {len(deactivated_sets)} deactivated")
            logger.info(f"   Active patterns: {len(filtered_patterns)} patterns from {len(new_active_sets)} sets")
        
        return result
    
    def _detect_project_type(self, message: str) -> ProjectType:
        """Detect project type from message content and environment."""
        message_lower = message.lower()
        
        # Use neural domain classifier if available
        try:
            from intelligence.neural_domain_classifier import get_neural_domain_classifier
            neural_classifier = get_neural_domain_classifier(self.memory_dir)
            analysis = neural_classifier.analyze_project_domain(".")
            
            # Map neural domain to project type
            domain_mapping = {
                "ai_ml": ProjectType.AI_ML,
                "web_development": ProjectType.WEB_DEVELOPMENT,
                "mobile_development": ProjectType.MOBILE_DEVELOPMENT,
                "data_science": ProjectType.DATA_SCIENCE,
                "devops": ProjectType.DEVOPS_INFRASTRUCTURE,
                "gaming": ProjectType.GAME_DEVELOPMENT,
                "blockchain": ProjectType.BLOCKCHAIN,
                "iot": ProjectType.IOT_EMBEDDED,
                "documentation": ProjectType.DOCUMENTATION
            }
            
            if analysis.primary_domain.value in domain_mapping:
                return domain_mapping[analysis.primary_domain.value]
                
        except Exception as e:
            logger.debug(f"Neural domain classification failed, using fallback: {e}")
        
        # Fallback to keyword-based detection
        if any(keyword in message_lower for keyword in ['react', 'vue', 'angular', 'frontend', 'backend', 'web', 'html', 'css']):
            return ProjectType.WEB_DEVELOPMENT
        elif any(keyword in message_lower for keyword in ['ml', 'ai', 'neural', 'model', 'tensorflow', 'pytorch', 'machine learning']):
            return ProjectType.AI_ML
        elif any(keyword in message_lower for keyword in ['android', 'ios', 'mobile', 'swift', 'kotlin', 'react native']):
            return ProjectType.MOBILE_DEVELOPMENT
        elif any(keyword in message_lower for keyword in ['pandas', 'numpy', 'data', 'analysis', 'visualization', 'jupyter']):
            return ProjectType.DATA_SCIENCE
        elif any(keyword in message_lower for keyword in ['docker', 'kubernetes', 'deploy', 'infrastructure', 'devops']):
            return ProjectType.DEVOPS_INFRASTRUCTURE
        elif any(keyword in message_lower for keyword in ['unity', 'unreal', 'game', 'graphics', 'physics']):
            return ProjectType.GAME_DEVELOPMENT
        elif any(keyword in message_lower for keyword in ['blockchain', 'ethereum', 'smart contract', 'web3', 'crypto']):
            return ProjectType.BLOCKCHAIN
        elif any(keyword in message_lower for keyword in ['arduino', 'raspberry pi', 'iot', 'embedded', 'hardware']):
            return ProjectType.IOT_EMBEDDED
        elif any(keyword in message_lower for keyword in ['research', 'paper', 'study', 'experiment']):
            return ProjectType.RESEARCH
        elif any(keyword in message_lower for keyword in ['docs', 'documentation', 'readme', 'guide', 'tutorial']):
            return ProjectType.DOCUMENTATION
        else:
            return ProjectType.GENERAL
    
    def _detect_user_behavior(self, message: str, command_history: List[str]) -> UserBehaviorContext:
        """Detect user behavior from message and command history."""
        message_lower = message.lower()
        
        # Check for debugging behavior
        if any(keyword in message_lower for keyword in ['debug', 'error', 'bug', 'fix', 'issue', 'problem', 'fails', 'broken']):
            return UserBehaviorContext.DEBUGGING
        
        # Check for building behavior
        if any(keyword in message_lower for keyword in ['create', 'build', 'implement', 'add', 'new', 'feature', 'develop']):
            return UserBehaviorContext.BUILDING
        
        # Check for optimizing behavior
        if any(keyword in message_lower for keyword in ['optimize', 'performance', 'faster', 'improve', 'refactor', 'efficiency']):
            return UserBehaviorContext.OPTIMIZING
        
        # Check for planning behavior
        if any(keyword in message_lower for keyword in ['plan', 'design', 'architecture', 'approach', 'strategy', 'structure']):
            return UserBehaviorContext.PLANNING
        
        # Check for learning behavior
        if any(keyword in message_lower for keyword in ['learn', 'understand', 'explain', 'how', 'what', 'why', 'tutorial']):
            return UserBehaviorContext.LEARNING
        
        # Check for collaboration behavior
        if any(keyword in message_lower for keyword in ['review', 'team', 'collaborate', 'share', 'discuss', 'feedback']):
            return UserBehaviorContext.COLLABORATING
        
        # Check for experimenting behavior
        if any(keyword in message_lower for keyword in ['try', 'test', 'experiment', 'prototype', 'poc', 'proof of concept']):
            return UserBehaviorContext.EXPERIMENTING
        
        # Check command history for patterns
        recent_commands = command_history[-5:] if command_history else []
        if any(cmd in ['search', 'recall', 'analyze'] for cmd in recent_commands):
            return UserBehaviorContext.EXPLORING
        
        # Default to exploring
        return UserBehaviorContext.EXPLORING
    
    def _detect_conversation_theme(self, message: str) -> ConversationTheme:
        """Detect conversation theme from message content."""
        message_lower = message.lower()
        
        if any(keyword in message_lower for keyword in ['implement', 'code', 'function', 'method', 'algorithm']):
            return ConversationTheme.TECHNICAL_IMPLEMENTATION
        elif any(keyword in message_lower for keyword in ['problem', 'solve', 'issue', 'challenge', 'solution']):
            return ConversationTheme.PROBLEM_SOLVING
        elif any(keyword in message_lower for keyword in ['architecture', 'design', 'structure', 'pattern', 'system']):
            return ConversationTheme.ARCHITECTURAL_DESIGN
        elif any(keyword in message_lower for keyword in ['review', 'feedback', 'critique', 'improve', 'quality']):
            return ConversationTheme.CODE_REVIEW
        elif any(keyword in message_lower for keyword in ['performance', 'speed', 'optimize', 'efficient', 'bottleneck']):
            return ConversationTheme.PERFORMANCE_OPTIMIZATION
        elif any(keyword in message_lower for keyword in ['bug', 'error', 'debug', 'investigate', 'trace']):
            return ConversationTheme.BUG_INVESTIGATION
        elif any(keyword in message_lower for keyword in ['feature', 'plan', 'requirement', 'spec', 'roadmap']):
            return ConversationTheme.FEATURE_PLANNING
        elif any(keyword in message_lower for keyword in ['user', 'ux', 'ui', 'interface', 'experience']):
            return ConversationTheme.USER_EXPERIENCE
        elif any(keyword in message_lower for keyword in ['security', 'auth', 'permission', 'vulnerability', 'safe']):
            return ConversationTheme.SECURITY_CONCERNS
        elif any(keyword in message_lower for keyword in ['deploy', 'production', 'release', 'environment', 'server']):
            return ConversationTheme.DEPLOYMENT_OPERATIONS
        else:
            return ConversationTheme.GENERAL_DISCUSSION
    
    def _determine_temporal_context(self) -> TemporalContext:
        """Determine temporal context based on current time."""
        now = datetime.datetime.now()
        hour = now.hour
        is_weekend = now.weekday() >= 5
        
        if is_weekend:
            return TemporalContext.WEEKEND_EXPLORATORY
        elif 22 <= hour or hour <= 6:
            return TemporalContext.LATE_NIGHT_CREATIVE
        elif 6 < hour <= 10:
            return TemporalContext.MORNING_FRESH
        elif 10 < hour <= 14:
            return TemporalContext.MIDDAY_PRODUCTIVE
        elif 14 < hour <= 18:
            return TemporalContext.AFTERNOON_COLLABORATIVE
        else:  # 18 < hour < 22
            return TemporalContext.EVENING_REFLECTIVE
    
    def _detect_error_context(self, message: str, command_history: List[str]) -> bool:
        """Detect if user is in an error/problem context."""
        message_lower = message.lower()
        
        error_indicators = ['error', 'fail', 'bug', 'issue', 'problem', 'broken', 'wrong', 'crash']
        return any(indicator in message_lower for indicator in error_indicators)
    
    def _estimate_complexity_level(self, message: str, user_feedback: Dict) -> float:
        """Estimate complexity level of current task."""
        message_lower = message.lower()
        
        # Base complexity on message length and technical terms
        base_complexity = min(1.0, len(message) / 500.0)
        
        # Increase for technical terms
        technical_terms = ['algorithm', 'architecture', 'optimization', 'performance', 'system', 'integration']
        tech_score = sum(1 for term in technical_terms if term in message_lower) / len(technical_terms)
        
        # Adjust based on user feedback
        feedback_complexity = user_feedback.get('complexity', 0.5)
        
        return (base_complexity + tech_score + feedback_complexity) / 3.0
    
    def _detect_collaboration_mode(self, message: str) -> bool:
        """Detect if user is in collaboration mode."""
        message_lower = message.lower()
        
        collaboration_indicators = ['team', 'we', 'us', 'together', 'collaborate', 'review', 'share']
        return any(indicator in message_lower for indicator in collaboration_indicators)
    
    def _estimate_urgency_level(self, message: str, user_feedback: Dict) -> float:
        """Estimate urgency level of current task."""
        message_lower = message.lower()
        
        urgency_indicators = ['urgent', 'asap', 'quickly', 'fast', 'deadline', 'emergency', 'critical']
        urgency_score = sum(1 for indicator in urgency_indicators if indicator in message_lower)
        
        # Normalize to 0-1
        base_urgency = min(1.0, urgency_score / 3.0)
        
        # Factor in user feedback
        feedback_urgency = user_feedback.get('urgency', 0.3)
        
        return (base_urgency + feedback_urgency) / 2.0
    
    def _apply_confidence_filtering(self, pattern_ids: List[str], context: ContextualEnvironment) -> List[str]:
        """Filter patterns based on confidence scores."""
        if not self.confidence_system:
            return pattern_ids
        
        try:
            # Get active patterns from confidence system
            active_patterns = self.confidence_system.get_active_patterns(min_confidence=0.3)
            active_pattern_ids = {pattern_id for pattern_id, _ in active_patterns}
            
            # Filter contextual patterns by confidence
            filtered_patterns = [pid for pid in pattern_ids if pid in active_pattern_ids]
            
            if not filtered_patterns:
                # If confidence filtering removes all patterns, use lower threshold
                lower_threshold_patterns = self.confidence_system.get_active_patterns(min_confidence=0.1)
                lower_active_ids = {pattern_id for pattern_id, _ in lower_threshold_patterns}
                filtered_patterns = [pid for pid in pattern_ids if pid in lower_active_ids]
            
            logger.debug(f"🎯 CONFIDENCE FILTER: {len(filtered_patterns)}/{len(pattern_ids)} patterns passed confidence filtering")
            return filtered_patterns
            
        except Exception as e:
            logger.debug(f"Confidence filtering failed, using all patterns: {e}")
            return pattern_ids
    
    def _save_context_to_history(self, context: ContextualEnvironment, message: str):
        """Save context to history for analysis."""
        try:
            context_entry = {
                "timestamp": datetime.datetime.now().isoformat(),
                "context": asdict(context),
                "message_preview": message[:100]
            }
            
            with open(self.context_history_file, 'a') as f:
                f.write(json.dumps(context_entry) + '\n')
        except Exception as e:
            logger.debug(f"Failed to save context history: {e}")
    
    def _log_activation_event(self, event: PatternActivationEvent):
        """Log pattern activation event."""
        try:
            with open(self.activation_log_file, 'a') as f:
                f.write(json.dumps(asdict(event)) + '\n')
        except Exception as e:
            logger.debug(f"Failed to log activation event: {e}")
    
    def get_activation_statistics(self) -> Dict:
        """Get statistics about pattern activation."""
        stats = {
            "total_pattern_sets": len(self.pattern_sets),
            "currently_active_sets": len(self.active_pattern_sets),
            "active_set_names": [self.pattern_sets[set_id].name for set_id in self.active_pattern_sets],
            "session_duration_minutes": (time.time() - self.session_start_time) / 60.0,
            "current_context": asdict(self.current_context) if self.current_context else None
        }
        
        # Add pattern set utilization
        set_utilization = {}
        for set_id, pattern_set in self.pattern_sets.items():
            set_utilization[set_id] = {
                "name": pattern_set.name,
                "pattern_count": len(pattern_set.pattern_ids),
                "base_threshold": pattern_set.base_confidence_threshold,
                "currently_active": set_id in self.active_pattern_sets
            }
        
        stats["pattern_set_utilization"] = set_utilization
        return stats
    
    def get_context_recommendations(self) -> List[str]:
        """Get recommendations for improving contextual activation."""
        recommendations = []
        
        if self.current_context:
            # Check if we have good pattern coverage for current context
            if len(self.active_pattern_sets) < 2:
                recommendations.append("Consider adding more diverse pattern sets for better context coverage")
            
            # Check if patterns are too general
            general_sets = [s for s in self.active_pattern_sets if "general" in s.lower()]
            if len(general_sets) > len(self.active_pattern_sets) / 2:
                recommendations.append("Context detection may be too generic - consider more specific patterns")
            
            # Check session duration
            if self.current_context.session_duration > 180:  # 3 hours
                recommendations.append("Long session detected - consider patterns for sustained work")
            
            # Check complexity vs patterns
            if self.current_context.complexity_level > 0.8 and len(self.active_pattern_sets) < 3:
                recommendations.append("High complexity task - consider activating more specialized pattern sets")
        
        if not recommendations:
            recommendations.append("Contextual pattern activation is working optimally")
        
        return recommendations


# Global singleton instance
_contextual_pattern_activation_instance = None

def get_contextual_pattern_activation(memory_dir: str) -> ContextualPatternActivation:
    """Get the contextual pattern activation system instance (singleton)."""
    global _contextual_pattern_activation_instance
    if _contextual_pattern_activation_instance is None:
        _contextual_pattern_activation_instance = ContextualPatternActivation(memory_dir)
    return _contextual_pattern_activation_instance


# Example usage and testing
if __name__ == "__main__":
    import tempfile
    
    # Test the contextual pattern activation system
    with tempfile.TemporaryDirectory() as temp_dir:
        activation_system = ContextualPatternActivation(temp_dir)
        
        print("🧪 Testing Contextual Pattern Activation System")
        
        # Test different contexts
        test_scenarios = [
            ("I need to debug this React component that's not rendering correctly", ["search", "analyze"]),
            ("Let's design the architecture for our new ML pipeline", ["learn", "journey"]),
            ("Can you help me optimize the performance of this database query?", ["unified_analysis"]),
            ("I want to explore different approaches to implement user authentication", ["search", "journey"])
        ]
        
        for message, commands in test_scenarios:
            print(f"\n📝 Scenario: {message[:50]}...")
            
            # Analyze context
            context = activation_system.analyze_current_context(message, commands)
            print(f"   Project Type: {context.project_type.value}")
            print(f"   User Behavior: {context.user_behavior.value}")
            print(f"   Theme: {context.conversation_theme.value}")
            print(f"   Temporal: {context.temporal_context.value}")
            
            # Activate patterns
            activation_result = activation_system.activate_patterns_for_context(context)
            print(f"   Active Sets: {len(activation_result['activated_sets'])}")
            print(f"   Active Patterns: {len(activation_result['active_pattern_ids'])}")
            
            # Show top activated sets
            if activation_result['context_scores']:
                top_set = max(activation_result['context_scores'].items(), key=lambda x: x[1])
                print(f"   Top Set: {top_set[0]} (score: {top_set[1]:.2f})")
        
        # Get overall statistics
        stats = activation_system.get_activation_statistics()
        print(f"\n📊 System Statistics:")
        print(f"   Total Pattern Sets: {stats['total_pattern_sets']}")
        print(f"   Currently Active: {stats['currently_active_sets']}")
        print(f"   Session Duration: {stats['session_duration_minutes']:.1f} minutes")
        
        # Get recommendations
        recommendations = activation_system.get_context_recommendations()
        print(f"\n💡 Recommendations:")
        for rec in recommendations:
            print(f"   - {rec}")