import logging
import os
import sys
import time
import platform
import traceback
from datetime import datetime
from pathlib import Path
from typing import Optional, Dict, Any, Union


# ======== ANSI Color Codes for Terminal Output ========
# Check if we're on Windows and if colorama is available
_USE_COLORS = True
try:
    # Windows requires the colorama library for ANSI colors
    if platform.system() == "Windows":
        import colorama
        colorama.init(autoreset=True)
except ImportError:
    # If colorama isn't available on Windows, disable colors
    if platform.system() == "Windows":
        _USE_COLORS = False


# Color definitions
class Colors:
    # Basic colors
    BLACK = "\033[30m" if _USE_COLORS else ""
    RED = "\033[31m" if _USE_COLORS else ""
    GREEN = "\033[32m" if _USE_COLORS else "" 
    YELLOW = "\033[33m" if _USE_COLORS else ""
    BLUE = "\033[34m" if _USE_COLORS else ""
    MAGENTA = "\033[35m" if _USE_COLORS else ""
    CYAN = "\033[36m" if _USE_COLORS else ""
    WHITE = "\033[37m" if _USE_COLORS else ""
    
    # Bright variants
    BRIGHT_RED = "\033[91m" if _USE_COLORS else ""
    BRIGHT_GREEN = "\033[92m" if _USE_COLORS else ""
    BRIGHT_YELLOW = "\033[93m" if _USE_COLORS else ""
    BRIGHT_BLUE = "\033[94m" if _USE_COLORS else ""
    BRIGHT_MAGENTA = "\033[95m" if _USE_COLORS else ""
    BRIGHT_CYAN = "\033[96m" if _USE_COLORS else ""
    BRIGHT_WHITE = "\033[97m" if _USE_COLORS else ""
    
    # Background colors
    BG_RED = "\033[41m" if _USE_COLORS else ""
    BG_GREEN = "\033[42m" if _USE_COLORS else ""
    BG_YELLOW = "\033[43m" if _USE_COLORS else ""
    BG_BLUE = "\033[44m" if _USE_COLORS else ""
    BG_MAGENTA = "\033[45m" if _USE_COLORS else ""
    BG_CYAN = "\033[46m" if _USE_COLORS else ""
    BG_WHITE = "\033[47m" if _USE_COLORS else ""
    
    # Styles
    BOLD = "\033[1m" if _USE_COLORS else ""
    UNDERLINE = "\033[4m" if _USE_COLORS else ""
    ITALIC = "\033[3m" if _USE_COLORS else ""
    
    # Reset
    RESET = "\033[0m" if _USE_COLORS else ""
    
    # Special trading log colors
    SUCCESS = BRIGHT_GREEN
    PROFIT = BRIGHT_GREEN
    LOSS = BRIGHT_RED
    WARNING = BRIGHT_YELLOW
    ERROR = BRIGHT_RED
    CRITICAL = BG_RED + BRIGHT_WHITE
    TRADE = BRIGHT_CYAN
    INFO = BRIGHT_WHITE
    DEBUG = BRIGHT_BLUE


# ======== Custom Log Levels for Trading Operations ========
# Define custom log levels
TRACE = 5  # Very detailed debugging
NETWORK = 15  # Network operations
SUCCESS = 25  # Successful operations
TRADE = 26  # Trade-related info
PROFIT = 27  # Profit reports
RATE_LIMIT = 28  # Rate limit warnings
RPC = 29  # RPC-related events


# Register custom log levels with logging
logging.addLevelName(TRACE, "TRACE")
logging.addLevelName(NETWORK, "NETWORK")
logging.addLevelName(SUCCESS, "SUCCESS")
logging.addLevelName(TRADE, "TRADE")
logging.addLevelName(PROFIT, "PROFIT")
logging.addLevelName(RATE_LIMIT, "RATE_LIMIT")
logging.addLevelName(RPC, "RPC")


