"""
Whale Bot Core - Enhanced whale tracking and following system

This module provides the core whale bot functionality with real-time detection,
intelligent analysis, and automated following capabilities.
"""

import asyncio
import logging
import numpy as np
from datetime import datetime
from typing import List, Optional, Dict, Callable, Any
from dataclasses import dataclass, field
import threading
import time

from ..core_types import Trade  # Import from base library
from ..monitor import HyperliquidMonitor  # Import from base library

logger = logging.getLogger(__name__)

# Optional imports that require sklearn
try:
    from ..core_types import (
        EnhancedTrade, WhaleBotConfig, WhaleDetectionCallback,
        PatternRecognitionCallback, MarketImpactCallback, FollowActionCallback,
        FollowRecommendation, WhaleTier, FollowAction, WhaleDetectionEvent
    )
except ImportError:
    EnhancedTrade = None
    WhaleBotConfig = None
    WhaleDetectionCallback = None
    PatternRecognitionCallback = None
    MarketImpactCallback = None
    FollowActionCallback = None
    FollowRecommendation = None
    WhaleTier = None
    FollowAction = None
    WhaleDetectionEvent = None

try:
    from ..analysis import (
        MarketImpactAnalyzer, ImpactCalculation, SizeClassifier, SizeClassification,
        VolumeAnomalyDetector, VolumeAnomaly, CorrelationEngine, CorrelationAnomaly, MarketRegime
    )
except ImportError:
    MarketImpactAnalyzer = None
    ImpactCalculation = None
    SizeClassifier = None
    SizeClassification = None
    VolumeAnomalyDetector = None
    VolumeAnomaly = None
    CorrelationEngine = None
    CorrelationAnomaly = None
    MarketRegime = None

# Phase 2 Intelligence Components
try:
    from ..intelligence import (
        SocialSentimentAnalyzer, SentimentScore, SentimentAnomaly,
        IntelligenceEnhancements, IntelligenceSignal, IntelligenceSummary, PredictiveInsight
    )
except ImportError:
    SocialSentimentAnalyzer = None
    SentimentScore = None
    SentimentAnomaly = None
    IntelligenceEnhancements = None
    IntelligenceSignal = None
    IntelligenceSummary = None
    PredictiveInsight = None

# Phase 3 Advanced Components
try:
    from ..tracking import (
        AdvancedWhaleBot, CrossChainTracker, AdvancedAlertSystem, MLModelManager
    )
    from ..intelligence import (
        ModelEnsemble, WhaleBehaviorMLModel, PricePredictionMLModel
    )
    from ..tracking import CrossChainAnalytics, CrossChainMonitor
    from ..integration import RealTimeDashboard
    from ..optimization import PortfolioOptimizer, RiskAnalyzer, WhaleOpportunityDetector
    from ..config import Phase3Config, get_phase3_config, validate_phase3_config
except ImportError:
    AdvancedWhaleBot = None
    CrossChainTracker = None
    AdvancedAlertSystem = None
    MLModelManager = None
    ModelEnsemble = None
    WhaleBehaviorMLModel = None
    PricePredictionMLModel = None
    CrossChainAnalytics = None
    CrossChainMonitor = None
    RealTimeDashboard = None
    PortfolioOptimizer = None
    RiskAnalyzer = None
    WhaleOpportunityDetector = None
    Phase3Config = None
    get_phase3_config = None
    validate_phase3_config = None

from ..core_types import Trade  # Import from base library
from ..monitor import HyperliquidMonitor  # Import from base library

logger = logging.getLogger(__name__)

@dataclass
class WhaleBotConfigEnhancement:
    """Enhanced configuration methods for whale bot"""
    
    # Additional whale bot specific settings
    enable_predictive_analysis: bool = True
    enable_ml_pattern_recognition: bool = False
    max_concurrent_whales: int = 10
    alert_cooldown_seconds: int = 30
    
    # Market analysis settings
    market_impact_threshold: float = 0.005  # 0.5%
    volume_spike_threshold: float = 2.0     # 2x average
    
    # Risk management
    max_daily_trades: int = 100
    max_position_size_ratio: float = 0.05   # 5% of portfolio

@dataclass
# WhaleDetectionEvent is now imported from types module
# from ..core_types import WhaleDetectionEvent  # Already imported above

