"""
Whale Bot Types - Custom data types for whale tracking operations

This module defines specialized data structures and enums for whale bot functionality,
enhancing the base types from the main library.
"""

from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional, Dict, List, Union, Literal, Callable, Any
from enum import Enum

# Import callback types from callback module
from .callback_types import (
    WhaleDetectionCallback,
    PatternRecognitionCallback, 
    MarketImpactCallback,
    FollowActionCallback
)

# Re-export Trade and WhaleAlert from monitor_types for compatibility
from ..monitor_types import Trade as BaseTrade, WhaleAlert

# Export as Trade for compatibility
Trade = BaseTrade

# Enhanced trade types for whale bot
WhaleDirection = Literal["LONG", "SHORT", "UNKNOWN"]
TradeUrgency = Literal["LOW", "MEDIUM", "HIGH", "CRITICAL"]
FollowAction = Literal["FOLLOW", "SKIP", "HEDGE", "CONTRARY"]
PatternType = Literal["accumulation", "distribution", "manipulation", "momentum", "mean_reversion"]

class WhaleTier(Enum):
    """Classification tiers for whale trades based on size"""
    MINNOW = "minnow"          # < $100K
    DOLPHIN = "dolphin"        # $100K - $1M
    WHALE = "whale"            # $1M - $5M  
    MEGA_WHALE = "mega_whale"  # $5M - $10M
    GIANT_WHALE = "giant_whale" # $10M+
    
    @classmethod
    def from_size(cls, size_usd: float) -> 'WhaleTier':
        """Determine whale tier based on trade size in USD"""
        if size_usd < 100_000:
            return cls.MINNOW
        elif size_usd < 1_000_000:
            return cls.DOLPHIN
        elif size_usd < 5_000_000:
            return cls.WHALE
        elif size_usd < 10_000_000:
            return cls.MEGA_WHALE
        else:
            return cls.GIANT_WHALE

@dataclass
class EnhancedTrade:
    """Enhanced trade information with whale bot specific features"""
    timestamp: datetime
    address: str
    coin: str
    side: str  # BUY/SELL from base library
    whale_direction: WhaleDirection  # LONG/SHORT/UNKNOWN
    size: float
    price: float
    size_usd: float  # Calculated USD value
    whale_tier: WhaleTier
    urgency: TradeUrgency
    leverage: Optional[float] = None
    position_after: Optional[float] = None  # Position size after this trade
    market_impact: Optional[float] = None  # Predicted/calculated market impact
    slippage: Optional[float] = None  # Expected slippage
    follow_opportunity: Optional[FollowAction] = None
    
    # Original trade attributes from base library
    trade_type: str = "FILL"
    tx_hash: Optional[str] = None
    fee: Optional[float] = None
    fee_token: Optional[str] = None
    start_position: Optional[float] = None
    closed_pnl: Optional[float] = None
    order_id: Optional[int] = None
    
    def __post_init__(self):
        """Validate and enhance trade data after initialization"""
        if not self.whale_direction in ("LONG", "SHORT", "UNKNOWN"):
            raise ValueError(f"Invalid whale_direction: {self.whale_direction}")
        
        if self.size_usd <= 0:
            self.size_usd = self.size * self.price
        
        # Auto-classify tier if not set
        if not isinstance(self.whale_tier, WhaleTier):
            self.whale_tier = WhaleTier.from_size(self.size_usd)
    
    def is_tradeable(self) -> bool:
        """Check if this trade is suitable for following"""
        return (self.whale_tier in [WhaleTier.WHALE, WhaleTier.MEGA_WHALE, WhaleTier.GIANT_WHALE] 
                and self.whale_direction != "UNKNOWN"
                and self.size_usd >= 100_000)

@dataclass  
class MarketImpact:
    """Market impact analysis for a whale trade"""
    predicted_impact: float  # % price impact predicted
    slippage_estimate: float  # % slippage estimate
    depth_analysis: Dict[str, float]  # Depth at various levels
    optimal_follow_size: Optional[float] = None  # Optimal position size for following
    timing_window: Optional[int] = None  # Window in seconds for optimal entry
    
@dataclass
class WhalePattern:
    """Identified pattern in whale behavior"""
    pattern_type: str  # "accumulation", "distribution", "manipulation", etc.
    confidence: float  # 0.0 to 1.0
    historical_examples: List[EnhancedTrade]
    predicted_duration: Optional[int] = None  # Duration in minutes
    strength: Optional[float] = None  # Pattern strength 0.0 to 1.0