# ======== Custom Formatter with Colors ========
class ColoredFormatter(logging.Formatter):
    """Custom formatter with colored output based on log level"""
    
    # Map log levels to colors
    COLORS = {
        TRACE: Colors.BRIGHT_BLUE,
        logging.DEBUG: Colors.BLUE,
        NETWORK: Colors.CYAN,
        logging.INFO: Colors.BRIGHT_WHITE,
        SUCCESS: Colors.BRIGHT_GREEN,
        TRADE: Colors.BRIGHT_CYAN,
        PROFIT: Colors.SUCCESS,
        RATE_LIMIT: Colors.BRIGHT_YELLOW,
        RPC: Colors.MAGENTA,
        logging.WARNING: Colors.WARNING,
        logging.ERROR: Colors.ERROR,
        logging.CRITICAL: Colors.CRITICAL
    }
    
    # Map log levels to prefixes
    PREFIXES = {
        TRACE: "🔍",
        logging.DEBUG: "🔧",
        NETWORK: "🌐",
        logging.INFO: "ℹ️ ",
        SUCCESS: "✅",
        TRADE: "🚀",
        PROFIT: "💰",
        RATE_LIMIT: "⏱️ ",
        RPC: "📡",
        logging.WARNING: "⚠️ ",
        logging.ERROR: "❌",
        logging.CRITICAL: "🔥"
    }
    
    def __init__(self, fmt=None, datefmt=None, style='%', use_colors=True):
        super().__init__(fmt, datefmt, style)
        self.use_colors = use_colors and _USE_COLORS
    
    def format(self, record):
        # Save original format
        orig_format = self._style._fmt
        
        # Add color based on level if enabled
        if self.use_colors:
            color = self.COLORS.get(record.levelno, Colors.WHITE)
            prefix = self.PREFIXES.get(record.levelno, "")
            
            # Modify the format to include color
            self._style._fmt = f"{color}{prefix} {orig_format}{Colors.RESET}"
        
        # Format the record
        result = super().format(record)
        
        # Restore original format
        self._style._fmt = orig_format
        
        return result