class WhaleBotCore:
    """
    Core whale bot functionality with enhanced detection and analysis.
    
    This class integrates:
    - Real-time trade detection from Hyperliquid Monitor
    - Size classification and urgency assessment
    - Market impact analysis and prediction
    - Intelligent following recommendations
    - Pattern recognition and learning
    """
    
    def __init__(self, config: 'WhaleBotConfig', phase3_config: Optional['Phase3Config'] = None):
        """
        Initialize the whale bot core with Phase 1, 2, and 3 capabilities.
        
        Args:
            config: Base whale bot configuration
            phase3_config: Optional Phase 3 configuration for advanced features
        """
        # Initialize logger first
        self._logger = logger
        
        self.config = config
        self.phase3_config = phase3_config or get_phase3_config("default")
        
        # Validate Phase 3 configuration
        config_issues = validate_phase3_config(self.phase3_config)
        if config_issues:
            self._logger.warning(f"Phase 3 configuration issues: {config_issues}")
        
        self.monitor: Optional[HyperliquidMonitor] = None
        self.size_classifier = SizeClassifier(config)
        self.impact_analyzer = MarketImpactAnalyzer(config)
        
        # Phase 2 Intelligence Components
        self.volume_detector = VolumeAnomalyDetector(config)
        self.correlation_engine = CorrelationEngine(config)
        self.risk_manager = AdvancedRiskManager(config)
        self.sentiment_analyzer = SocialSentimentAnalyzer(config)
        self.intelligence = IntelligenceEnhancements(config)
        
        # Phase 3 Advanced Components
        self.advanced_whale_bot: Optional[AdvancedWhaleBot] = None
        self.ml_manager: Optional[MLModelManager] = None
        self.cross_chain_tracker: Optional[CrossChainTracker] = None
        self.dashboard: Optional[RealTimeDashboard] = None
        self.portfolio_optimizer: Optional[PortfolioOptimizer] = None
        
        # Initialize Phase 3 components if enabled
        if self.phase3_config.ml_model_enabled:
            self.ml_manager = MLModelManager(config)
            self._logger.info("Phase 3 ML Manager initialized")
        
        if self.phase3_config.cross_chain_enabled:
            self.cross_chain_tracker = CrossChainTracker(config)
            self._logger.info("Phase 3 Cross-Chain Tracker initialized")
        
        if self.phase3_config.dashboard_enabled:
            self.dashboard = RealTimeDashboard(
                AdvancedWhaleBot(config), 
                self.phase3_config.dashboard_port
            )
            self._logger.info(f"Phase 3 Dashboard initialized on port {self.phase3_config.dashboard_port}")
        
        if self.phase3_config.portfolio_optimization_enabled:
            self.portfolio_optimizer = PortfolioOptimizer(config)
            self._logger.info("Phase 3 Portfolio Optimizer initialized")
        
        # Callbacks for different event types
        self.detection_callbacks: List[WhaleDetectionCallback] = []
        self.pattern_callbacks: List[PatternRecognitionCallback] = []
        self.impact_callbacks: List[MarketImpactCallback] = []
        self.follow_callbacks: List[FollowActionCallback] = []
        
        # Phase 2 callbacks
        self.intelligence_callbacks: List[Callable[[IntelligenceSignal], None]] = []
        self.volume_anomaly_callbacks: List[Callable[[VolumeAnomaly], None]] = []
        self.correlation_alert_callbacks: List[Callable[[CorrelationAnomaly], None]] = []
        self.risk_alert_callbacks: List[Callable[[], None]] = []
        
        # Phase 3 callbacks
        self.ml_prediction_callbacks: List[Callable[[Dict], None]] = []
        self.cross_chain_alert_callbacks: List[Callable[[Dict], None]] = []
        self.portfolio_alert_callbacks: List[Callable[[Dict], None]] = []
        
        # State tracking
        self.is_running = False
        self.detection_count = 0
        self.follow_actions_taken = 0
        self.last_alert_time = datetime.min
        
        # Threading for async processing
        self.processing_lock = threading.RLock()
        self.pending_trades: List[Dict] = []
        self.processed_trade_hashes: set = set()
        
        # Performance metrics
        self.performance_stats = {
            "total_trades_processed": 0,
            "whales_detected": 0,
            "follow_recommendations": 0,
            "avg_processing_time_ms": 0.0,
            "last_detection_time": None,
            # Phase 3 metrics
            "ml_predictions_made": 0,
            "cross_chain_whales_tracked": 0,
            "portfolio_optimizations_run": 0,
            "dashboard_connections": 0
        }
        
    def add_detection_callback(self, callback: WhaleDetectionCallback):
        """Add callback for whale detection events"""
        self.detection_callbacks.append(callback)
        
    def add_pattern_callback(self, callback: PatternRecognitionCallback):
        """Add callback for pattern recognition events"""
        self.pattern_callbacks.append(callback)
        
    def add_impact_callback(self, callback: MarketImpactCallback):
        """Add callback for market impact analysis events"""
        self.impact_callbacks.append(callback)
        
    def add_follow_callback(self, callback: FollowActionCallback):
        """Add callback for follow action recommendations"""
        self.follow_callbacks.append(callback)
    
    def start_monitoring(self, addresses: List[str], db_path: Optional[str] = None):
        """
        Start whale monitoring for specified addresses.
        
        Args:
            addresses: List of wallet addresses to monitor
            db_path: Optional database path for trade storage
        """
        try:
            if self.is_running:
                self._logger.warning("Whale bot is already running")
                return
            
            self._logger.info(f"Starting whale bot monitoring for {len(addresses)} addresses")
            
            # Initialize base monitor
            def whale_trade_callback(trade: Trade):
                """Process trades from base monitor"""
                self._process_base_trade(trade)
            
            self.monitor = HyperliquidMonitor(
                addresses=addresses,
                db_path=db_path,
                callback=whale_trade_callback,
                track_pnl=True,
                silent=False
            )
            
            # Start monitoring in background
            monitor_thread = threading.Thread(
                target=self._start_monitor_thread,
                daemon=True
            )
            monitor_thread.start()
            
            self.is_running = True
            self._logger.info("Whale bot monitoring started successfully")
            
        except Exception as e:
            self._logger.error(f"Error starting whale bot monitoring: {e}")
            raise
    
    def _start_monitor_thread(self):
        """Start the base monitor in a separate thread"""
        try:
            if self.monitor:
                self.monitor.start()
        except Exception as e:
            self._logger.error(f"Monitor thread error: {e}")
            self.is_running = False
    
    def stop_monitoring(self):
        """Stop whale monitoring"""
        try:
            self._logger.info("Stopping whale bot monitoring")
            self.is_running = False
            
            if self.monitor:
                self.monitor.stop()
                self.monitor = None
                
            self._logger.info("Whale bot monitoring stopped")
            
        except Exception as e:
            self._logger.error(f"Error stopping whale bot: {e}")
    
    def _process_base_trade(self, base_trade: Trade):
        """
        Process a trade from the base monitor and enhance it for whale analysis.
        
        Args:
            base_trade: Trade from HyperliquidMonitor
        """
        start_time = time.time()
        
        try:
            # Skip if we've already processed this trade
            trade_hash = getattr(base_trade, 'tx_hash', f"{base_trade.timestamp}_{base_trade.coin}_{base_trade.size}")
            if trade_hash in self.processed_trade_hashes:
                return
                
            with self.processing_lock:
                self.processed_trade_hashes.add(trade_hash)
                
                # Keep processed hash set manageable
                if len(self.processed_trade_hashes) > 10000:
                    self.processed_trade_hashes = set(list(self.processed_trade_hashes)[-5000:])
            
            # Update performance stats
            self.performance_stats["total_trades_processed"] += 1
            
            # Convert to enhanced trade
            enhanced_trade = self._convert_to_enhanced_trade(base_trade)
            
            # Skip if trade is too small to be interesting
            if not self._should_process_trade(enhanced_trade):
                return
            
            # Classify trade size and urgency
            classification = self.size_classifier.classify_trade(enhanced_trade)
            enhanced_trade.whale_tier = classification.tier
            enhanced_trade.urgency = classification.urgency
            
            # Analyze market impact
            impact_calculation = self.impact_analyzer.analyze_market_impact(enhanced_trade)
            enhanced_trade.market_impact = impact_calculation.predicted_price_impact
            enhanced_trade.slippage = impact_calculation.slippage_estimate
            
            # Determine follow opportunity
            follow_recommendation = self._generate_follow_recommendation(enhanced_trade, classification, impact_calculation)
            enhanced_trade.follow_opportunity = follow_recommendation.action
            
            # Create detection event
            detection_event = WhaleDetectionEvent(
                trade=enhanced_trade,
                classification=classification,
                market_impact=impact_calculation
            )
            
            # Update stats
            self.detection_count += 1
            self.performance_stats["whales_detected"] += 1
            self.performance_stats["last_detection_time"] = datetime.now()
            
            # Process callbacks
            self._process_detection_callbacks(detection_event)
            self._process_impact_callbacks(impact_calculation)
            
            if follow_recommendation.action != "SKIP":
                self._process_follow_callbacks(follow_recommendation)
                self.follow_actions_taken += 1
                self.performance_stats["follow_recommendations"] += 1
            
            # Update performance metrics
            processing_time = (time.time() - start_time) * 1000  # Convert to ms
            self._update_performance_metrics(processing_time)
            
            self._logger.info(f"Processed whale trade: ${enhanced_trade.size_usd:,.0f} {enhanced_trade.coin} "
                            f"({classification.tier.value}) - Impact: {impact_calculation.predicted_price_impact:.3f}%")
            
        except Exception as e:
            self._logger.error(f"Error processing base trade: {e}", exc_info=True)
    
    def _convert_to_enhanced_trade(self, base_trade: Trade) -> EnhancedTrade:
        """Convert base trade to enhanced trade with whale-specific attributes"""
        # Calculate USD value if not available
        size_usd = getattr(base_trade, 'size_usd', None)
        if not size_usd:
            size_usd = base_trade.size * base_trade.price
        
        # Determine whale direction from trade data
        whale_direction = self._determine_whale_direction(base_trade)
        
        # Create enhanced trade
        return EnhancedTrade(
            timestamp=base_trade.timestamp,
            address=base_trade.address,
            coin=base_trade.coin,
            side=base_trade.side,
            whale_direction=whale_direction,
            size=base_trade.size,
            price=base_trade.price,
            size_usd=size_usd,
            whale_tier=WhaleTier.MINNOW,  # Will be updated by classifier
            urgency="MEDIUM",  # Will be updated by classifier
            trade_type=base_trade.trade_type,
            tx_hash=base_trade.tx_hash,
            fee=base_trade.fee,
            fee_token=base_trade.fee_token,
            start_position=base_trade.start_position,
            closed_pnl=base_trade.closed_pnl,
            order_id=base_trade.order_id,
            leverage=getattr(base_trade, 'leverage', None)
        )
    
    def _determine_whale_direction(self, base_trade: Trade) -> str:
        """
        Determine if whale is going long or short based on trade data.
        
        This is a simplified implementation - real implementation would need
        more sophisticated position analysis.
        """
        try:
            # Simple heuristic: if fee is charged, likely opening position
            # If closed_pnl is significant, likely closing position
            
            if base_trade.closed_pnl and abs(base_trade.closed_pnl) > 100:  # >$100 PnL
                # Significant PnL suggests position change
                if base_trade.side == "BUY":
                    return "LONG" if base_trade.closed_pnl > 0 else "SHORT"
                else:
                    return "SHORT" if base_trade.closed_pnl > 0 else "LONG"
            
            # Default assumption based on trade side
            return "LONG" if base_trade.side == "BUY" else "SHORT"
            
        except Exception as e:
            self._logger.debug(f"Error determining whale direction: {e}")
            return "UNKNOWN"
    
    def _should_process_trade(self, trade: EnhancedTrade) -> bool:
        """
        Determine if a trade should be processed for whale analysis.
        
        Filters out small trades and applies minimum thresholds.
        """
        try:
            # Minimum size threshold
            if trade.size_usd < self.config.min_whale_threshold:
                return False
            
            # Check if it's during active hours (optional filter)
            current_hour = datetime.now().hour
            # Consider trades during reasonable hours more important
            if current_hour < 2 or current_hour > 23:  # Very late/early hours
                if trade.size_usd < self.config.mega_whale_threshold:
                    return False
            
            # Rate limiting - avoid too many alerts
            time_since_last_alert = (datetime.now() - self.last_alert_time).total_seconds()
            if time_since_last_alert < self.config.alert_cooldown_seconds:
                # Allow only mega/whale tier trades during cooldown
                if trade.whale_tier not in [WhaleTier.WHALE, WhaleTier.MEGA_WHALE, WhaleTier.GIANT_WHALE]:
                    return False
            
            return True
            
        except Exception as e:
            self._logger.debug(f"Error in trade filtering: {e}")
            return True  # Default to processing if unsure
    
    def _generate_follow_recommendation(self, trade: EnhancedTrade, 
                                      classification: SizeClassification,
                                      impact: ImpactCalculation) -> FollowRecommendation:
        """
        Generate intelligent follow recommendation for a whale trade.
        
        Args:
            trade: Enhanced trade data
            classification: Size and urgency classification
            impact: Market impact analysis
            
        Returns:
            FollowRecommendation: Action recommendation with reasoning
        """
        try:
            # Determine base action
            action = FollowAction.FOLLOW
            
            reasoning_parts = []
            
            # Size-based decisions
            if trade.whale_tier == WhaleTier.MINNOW:
                action = FollowAction.SKIP
                reasoning_parts.append("Trade too small to follow")
            elif trade.whale_tier == WhaleTier.GIANT_WHALE:
                reasoning_parts.append("Large whale trade - high priority")
            
            # Risk-based decisions
            if impact.risk_score > 0.8:
                action = FollowAction.SKIP
                reasoning_parts.append("High risk trade")
            elif impact.risk_score > 0.6:
                action = FollowAction.HEDGE
                reasoning_parts.append("Moderate risk - consider hedging")
            
            # Market impact decisions
            if impact.predicted_price_impact > self.config.max_market_impact_threshold:
                action = FollowAction.SKIP
                reasoning_parts.append("Excessive market impact")
            elif impact.predicted_price_impact < 0.001:
                reasoning_parts.append("Low market impact - good opportunity")
            
            # Slippage decisions
            if impact.slippage_estimate > self.config.max_slippage_threshold:
                if action != FollowAction.SKIP:
                    action = FollowAction.HEDGE
                reasoning_parts.append("High slippage expected")
            
            # Urgency-based adjustments
            if classification.urgency_score > 0.8:
                reasoning_parts.append("High urgency - quick action needed")
            
            # Calculate optimal parameters if following
            if action == FollowAction.FOLLOW:
                # Entry delay based on timing window
                optimal_delay = impact.entry_timing_window or 30
                
                # Position size ratio based on risk and size
                base_ratio = self.config.follow_ratio
                if trade.whale_tier == WhaleTier.GIANT_WHALE:
                    base_ratio *= 1.2
                elif trade.whale_tier == WhaleTier.MEGA_WHALE:
                    base_ratio *= 1.1
                
                # Adjust for risk
                if impact.risk_score > 0.5:
                    base_ratio *= 0.8  # Reduce size for higher risk
                
                # Stop loss and take profit levels
                stop_loss_ratio = max(0.02, impact.predicted_price_impact * 2)  # 2% or 2x impact
                take_profit_levels = [
                    trade.price * (1 + impact.predicted_price_impact),
                    trade.price * (1 + impact.predicted_price_impact * 2)
                ]
                
            else:
                optimal_delay = 0
                base_ratio = 0.0
                stop_loss_ratio = 0.0
                take_profit_levels = []
            
            # Generate final reasoning
            if not reasoning_parts:
                reasoning_parts.append("Standard follow opportunity")
            
            recommendation = FollowRecommendation(
                action=action,
                confidence=classification.total_score * impact.calculation_confidence,
                reasoning="; ".join(reasoning_parts),
                optimal_entry_delay=optimal_delay,
                position_size_ratio=base_ratio,
                stop_loss_ratio=stop_loss_ratio,
                take_profit_levels=take_profit_levels
            )
            
            return recommendation
            
        except Exception as e:
            self._logger.error(f"Error generating follow recommendation: {e}")
            return FollowRecommendation(
                action=FollowAction.SKIP,
                confidence=0.1,
                reasoning="Error in recommendation generation",
                optimal_entry_delay=30,
                position_size_ratio=0.0,
                stop_loss_ratio=0.0,
                take_profit_levels=[]
            )
    
    def _process_detection_callbacks(self, event: WhaleDetectionEvent):
        """Process whale detection callbacks"""
        for callback in self.detection_callbacks:
            try:
                callback(event.trade)
            except Exception as e:
                self._logger.error(f"Error in detection callback: {e}")
    
    def _process_impact_callbacks(self, impact: ImpactCalculation):
        """Process market impact callbacks"""
        for callback in self.impact_callbacks:
            try:
                callback(impact)
            except Exception as e:
                self._logger.error(f"Error in impact callback: {e}")
    
    def _process_follow_callbacks(self, recommendation: FollowRecommendation):
        """Process follow action callbacks"""
        for callback in self.follow_callbacks:
            try:
                callback(recommendation)
            except Exception as e:
                self._logger.error(f"Error in follow callback: {e}")
    
    def _update_performance_metrics(self, processing_time_ms: float):
        """Update performance tracking metrics"""
        try:
            # Update average processing time
            current_avg = self.performance_stats["avg_processing_time_ms"]
            total_processed = self.performance_stats["total_trades_processed"]
            
            new_avg = ((current_avg * (total_processed - 1)) + processing_time_ms) / total_processed
            self.performance_stats["avg_processing_time_ms"] = new_avg
            
            # Check performance thresholds
            if processing_time_ms > self.config.max_response_time_ms:
                self._logger.warning(f"Slow processing time: {processing_time_ms:.1f}ms "
                                   f"(threshold: {self.config.max_response_time_ms}ms)")
            
        except Exception as e:
            self._logger.debug(f"Error updating performance metrics: {e}")
    
    def get_bot_statistics(self) -> Dict:
        """Get comprehensive bot statistics"""
        try:
            return {
                "status": "running" if self.is_running else "stopped",
                "performance": self.performance_stats.copy(),
                "configuration": {
                    "min_whale_threshold": f"${self.config.min_whale_threshold:,.0f}",
                    "max_response_time_ms": self.config.max_response_time_ms,
                    "follow_ratio": f"{self.config.follow_ratio:.1%}",
                    "max_position_risk": f"{self.config.max_position_risk:.1%}"
                },
                "size_classifier": self.size_classifier.get_classification_summary(),
                "impact_analyzer": self.impact_analyzer.get_impact_summary(),
                "active_callbacks": {
                    "detection": len(self.detection_callbacks),
                    "pattern": len(self.pattern_callbacks),
                    "impact": len(self.impact_callbacks),
                    "follow": len(self.follow_callbacks)
                }
            }
            
        except Exception as e:
            self._logger.error(f"Error generating bot statistics: {e}")
            return {"error": str(e)}
    
    # Phase 3 Advanced Methods
    
    async def start_advanced_features(self):
        """Start Phase 3 advanced features"""
        try:
            if self.phase3_config.dashboard_enabled and self.dashboard:
                # Start dashboard in background
                asyncio.create_task(self.dashboard.start_dashboard())
                self._logger.info("Phase 3 Dashboard started")
            
            if self.phase3_config.cross_chain_enabled and self.cross_chain_tracker:
                # Start cross-chain monitoring
                cross_chain_monitor = CrossChainMonitor(self.config)
                asyncio.create_task(cross_chain_monitor.start_monitoring())
                self._logger.info("Phase 3 Cross-chain monitoring started")
            
            # Initialize advanced whale bot
            if any([
                self.phase3_config.ml_model_enabled,
                self.phase3_config.cross_chain_enabled,
                self.phase3_config.portfolio_optimization_enabled
            ]):
                self.advanced_whale_bot = AdvancedWhaleBot(self.config)
                self._logger.info("Phase 3 Advanced Whale Bot initialized")
            
        except Exception as e:
            self._logger.error(f"Error starting Phase 3 features: {e}")
    
    async def stop_advanced_features(self):
        """Stop Phase 3 advanced features"""
        try:
            if self.dashboard:
                await self.dashboard.stop_dashboard()
                self._logger.info("Phase 3 Dashboard stopped")
                
        except Exception as e:
            self._logger.error(f"Error stopping Phase 3 features: {e}")
    
    async def get_phase3_status(self) -> Dict[str, Any]:
        """Get Phase 3 system status"""
        try:
            status = {
                "phase3_enabled": True,
                "configuration": {
                    "ml_enabled": self.phase3_config.ml_model_enabled,
                    "cross_chain_enabled": self.phase3_config.cross_chain_enabled,
                    "dashboard_enabled": self.phase3_config.dashboard_enabled,
                    "portfolio_optimization_enabled": self.phase3_config.portfolio_optimization_enabled
                },
                "components": {}
            }
            
            # ML Manager status
            if self.ml_manager:
                status["components"]["ml_manager"] = {
                    "active_models": len([m for m in self.ml_manager.models.values() if m.is_active]),
                    "model_performance": self.ml_manager.get_model_performance()
                }
            
            # Cross-chain tracker status
            if self.cross_chain_tracker:
                status["components"]["cross_chain_tracker"] = {
                    "whales_tracked": len(self.cross_chain_tracker.cross_chain_whales),
                    "monitoring_active": True  # Would check actual status
                }
            
            # Dashboard status
            if self.dashboard:
                status["components"]["dashboard"] = {
                    "port": self.phase3_config.dashboard_port,
                    "connections": self.performance_stats.get("dashboard_connections", 0)
                }
            
            # Portfolio optimizer status
            if self.portfolio_optimizer:
                status["components"]["portfolio_optimizer"] = {
                    "optimizations_run": self.performance_stats["portfolio_optimizations_run"],
                    "history_length": len(self.portfolio_optimizer.optimization_history)
                }
            
            return status
            
        except Exception as e:
            self._logger.error(f"Error getting Phase 3 status: {e}")
            return {"error": str(e)}
    
    async def run_ml_prediction(self, trade: EnhancedTrade) -> Optional[Dict[str, Any]]:
        """Run ML prediction for a trade"""
        if not self.ml_manager:
            return None
        
        try:
            market_data = await self._get_market_data(trade.coin)
            prediction = await self.ml_manager.predict_whale_behavior(trade.address, market_data)
            
            if prediction:
                self.performance_stats["ml_predictions_made"] += 1
                
                # Trigger callbacks
                for callback in self.ml_prediction_callbacks:
                    try:
                        callback(prediction)
                    except Exception as e:
                        self._logger.error(f"Error in ML prediction callback: {e}")
            
            return prediction
            
        except Exception as e:
            self._logger.error(f"Error in ML prediction: {e}")
            return None
    
    async def track_cross_chain_activity(self, trade: EnhancedTrade) -> Optional[Dict[str, Any]]:
        """Track whale activity across chains"""
        if not self.cross_chain_tracker:
            return None
        
        try:
            cross_chain_data = await self.cross_chain_tracker.track_whale_across_chains(
                trade.address, trade.coin, {"size_usd": trade.size_usd}
            )
            
            if cross_chain_data:
                self.performance_stats["cross_chain_whales_tracked"] += 1
                
                # Trigger callbacks
                for callback in self.cross_chain_alert_callbacks:
                    try:
                        callback(cross_chain_data)
                    except Exception as e:
                        self._logger.error(f"Error in cross-chain callback: {e}")
            
            return cross_chain_data
            
        except Exception as e:
            self._logger.error(f"Error in cross-chain tracking: {e}")
            return None
    
    async def optimize_portfolio(self) -> Optional[Dict[str, Any]]:
        """Run portfolio optimization"""
        if not self.portfolio_optimizer:
            return None
        
        try:
            # Get current positions (would integrate with actual portfolio)
            current_positions = await self._get_current_positions()
            market_data = await self._get_market_data("PORTFOLIO")
            whale_intelligence = await self._get_whale_intelligence()
            
            optimization_result = await self.portfolio_optimizer.optimize_portfolio(
                current_positions, market_data, whale_intelligence
            )
            
            if optimization_result:
                self.performance_stats["portfolio_optimizations_run"] += 1
                
                # Trigger callbacks
                for callback in self.portfolio_alert_callbacks:
                    try:
                        callback(optimization_result)
                    except Exception as e:
                        self._logger.error(f"Error in portfolio callback: {e}")
            
            return optimization_result
            
        except Exception as e:
            self._logger.error(f"Error in portfolio optimization: {e}")
            return None
    
    async def _get_market_data(self, asset: str) -> Dict[str, Any]:
        """Get market data for analysis (placeholder implementation)"""
        return {
            "price_change_1h": np.random.uniform(-0.05, 0.05),
            "price_change_4h": np.random.uniform(-0.10, 0.10),
            "current_volume": np.random.uniform(1000000, 10000000),
            "avg_volume": 5000000,
            "social_sentiment_score": np.random.uniform(-1, 1),
            "whale_inflow_24h": np.random.uniform(-1000000, 5000000)
        }
    
    async def _get_current_positions(self) -> List:
        """Get current portfolio positions (placeholder implementation)"""
        # This would integrate with actual portfolio management
        return []
    
    async def _get_whale_intelligence(self) -> Dict[str, Any]:
        """Get whale intelligence data (placeholder implementation)"""
        return {
            "recent_whale_trades": [],
            "whale_activity_level": "MEDIUM",
            "market_regime": "BULL_MARKET"
        }
    
    # Phase 3 Callback Management
    def add_ml_prediction_callback(self, callback: Callable[[Dict], None]):
        """Add callback for ML predictions"""
        self.ml_prediction_callbacks.append(callback)
    
    def add_cross_chain_alert_callback(self, callback: Callable[[Dict], None]):
        """Add callback for cross-chain alerts"""
        self.cross_chain_alert_callbacks.append(callback)
    
    def add_portfolio_alert_callback(self, callback: Callable[[Dict], None]):
        """Add callback for portfolio optimization alerts"""
        self.portfolio_alert_callbacks.append(callback)
    
    def reset_statistics(self):
        """Reset all bot statistics"""
        try:
            self.detection_count = 0
            self.follow_actions_taken = 0
            self.last_alert_time = datetime.min
            self.performance_stats = {
                "total_trades_processed": 0,
                "whales_detected": 0,
                "follow_recommendations": 0,
                "avg_processing_time_ms": 0.0,
                "last_detection_time": None,
                # Phase 3 metrics
                "ml_predictions_made": 0,
                "cross_chain_whales_tracked": 0,
                "portfolio_optimizations_run": 0,
                "dashboard_connections": 0
            }
            
            # Reset classifiers
            self.size_classifier.reset_history()
            
            self._logger.info("Bot statistics reset")
            
        except Exception as e:
            self._logger.error(f"Error resetting statistics: {e}")