@dataclass
class FollowRecommendation:
    """Recommendation for following a whale trade"""
    action: FollowAction
    confidence: float
    reasoning: str
    optimal_entry_delay: int  # Seconds to wait before entering
    position_size_ratio: float  # Ratio of whale size to use (0.0 to 1.0)
    stop_loss_ratio: float  # Stop loss as ratio of entry price
    take_profit_levels: List[float]  # TP levels as price values

# Configuration types
@dataclass
class WhaleBotConfig:
    """Configuration for whale bot operations"""
    # Size thresholds (USD)
    min_whale_threshold: float = 1_000_000  # $1M minimum to consider
    mega_whale_threshold: float = 5_000_000  # $5M for mega alerts
    giant_whale_threshold: float = 10_000_000  # $10M for giant alerts
    
    # Speed requirements
    max_response_time_ms: int = 500  # Maximum response time in milliseconds
    processing_batch_size: int = 50  # Number of trades to process in batch
    
    # Follow parameters  
    follow_ratio: float = 0.1  # Follow with 10% of whale size by default
    max_follow_ratio: float = 0.5  # Never follow with more than 50% of whale size
    leverage_cap: float = 10.0  # Maximum leverage for following
    
    # Risk management
    max_position_risk: float = 0.02  # Max 2% of portfolio per trade
    max_daily_exposure: float = 0.10  # Max 10% of portfolio exposure per day
    min_profit_threshold: float = 0.005  # Min 0.5% profit before considering follow
    
    # Market impact thresholds
    max_slippage_threshold: float = 0.01  # Max 1% slippage acceptable
    max_market_impact_threshold: float = 0.005  # Max 0.5% market impact
    
    # Alert settings
    enable_real_time_alerts: bool = True
    enable_pattern_alerts: bool = True
    alert_cooldown_seconds: int = 30  # Cool down between alerts
    
    # Pattern recognition settings
    pattern_confidence_threshold: float = 0.7  # Minimum confidence for pattern detection
    min_pattern_examples: int = 3  # Minimum historical examples for pattern
    
    # Performance optimization
    enable_async_processing: bool = True
    max_concurrent_trades: int = 10
    cache_market_data_seconds: int = 5  # Cache market data for this duration
    
    # Dashboard settings
    dashboard: bool = False  # Enable web dashboard
    dashboard_port: int = 8080  # Dashboard port

@dataclass
class WhaleDetectionEvent:
    """Event data for whale trade detection"""
    trade: EnhancedTrade
    classification: str = "UNKNOWN"  # Size classification
    market_impact: Optional[float] = None  # Market impact percentage
    detection_time: datetime = field(default_factory=datetime.now)
    
    def to_dict(self) -> Dict:
        """Convert event to dictionary for logging/notifications"""
        return {
            "timestamp": self.detection_time.isoformat(),
            "coin": self.trade.coin,
            "size_usd": self.trade.size_usd,
            "tier": self.trade.whale_tier.value if self.trade.whale_tier else "unknown",
            "direction": self.trade.whale_direction,
            "urgency": self.trade.urgency,
            "predicted_impact": self.market_impact,
        }

@dataclass
class MarketImpactAnalysis:
    """Market impact analysis for whale trades"""
    predicted_price_impact: float
    slippage_estimate: float
    risk_score: float
    optimal_follow_size: Optional[float] = None

@dataclass
class PredictionResult:
    """Result of ML prediction"""
    prediction: str
    confidence: float
    model_version: str
    features_used: List[str]

@dataclass
class RiskAssessment:
    """Risk assessment for trade decisions"""
    risk_level: Literal["LOW", "MEDIUM", "HIGH", "CRITICAL"]
    risk_factors: List[str]
    recommended_action: FollowAction
    risk_score: float


class BaseType:
    """
    Base type class for all whale bot data types
    Provides common functionality for all data types
    """
    
    def __init__(self, data: Optional[Dict] = None):
        """
        Initialize base type
        
        Args:
            data: Optional dictionary to initialize from
        """
        self.data = data or {}
        self._created_at = datetime.now()
    
    def to_dict(self) -> Dict:
        """Convert to dictionary representation"""
        result = {}
        for key, value in self.__dict__.items():
            if not key.startswith('_'):
                result[key] = value
        return result
    
    def from_dict(self, data: Dict):
        """Initialize from dictionary"""
        for key, value in data.items():
            if hasattr(self, key):
                setattr(self, key, value)
        return self
    
    def validate(self) -> bool:
        """Validate the data type"""
        # Base implementation - always returns True
        return True
    
    def __repr__(self) -> str:
        return f"{self.__class__.__name__}({self.to_dict()})"