# ======== SolanaLogger Class ========
class SolanaLogger:
    """Enhanced logger for Solana trading operations with colored output"""
    
    def __init__(self, name="solana_trading", level=logging.INFO):
        """Initialize logger with console and file handlers
        
        Args:
            name: Logger name
            level: Default logging level
        """
        self.logger = logging.getLogger(name)
        self.logger.setLevel(level)
        self.logger.propagate = False
        
        # Clear any existing handlers
        if self.logger.handlers:
            self.logger.handlers.clear()
        
        # Create log directory if it doesn't exist
        log_dir = Path("logs")
        if not log_dir.exists():
            log_dir.mkdir(parents=True, exist_ok=True)
        
        # Generate timestamp for log file
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        log_file = log_dir / f"{name}_{timestamp}.log"
        
        # Console handler with colors
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setLevel(level)
        
        console_format = ColoredFormatter(
            fmt='%(asctime)s | %(levelname)-10s | %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )
        console_handler.setFormatter(console_format)
        
        # File handler with more detailed info but no colors
        file_handler = logging.FileHandler(log_file, encoding='utf-8')
        file_handler.setLevel(min(level, logging.DEBUG))  # Always log debug+ to file
        
        file_format = logging.Formatter(
            fmt='%(asctime)s | %(levelname)-10s | %(filename)s:%(lineno)d | %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )
        file_handler.setFormatter(file_format)
        
        # Add handlers to logger
        self.logger.addHandler(console_handler)
        self.logger.addHandler(file_handler)
        
        # Store handlers for separate message handling
        self.console_handler = console_handler
        self.file_handler = file_handler
        
        # Save log path for reference
        self.log_file = log_file
        
        # Log the startup
        self.info(f"Solana Trading Logger initialized: {name}")
        self.info(f"Log file: {log_file}")


    # Standard logging methods
    def trace(self, message, *args, **kwargs):
        """Log trace message (very detailed debug info)"""
        self.logger.log(TRACE, message, *args, **kwargs)
    
    def debug(self, message, *args, **kwargs):
        """Log debug message"""
        self.logger.debug(message, *args, **kwargs)
    
    def network(self, message, *args, **kwargs):
        """Log network message"""
        self.logger.log(NETWORK, message, *args, **kwargs)
    
    def info(self, message, *args, **kwargs):
        """Log info message"""
        self.logger.info(message, *args, **kwargs)
    
    def success(self, message, *args, **kwargs):
        """Log success message"""
        self.logger.log(SUCCESS, message, *args, **kwargs)
    
    def warning(self, message, *args, **kwargs):
        """Log warning message"""
        self.logger.warning(message, *args, **kwargs)
    
    def error(self, message, *args, **kwargs):
        """Log error message"""
        self.logger.error(message, *args, **kwargs)
    
    def critical(self, message, *args, **kwargs):
        """Log critical message"""
        self.logger.critical(message, *args, **kwargs)
    
    # Trading-specific log methods
    def trade(self, message, *args, **kwargs):
        """Log trade execution message"""
        self.logger.log(TRADE, message, *args, **kwargs)
    
    def profit(self, amount: float, token="SOL", **kwargs):
        """Log profit with amount
        
        Args:
            amount: Profit amount (positive or negative)
            token: Token symbol (default: SOL)
        """
        if amount > 0:
            self.logger.log(PROFIT, f"Profit: +{amount:.6f} {token}", **kwargs)
        else:
            # Use error color for losses
            self.logger.log(PROFIT, f"Loss: {amount:.6f} {token}", **kwargs)
    
    def rate_limit(self, message, *args, **kwargs):
        """Log rate limit warning"""
        self.logger.log(RATE_LIMIT, message, *args, **kwargs)
        
    def rpc(self, message, *args, **kwargs):
        """Log RPC related message"""
        self.logger.log(RPC, message, *args, **kwargs)
    
    # Special methods for trades with visual indicators
    def trade_start(self, trade_type, amount, token="SOL"):
        """Log the start of a trade with visual indicator"""
        self.trade(f"▶️ Starting {trade_type} trade: {amount:.6f} {token}")
    
    def trade_complete(self, trade_type, amount, token="SOL", tx_hash=None):
        """Log successful trade completion with visual indicator"""
        msg = f"✅ Completed {trade_type} trade: {amount:.6f} {token}"
        if tx_hash:
            msg += f" | TX: {tx_hash}"
        self.trade(msg)
    
    def trade_failed(self, trade_type, reason=None, tx_hash=None):
        """Log failed trade with visual indicator"""
        msg = f"❌ Failed {trade_type} trade"
        if reason:
            msg += f": {reason}"
        if tx_hash:
            msg += f" | TX: {tx_hash}"
        self.error(msg)
    
    # Utility methods
    def log_exception(self, exc_info=True, level=logging.ERROR, stack_info=False):
        """Log the current exception with traceback
        
        Args:
            exc_info: Whether to include exception info
            level: Logging level
            stack_info: Whether to include stack info
        """
        self.logger.log(level, "Exception occurred", exc_info=exc_info, stack_info=stack_info)
    
    def section(self, title, char="=", width=80):
        """Create a section header in the log
        
        Args:
            title: Section title
            char: Character to use for the divider
            width: Width of the divider
        """
        divider = char * width
        spacing = char * 3
        self.info(f"\n{divider}\n{spacing} {title} {spacing}\n{divider}")
    
    def progress(self, message, current, total):
        """Log a progress message with percentage
        
        Args:
            message: Progress message
            current: Current progress value
            total: Total progress value
        """
        percent = min(100, int(100 * current / max(1, total)))
        self.info(f"{message}: {current}/{total} ({percent}%)")
    
    def timed(self, func):
        """Decorator to log function execution time
        
        Args:
            func: Function to time
        
        Returns:
            Wrapped function with timing
        """
        def wrapper(*args, **kwargs):
            start_time = time.time()
            self.debug(f"Starting {func.__name__}")
            try:
                result = func(*args, **kwargs)
                elapsed = time.time() - start_time
                self.debug(f"Completed {func.__name__} in {elapsed:.3f}s")
                return result
            except Exception as e:
                elapsed = time.time() - start_time
                self.error(f"Failed {func.__name__} after {elapsed:.3f}s: {e}")
                raise
        return wrapper
    
    def status_update(self, balance=None, trades=None, profit=None):
        """Log a status update with trading stats
        
        Args:
            balance: Current balance
            trades: Number of trades executed
            profit: Total profit
        """
        parts = []
        if balance is not None:
            parts.append(f"Balance: {balance:.6f} SOL")
        if trades is not None:
            parts.append(f"Trades: {trades}")
        if profit is not None:
            profit_str = f"+{profit:.6f}" if profit >= 0 else f"{profit:.6f}"
            parts.append(f"Profit: {profit_str} SOL")
            
        if parts:
            self.info(f"Status Update: {' | '.join(parts)}")

    def print_stats(self, stats: Dict[str, Any], title="Trading Statistics"):
        """Format and print statistics dictionary
        
        Args:
            stats: Dictionary of statistics
            title: Title for the stats section
        """
        self.section(title)
        
        # Format each stat and log it
        for key, value in stats.items():
            # Format the key nicely
            nice_key = key.replace("_", " ").title()
            
            # Format the value based on type
            if isinstance(value, float):
                formatted = f"{value:.6f}"
            elif isinstance(value, (list, tuple)) and all(isinstance(x, float) for x in value):
                formatted = ", ".join([f"{x:.6f}" for x in value])
            else:
                formatted = str(value)
                
            self.info(f"{nice_key}: {formatted}")
    
    def change_level(self, level):
        """Change the logging level
        
        Args:
            level: New logging level
        """
        self.logger.setLevel(level)
        self.console_handler.setLevel(level)
        self.info(f"Logging level changed to {logging.getLevelName(level)}")


# Create the default logger instance
logger = SolanaLogger(
    name="trade_engine",
    level=getattr(logging, os.environ.get("LOG_LEVEL", "INFO"))
)


# Export main logger methods directly for easier imports
trace = logger.trace
debug = logger.debug
network = logger.network
info = logger.info
success = logger.success
warning = logger.warning
error = logger.error
critical = logger.critical
trade = logger.trade
profit = logger.profit
rate_limit = logger.rate_limit
rpc = logger.rpc
section = logger.section
status_update = logger.status_update
log_exception = logger.log_exception


# Alias for backward compatibility
Solana_logger = SolanaLogger
   FIX THIS SO IT LOADS AND WORKS PLEASE THE FILE NAME IS C:\solana_rust_bot\src\python\solana_logger.py    ITS solana_logger.py soooooooo ?!?!?!?!?!?!?!?!? (quantum_beast) PS C:\solana_rust_bot> python "C:\solana_rust_bot\src\python\test_solana_trading.py"
ℹ️  2025-03-08 05:09:14 | INFO       | Solana Trading Logger initialized: trade_engine
ℹ️  2025-03-08 05:09:14 | INFO       | Log file: logs\trade_engine_20250308_050914.log
Traceback (most recent call last):
  File "C:\solana_rust_bot\src\python\test_solana_trading.py", line 16, in <module>
    from solana_logger import setup_logger, logger  # Changed from get_logger to logger
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ImportError: cannot import name 'setup_logger' from 'solana_logger' (C:\solana_rust_bot\src\python\solana_logger.py)
(quantum_beast) PS C:\solana_rust_bot> import asyncio
import os
import sys
import time
import random
from pathlib import Path
from typing import Dict, List, Optional, Tuple, Union

import numpy as np
import torch

# Add the parent directory to sys.path
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# Import local modules
from solana_logger import setup_logger, logger  # Changed from get_logger to logger
from config_loader import load_config

# Set up logger
setup_logger("trade_engine")
# logger = get_logger("trade_engine")  # This line is removed since we're importing logger directly

# Load configuration
config = load_config()

# Try to import Rust trading module
try:
    import solana_rust_bot
    RUST_AVAILABLE = True
except ImportError:
    logger.warning("Solana Rust bot module not available, using dummy implementation")
    RUST_AVAILABLE = False


class DummySwapParams:
    """Dummy swap params for testing without the Rust module"""
    
    def __init__(self, token_mint, amount_in, is_buy, slippage_bps=None, compute_limit=None, priority_fee=None):
        self.token_mint = token_mint
        self.amount_in = amount_in
        self.is_buy = is_buy
        self.slippage_bps = slippage_bps or 1000
        self.compute_limit = compute_limit or 50000
        self.priority_fee = priority_fee or 750000


class DummyTransactionStatus:
    """Dummy transaction status for testing"""
    
    def __init__(self, signature="dummy_sig", success=True, error=None, timestamp=None, simulation_only=False):
        self.signature = signature
        self.success = success
        self.error = error
        self.timestamp = timestamp or int(time.time())
        self.simulation_only = simulation_only


class DummyRaydiumTradingCore:
    """Dummy trading core implementation for testing"""
    
    @classmethod
    def new(cls, keypair_path):
        return cls()
    
    async def execute_swap(self, params):
        """Simulate swap execution with random success/failure"""
        time.sleep(0.1)  # Simulate network delay
        
        success = random.random() > 0.2  # 80% success rate
        sig = f"DummySignature_{random.randint(1000000, 9999999)}"
        
        return DummyTransactionStatus(
            signature=sig,
            success=success,
            error=None if success else "Simulated error",
            timestamp=int(time.time()),
            simulation_only=True
        )


class TestTradingEngine:
    """Test implementation of trading engine"""
    
    def __init__(self):
        """Initialize trading engine"""
        logger.info("Initializing test trading engine")
        
        # Initialize statistics
        self.stats = {
            "start_time": time.time(),
            "trades_processed": 0,
            "trades_executed": 0,
            "successful_trades": 0,
            "total_profit": 0.0,
            "execution_times": []
        }
        
        # Set up ML model
        self.setup_ml_model()
        
        # Set up Rust trading core
        self.setup_rust_core()
    
    def setup_ml_model(self):
        """Set up ML model for trade evaluation"""
        try:
            # Check if CUDA is available
            self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
            
            if torch.cuda.is_available():
                device_name = torch.cuda.get_device_name(0)
                logger.info(f"CUDA available: Using {device_name}")
            else:
                logger.info("CUDA not available: Using CPU")
            
            # Load ML model
            model_path = Path("models/trade_model.pt")
            logger.info(f"Loading ML model from {model_path}")
            
            if not model_path.exists():
                logger.warning(f"Model file not found: {model_path}")
                self.model = None
                return
            
            self.model = torch.load(model_path, map_location=self.device)
            self.model.eval()
            
            # Test the model with dummy input
            dummy_input = torch.randn(1, 176).to(self.device)
            with torch.no_grad():
                _ = self.model(dummy_input)
            
            logger.info("ML model loaded and tested successfully")
        
        except Exception as e:
            logger.error(f"Error setting up ML model: {e}")
            logger.exception("Exception occurred")  # Changed from logger.log_exception()
            self.model = None
    
    def setup_rust_core(self):
        """Set up Rust trading core for trade execution"""
        try:
            # Check if keypair file exists
            keypair_path = "keypair.bin"
            if os.path.exists(keypair_path):
                logger.info(f"Found keypair at: {keypair_path}")
            else:
                logger.warning(f"Keypair file not found: {keypair_path}")
                self.rust_core = DummyRaydiumTradingCore()
                return
            
            # Initialize Rust trading core
            if RUST_AVAILABLE:
                self.rust_core = solana_rust_bot.RaydiumTradingCore.new(keypair_path)
            else:
                self.rust_core = DummyRaydiumTradingCore()
        
        except Exception as e:
            logger.error(f"Error initializing Rust trading core: {e}")
            logger.exception("Exception occurred")  # Changed from logger.log_exception()
            self.rust_core = DummyRaydiumTradingCore()
    
    def evaluate_ml(self, amount: float) -> Tuple[float, bool]:
        """Evaluate trade with ML model
        
        Args:
            amount: Amount of SOL being swapped
            
        Returns:
            Tuple of (confidence_score, execute_decision)
        """
        if self.model is None:
            # If no model available, use simple heuristic
            confidence = random.uniform(-100, 100)
            return confidence, confidence > 0
        
        try:
            # Create features
            features = [amount]
            
            # Add dummy features for testing
            features.extend([random.random() for _ in range(175)])
            
            # Convert to tensor
            features_tensor = torch.tensor([features], dtype=torch.float32).to(self.device)
            
            # Get prediction
            with torch.no_grad():
                output = self.model(features_tensor)
            
            # Convert to confidence score
            confidence = output.item()
            
            # Make decision
            execute = confidence > config.get("ml_confidence_threshold", 0.5)
            
            logger.info(f"ML evaluation - Confidence: {confidence:.4f}, Execute: {execute}")
            
            return confidence, execute
        
        except Exception as e:
            logger.error(f"Error evaluating ML model: {e}")
            logger.exception("Exception occurred")  # Changed from logger.log_exception()
            return 0.0, False
    
    def calculate_profit_rate(self, amount: float) -> float:
        """Calculate profit rate based on amount"""
        # Simple model for testing: bigger trades = higher profit rate
        # In reality, this would be based on market depth and price impact
        base_rate = 0.001  # 0.1% base rate
        
        # Scale with amount, with diminishing returns
        scale_factor = min(0.01, 0.001 * (amount / 10))
        
        return base_rate + scale_factor
    
    async def simulate_trade(self, amount: float):
        """Simulate a complete trade
        
        Args:
            amount: Amount of SOL being traded
        """
        try:
            self.stats["trades_processed"] += 1
            
            logger.info(f"Simulating trade with amount: {amount:.4f} SOL")  # Changed from logger.trade()
            
            # Evaluate with ML model
            ml_confidence, execute_decision = self.evaluate_ml(amount)
            
            if not execute_decision:
                return
            
            # Start timing
            start_time = time.time()
            
            self.stats["trades_executed"] += 1
            
            # If we're here, we've decided to execute the trade
            token_mint = config.get("token_mint", "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263")
            front_amount = config.get("front_run_amount", 0.35)
            
            if self.rust_core is not None:
                # Execute front-run swap
                front_swap_params = DummySwapParams(
                    token_mint=token_mint,
                    amount_in=front_amount,
                    is_buy=True,
                    slippage_bps=config.get("slippage_bps", 1000),
                    compute_limit=config.get("compute_limit", 50000),
                    priority_fee=config.get("priority_fee", 750000)
                )
                
                front_tx = await self.rust_core.execute_swap(front_swap_params)
                
                # Check if front_tx is None or doesn't have a success attribute
                front_success = False
                if front_tx is not None:
                    front_success = getattr(front_tx, 'success', False)
                    if isinstance(front_success, str):  # Handle case where success might be a string
                        front_success = front_success.lower() == 'true'
                
                if not front_success:
                    logger.error("Front-run transaction failed")
                    return
                
                # Proceed with back-run swap
                back_swap_params = DummySwapParams(
                    token_mint=token_mint,
                    amount_in=front_amount,
                    is_buy=False,
                    slippage_bps=config.get("slippage_bps", 1000),
                    compute_limit=config.get("compute_limit", 50000),
                    priority_fee=config.get("priority_fee", 750000)
                )
                
                back_tx = await self.rust_core.execute_swap(back_swap_params)

                # Check if back_tx is None or doesn't have a success attribute
                back_success = False
                if back_tx is not None:
                    back_success = getattr(back_tx, 'success', False)
                    if isinstance(back_success, str):  # Handle case where success might be a string
                        back_success = back_success.lower() == 'true'

                if not back_success:
                    logger.error("Back-run transaction failed")
                    return
                
                execution_time = (time.time() - start_time) * 1000
                self.stats["execution_times"].append(execution_time)

                profit_rate = self.calculate_profit_rate(amount)
                profit = front_amount * profit_rate
                
                self.stats["successful_trades"] += 1
                self.stats["total_profit"] += profit
                
                # Create formatted message for profit display
                front_signature = getattr(front_tx, 'signature', 'Unknown')
                back_signature = getattr(back_tx, 'signature', 'Unknown')
                
                profit_message = f"""
Trade #{self.stats["successful_trades"]} completed successfully:
Amount: {amount:.4f} SOL
Front TX: {front_signature}
Back TX: {back_signature}
Profit: {profit:.6f} SOL
Execution Time: {execution_time:.3f} ms
ML Confidence: {ml_confidence:.4f}
Total Profit: {self.stats["total_profit"]:.6f} SOL
"""
                logger.info(f"Profit: {profit:.6f} SOL")  # Changed from logger.profit()
                logger.info(profit_message)
                
        except Exception as e:
            logger.error(f"Error simulating trade: {e}")
            logger.exception("Exception occurred")  # Changed from logger.log_exception()
    
    def print_stats(self):
        """Print current trading statistics"""
        if len(self.stats["execution_times"]) > 0:
            avg_execution_time = sum(self.stats["execution_times"]) / len(self.stats["execution_times"])
        else:
            avg_execution_time = 0
            
        runtime = time.time() - self.stats["start_time"]
        
        stats_dict = {
            "runtime_seconds": runtime,
            "runtime_formatted": f"{int(runtime // 3600):02d}:{int((runtime % 3600) // 60):02d}:{int(runtime % 60):02d}",
            "trades_processed": self.stats["trades_processed"],
            "trades_executed": self.stats["trades_executed"],
            "successful_trades": self.stats["successful_trades"],
            "total_profit": self.stats["total_profit"],
            "avg_execution_time_ms": avg_execution_time
        }
        
        if self.stats["successful_trades"] > 0:
            stats_dict["avg_profit_per_trade"] = self.stats["total_profit"] / self.stats["successful_trades"]
        
        if self.stats["trades_processed"] > 0:
            stats_dict["execution_rate"] = self.stats["trades_executed"] / self.stats["trades_processed"]
            stats_dict["success_rate"] = self.stats["successful_trades"] / self.stats["trades_processed"]
        
        logger.info("Trading Bot Statistics:")  # Changed from logger.print_stats()
        for key, value in stats_dict.items():
            logger.info(f"  {key}: {value}")
async def run_test_simulation():
    """Run a test simulation of the trading engine"""
    try:
        logger.info("=" * 80)  # Changed from logger.section()
        logger.info("=== Starting Test Simulation ===")
        logger.info("=" * 80)
        
        # Create test engine
        engine = TestTradingEngine()
        
        # Wait a bit for initialization
        await asyncio.sleep(2)
        
        # Simulate multiple trades with different amounts
        min_amount = config.get("min_victim_size", 5.0)
        max_amount = config.get("max_victim_size", 320.0)
        
        num_trades = 5
        logger.info(f"Simulating {num_trades} trades with amounts between {min_amount} and {max_amount} SOL")
        
        for i in range(num_trades):
            # Generate a random trade amount
            amount = random.uniform(min_amount, max_amount)
            
            # Simulate the trade
            await engine.simulate_trade(amount)
            
            # Wait between trades
            await asyncio.sleep(1)
        
        # Print final statistics
        engine.print_stats()
        
        logger.info("=" * 80)  # Changed from logger.section()
        logger.info("=== Simulation Completed ===")
        logger.info("=" * 80)
        
    except Exception as e:
        logger.error(f"Error in test simulation: {e}")
        logger.exception("Exception occurred")


if __name__ == "__main__":
    try:
        # Create logs directory if it doesn't exist
        logs_dir = Path("logs")
        logs_dir.mkdir(exist_ok=True)
        
        # Run the test simulation
        asyncio.run(run_test_simulation())
        
    except KeyboardInterrupt:
        logger.warning("Test simulation interrupted by user")
    except Exception as e:
        logger.critical(f"Fatal error: {e}")
        logger.exception("Exception occurred")
 FIX THE LAST SCRIPT  WRITE THE FULL SCRIPT FIXED