"""Sniper Bot for BLOT SDK."""

from dataclasses import dataclass, field
from typing import Optional, List, Union

from blot.bots.base import BaseBot


@dataclass
class SniperBot(BaseBot):
    """Sniper Bot - Catch new token launches instantly.
    
    The Sniper Bot monitors the Solana mempool for new token listings
    and automatically purchases tokens the moment liquidity is added.
    
    Example:
        ```python
        from blot import SniperBot
        
        bot = SniperBot(
            target="new",
            buy_amount=0.5,
            min_liquidity=10,
            take_profit=[2.0, 5.0, 10.0],
            stop_loss=0.5,
            check_honeypot=True,
        )
        ```
    
    Attributes:
        target: Token address to snipe, or "new" for all new tokens.
        buy_amount: Amount in SOL to buy with.
        min_liquidity: Minimum liquidity in SOL required.
        take_profit: List of profit multipliers to sell at.
        stop_loss: Stop loss multiplier (e.g., 0.5 = -50%).
        check_honeypot: Whether to check for honeypot contracts.
        check_rug: Whether to check for rug pull indicators.
        max_dev_holding: Maximum developer holding percentage.
        dex: DEX to monitor ('raydium', 'orca', 'jupiter', 'meteora', 'pump.fun').
    """
    
    # Target settings
    target: Union[str, List[str]] = "new"
    dex: str = "raydium"
    
    # Buy settings
    buy_amount: float = 0.5  # SOL
    min_liquidity: float = 10.0  # SOL
    slippage: float = 1.0  # percent
    
    # Auto-sell settings
    take_profit: List[float] = field(default_factory=lambda: [2.0, 5.0, 10.0])
    stop_loss: float = 0.5
    
    # Safety checks
    check_honeypot: bool = True
    check_rug: bool = True
    max_dev_holding: Optional[float] = 10.0  # percent
    min_holders: Optional[int] = None
    
    # AI settings
    ai_filter: bool = False
    ai_confidence_threshold: float = 0.7
    
    def validate(self) -> bool:
        """Validate bot configuration."""
        if self.buy_amount <= 0:
            raise ValueError("buy_amount must be positive")
        if self.min_liquidity < 0:
            raise ValueError("min_liquidity must be non-negative")
        if self.slippage < 0 or self.slippage > 100:
            raise ValueError("slippage must be between 0 and 100")
        if self.stop_loss < 0 or self.stop_loss > 1:
            raise ValueError("stop_loss must be between 0 and 1")
        if not self.take_profit:
            raise ValueError("take_profit must have at least one level")
        if self.dex not in ["raydium", "orca", "jupiter", "meteora", "pump.fun"]:
            raise ValueError(f"Invalid DEX: {self.dex}")
        return True