class MonitorCore:
    """
    High-level monitoring core system
    Provides unified interface for all monitoring operations
    """
    
    def __init__(self, config: WhaleBotConfig):
        """
        Initialize monitor core
        
        Args:
            config: Configuration for the monitoring system
        """
        self.config = config
        self.whale_bot = WhaleBotCore(config)
        self._logger = logging.getLogger(__name__)
        logger.info("MonitorCore initialized")
    
    async def start_monitoring(self):
        """Start the monitoring system"""
        self._logger.info("Starting monitor core...")
        # Start the underlying whale bot
        await self.whale_bot.start()
    
    async def stop_monitoring(self):
        """Stop the monitoring system"""
        self._logger.info("Stopping monitor core...")
        # Stop the underlying whale bot
        await self.whale_bot.stop()
    
    def get_status(self) -> dict:
        """Get monitoring system status"""
        return {
            "status": "running" if hasattr(self, '_running') and self._running else "stopped",
            "config": self.config.__dict__,
            "whale_bot_status": getattr(self.whale_bot, 'is_running', False)
        }


def main():
    """Main entry point for whale bot CLI"""
    import argparse
    import sys
    import asyncio
    from typing import List
    
    # Setup argument parser
    parser = argparse.ArgumentParser(
        description="Hyperliquid Whale Bot - Advanced whale tracking and following",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  hyperliquid-whale-bot --addresses addr1 addr2 --config config.yaml
  hyperliquid-whale-bot --demo --aggressive-mode
        """
    )
    
    # Address options
    address_group = parser.add_mutually_exclusive_group(required=True)
    address_group.add_argument(
        '--address', '-a',
        help='Single Ethereum address to monitor'
    )
    address_group.add_argument(
        '--addresses', '-A',
        nargs='+',
        help='Multiple Ethereum addresses to monitor'
    )
    
    # Configuration options
    parser.add_argument(
        '--config', '-c',
        help='Configuration file path (YAML or JSON)'
    )
    
    parser.add_argument(
        '--demo',
        action='store_true',
        help='Run in demo mode (no real trading)'
    )
    
    parser.add_argument(
        '--aggressive-mode',
        action='store_true',
        help='Use aggressive whale following strategy'
    )
    
    parser.add_argument(
        '--conservative-mode',
        action='store_true',
        help='Use conservative whale following strategy (default)'
    )
    
    parser.add_argument(
        '--max-whales',
        type=int,
        default=5,
        help='Maximum number of whales to track simultaneously'
    )
    
    parser.add_argument(
        '--min-whale-size',
        type=float,
        default=1_000_000.0,
        help='Minimum whale trade size in USD'
    )
    
    # Logging options
    parser.add_argument(
        '--log-level',
        choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'],
        default='INFO',
        help='Set logging level'
    )
    
    parser.add_argument(
        '--silent', '-s',
        action='store_true',
        help='Run in silent mode (less logging)'
    )
    
    parser.add_argument(
        '--verbose', '-v',
        action='store_true',
        help='Verbose logging'
    )
    
    args = parser.parse_args()
    
    # Setup logging
    import logging
    if args.silent:
        logging.getLogger().setLevel(logging.WARNING)
    elif args.verbose:
        logging.getLogger().setLevel(logging.DEBUG)
    else:
        logging.getLogger().setLevel(getattr(logging, args.log_level))
    
    logger = logging.getLogger(__name__)
    
    # Prepare addresses list
    addresses: List[str] = []
    if args.address:
        addresses = [args.address]
    elif args.addresses:
        addresses = args.addresses
    
    # Validate addresses
    for addr in addresses:
        if len(addr) != 42 or not addr.startswith('0x'):
            logger.error(f"Invalid address format: {addr}")
            sys.exit(1)
    
    # Create configuration
    try:
        from ..config import get_conservative_config, get_aggressive_config
        
        if args.aggressive_mode:
            config = get_aggressive_config()
        else:
            config = get_conservative_config()
        
        # Override defaults with command line arguments
        config.max_whales = args.max_whales
        config.min_whale_threshold = args.min_whale_size
        config.dashboard = False  # Disable dashboard by default in CLI
        
    except ImportError:
        # Fallback to basic configuration
        logger.warning("Configuration module not available, using basic config")
        config = WhaleBotConfig(
            min_whale_threshold=args.min_whale_size,
            max_whales=args.max_whales,
            enable_real_time_alerts=True
        )
    
    logger.info("Initializing Hyperliquid Whale Bot...")
    logger.info(f"Mode: {'Aggressive' if args.aggressive_mode else 'Conservative'}")
    logger.info(f"Monitoring {len(addresses)} address(es)")
    logger.info(f"Minimum whale size: ${args.min_whale_size:,.2f}")
    
    if args.demo:
        logger.info("DEMO MODE: No real trading will occur")
    
    # Main async loop
    async def run_whale_bot():
        """Run the whale bot"""
        try:
            # Create and configure whale bot
            whale_bot = WhaleBotCore(config)
            
            # Add addresses to monitor
            for address in addresses:
                await whale_bot.add_whale_address(address)
            
            # Set up callbacks
            def on_whale_detected(event):
                logger.info(f"🐋 Whale Detected: {event.coin} ${event.analysis.estimated_value:,.2f}")
            
            def on_market_impact(analysis):
                logger.info(f"📊 Market Impact: {analysis.predicted_price_impact:.2f}%")
            
            whale_bot.whale_detection_callback = on_whale_detected
            whale_bot.market_impact_callback = on_market_impact
            
            logger.info("Starting whale bot...")
            
            # Start monitoring
            await whale_bot.start()
            
            # Run until interrupted
            try:
                while True:
                    await asyncio.sleep(1)
            except KeyboardInterrupt:
                logger.info("Shutting down whale bot...")
            finally:
                await whale_bot.stop()
                logger.info("Whale bot stopped")
                
        except Exception as e:
            logger.error(f"Whale bot error: {e}")
            sys.exit(1)
    
    # Run the async function
    try:
        asyncio.run(run_whale_bot())
    except KeyboardInterrupt:
        logger.info("Whale bot stopped by user")
    except Exception as e:
        logger.error(f"Fatal error: {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()