PLEASE FIX ENTIRE SCRIPT I MESSED UP I NEED ALL OF IT use anyhow::{anyhow, Result};
use dashmap::DashMap;
use futures_util::{StreamExt, SinkExt};
use log::{error, info, warn};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use std::{
    cmp::min,
    path::PathBuf,
    sync::Arc,
    time::{Duration, Instant, SystemTime},
};
use tokio::{fs::File, io::{AsyncReadExt, AsyncWriteExt}, sync::{broadcast, Mutex}};
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
use url::Url;

// Configuration Constants
const JUPITER_API: &str = "https://quote-api.jup.ag/v6";
const HELIUS_RPC: &str = "https://marga-e56m84-fast-mainnet.helius-rpc.com";
const WS_URL: &str = "wss://marga-e56m84-fast-mainnet.helius-rpc.com/";
const WALLET_PUBLIC_KEY: &str = "EHrpEhiBU13CygunXsmeGnzR6ircuYFQcFYPZT5BWUMA";
const HELIUS_API_KEY: &str = "1ea5843b-9daa-4926-a97a-be021922da2f";
const SOL_MINT: &str = "So11111111111111111111111111111111111111112";

// Trading Parameters
const MIN_SUPPLY: u64 = 900_000_000;
const LIQUIDITY_MIN: f64 = 4.0;  // ~1000 USD at 250 USD/SOL
const LIQUIDITY_MAX: f64 = 80.0; // ~20000 USD at 250 USD/SOL
const TRADE_AMOUNT: u64 = 5_000_000;
const MAX_TRADES: usize = 5;

#[derive(Debug, Clone, Serialize, Deserialize)]
struct TradeState {
    token_mint: String,
    entry_price: f64,
    amount: u64,
    timestamp: u64,
    last_price: f64,
    success_count: u32,
    profit_loss: f64,
}

#[derive(Debug, Clone)]
struct ActiveTrade {
    token_mint: String,
    entry_price: f64,
    amount: u64,
    start_time: Instant,
    last_price: Arc<Mutex<f64>>,
    success_count: u32,
    profit_loss: f64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
struct SystemMetrics {
    total_trades: u32,
    successful_trades: u32,
    failed_trades: u32,
    total_profit_loss: f64,
    start_time: u64,
    last_restart: u64,
}

#[derive(Debug)]
struct TradingSystem {
    active_trades: DashMap<String, ActiveTrade>,
    last_prices: DashMap<String, f64>,
    known_tokens: DashMap<String, Instant>,
    metrics: Arc<Mutex<SystemMetrics>>,
    state_file: PathBuf,
    metrics_file: PathBuf,
    shutdown_signal: broadcast::Sender<()>,
}

impl TradingSystem {
    fn new() -> Self {
        let (shutdown_tx, _) = broadcast::channel(1);
        Self {
            active_trades: DashMap::new(),
            last_prices: DashMap::new(),
            known_tokens: DashMap::new(),
            metrics: Arc::new(Mutex::new(SystemMetrics {
                total_trades: 0,
                successful_trades: 0,
                failed_trades: 0,
                total_profit_loss: 0.0,
                start_time: SystemTime::now()
                    .duration_since(SystemTime::UNIX_EPOCH)
                    .unwrap()
                    .as_secs(),
                last_restart: SystemTime::now()
                    .duration_since(SystemTime::UNIX_EPOCH)
                    .unwrap()
                    .as_secs(),
            })),
            state_file: PathBuf::from("trading_state.json"),
            metrics_file: PathBuf::from("system_metrics.json"),
            shutdown_signal: shutdown_tx,
        }
    }

    async fn check_liquidity_and_price(&self, token_mint: &str) -> Result<(f64, f64)> {
        let quote = get_quote(SOL_MINT, token_mint, TRADE_AMOUNT).await?;
        
        let in_amount = quote["inAmount"].as_str()
            .ok_or_else(|| anyhow!("Invalid input amount"))?
            .parse::<f64>()? / 1e9;
            
        let out_amount = quote["outAmount"].as_str()
            .ok_or_else(|| anyhow!("Invalid output amount"))?
            .parse::<f64>()?;
            
        let price = in_amount / out_amount;
        let liquidity = in_amount * price;

        Ok((liquidity, price))
    }

    async fn execute_trade(&self, token_mint: &str, is_buy: bool, amount: u64) -> Result<String> {
        let (input_mint, output_mint) = if is_buy {
            (SOL_MINT, token_mint)
        } else {
            (token_mint, SOL_MINT)
        };

        let quote = get_quote(input_mint, output_mint, amount).await?;
        let swap_data = get_swap_data(quote).await?;
        let signature = send_priority_tx(swap_data).await?;
        
        Ok(signature)
    }

    async fn validate_new_token(&self, token_data: &Value) -> Result<bool> {
        let token_mint = token_data["mint"].as_str()
            .ok_or_else(|| anyhow!("Invalid mint address"))?;

        info!("🔍 Validating token: {}", token_mint);

        if self.known_tokens.contains_key(token_mint) {
            return Ok(false);
        }

        if self.active_trades.contains_key(token_mint) {
            return Ok(false);
        }

        let mint_data = token_data
            .get("data")
            .and_then(|d| d.get("parsed"))
            .and_then(|p| p.get("info"))
            .ok_or_else(|| anyhow!("Invalid token data structure"))?;

        let supply = mint_data["supply"].as_str()
            .unwrap_or("0")
            .parse::<u64>()?;

        if supply < MIN_SUPPLY {
            self.known_tokens.insert(token_mint.to_string(), Instant::now());
            return Ok(false);
        }

        let (liquidity, price) = self.check_liquidity_and_price(token_mint).await?;
        
        if !(LIQUIDITY_MIN..=LIQUIDITY_MAX).contains(&liquidity) {
            self.known_tokens.insert(token_mint.to_string(), Instant::now());
            return Ok(false);
        }

        self.last_prices.insert(token_mint.to_string(), price);
        Ok(true)
    }

    async fn monitor_trades(&self) -> Result<()> {
        let mut interval = tokio::time::interval(Duration::from_secs(1));
        let mut shutdown_rx = self.shutdown_signal.subscribe();

        loop {
            tokio::select! {
                _ = interval.tick() => {
                    for trade in self.active_trades.iter() {
                        let token_mint = &trade.token_mint;
                        
                        match self.check_liquidity_and_price(token_mint).await {
                            Ok((liquidity, current_price)) => {
                                if let Ok(mut last_price) = trade.last_price.try_lock() {
                                    *last_price = current_price;
                                }

                                let profit_percent = (current_price - trade.entry_price) / trade.entry_price * 100.0;
                                
                                if profit_percent >= 20.0 {
                                    info!("🎯 Take profit hit for {}: {:.2}%", token_mint, profit_percent);
                                    if let Ok(sig) = self.execute_trade(token_mint, false, trade.amount).await {
                                        info!("💰 Sold for profit - TX: {}", sig);
                                        self.active_trades.remove(token_mint);
                                    }
                                } else if profit_percent <= -5.0 {
                                    warn!("⚠️ Stop loss hit for {}: {:.2}%", token_mint, profit_percent);
                                    if let Ok(sig) = self.execute_trade(token_mint, false, trade.amount).await {
                                        info!("🛑 Stop loss executed - TX: {}", sig);
                                        self.active_trades.remove(token_mint);
                                    }
                                }
                            }
                            Err(e) => warn!("Failed to fetch price for {}: {}", token_mint, e)
                        }
                    }
                }
                _ = shutdown_rx.recv() => {
                    info!("🛑 Received shutdown signal in monitor_trades");
                    break;
                }
            }
        }
        Ok(())
    }

    async fn run(&self) -> Result<()> {
        let monitor_handle = {
            let this = self.clone();
            tokio::spawn(async move {
                if let Err(e) = this.monitor_trades().await {
                    error!("Trade monitor error: {}", e);
                }
            })
        };

        let ws_url = Url::parse(WS_URL)?;
        let mut ws_stream = connect_async(ws_url).await?.0;

        // WebSocket subscription code here...

        monitor_handle.await?;
        Ok(())
    }
}

#[tokio::main]
async fn main() -> Result<()> {
    env_logger::init();
    info!("🚀 Starting trading system v2.0");

    let system = Arc::new(TradingSystem::new());

    let shutdown_signal = system.shutdown_signal.clone();
    ctrlc::set_handler(move || {
        info!("Received Ctrl+C, initiating graceful shutdown...");
        let _ = shutdown_signal.send(());
    })?;

    if let Err(e) = system.run().await {
        error!("System error: {}", e);
    }

    info!("👋 Trading system shutdown complete");
    Ok(())
}

impl TradingSystem {
    fn new() -> Self {
        let (shutdown_tx, _) = broadcast::channel(1);
        Self {
            active_trades: DashMap::new(),
            last_prices: DashMap::new(),
            known_tokens: DashMap::new(),
            metrics: Arc::new(Mutex::new(SystemMetrics {
                total_trades: 0,
                successful_trades: 0,
                failed_trades: 0,
                total_profit_loss: 0.0,
                start_time: SystemTime::now()
                    .duration_since(SystemTime::UNIX_EPOCH)
                    .unwrap()
                    .as_secs(),
                last_restart: SystemTime::now()
                    .duration_since(SystemTime::UNIX_EPOCH)
                    .unwrap()
                    .as_secs(),
            })),
            state_file: PathBuf::from("trading_state.json"),
            metrics_file: PathBuf::from("system_metrics.json"),
            shutdown_signal: shutdown_tx,
        }
    }
}
// Helper Functions
async fn get_quote(input_mint: &str, output_mint: &str, amount: u64) -> Result<Value> {
    let url = format!(
        "{}/quote?inputMint={}&outputMint={}&amount={}&slippageBps=50&onlyDirectRoutes=true&wrapUnwrapSOL=true",
        JUPITER_API, input_mint, output_mint, amount
    );
    
    let response = reqwest::get(&url)
        .await?
        .json::<Value>()
        .await?;
    
    Ok(response)
}

async fn get_swap_data(quote: Value) -> Result<String> {
    let swap_request = json!({
        "quoteResponse": quote,
        "userPublicKey": WALLET_PUBLIC_KEY,
        "wrapUnwrapSOL": true,
        "computeUnitPriceMicroLamports": 15000,
        "priorityFeeLamports": 15000,
        "asLegacyTransaction": false,
        "maxAccounts": 64
    });

    let response = reqwest::Client::new()
        .post(format!("{}/swap", JUPITER_API))
        .json(&swap_request)
        .send()
        .await?
        .json::<Value>()
        .await?;

    match response.get("swapTransaction") {
        Some(tx) => Ok(tx.as_str()
            .ok_or_else(|| anyhow!("Invalid transaction format"))?
            .to_string()),
        None => Err(anyhow!("No swap transaction in response"))
    }
}

async fn send_priority_tx(swap_data: String) -> Result<String> {
    let helius_request = json!({
        "jsonrpc": "2.0",
        "id": "helius-priority",
        "method": "sendTransaction",
        "params": [
            swap_data,
            {
                "encoding": "base64",
                "maxRetries": 0,
                "skipPreflight": true,
                "preflightCommitment": "processed",
                "priorityFee": 15000
            }
        ]
    });

    let response = reqwest::Client::new()
        .post(HELIUS_RPC)
        .header("Authorization", format!("Bearer {}", HELIUS_API_KEY))
        .json(&helius_request)
        .send()
        .await?
        .json::<Value>()
        .await?;

    match response.get("result") {
        Some(result) => Ok(result.as_str()
            .ok_or_else(|| anyhow!("Invalid result format"))?
            .to_string()),
        None => Err(anyhow!("No result in response"))
    }
    async fn save_detailed_state(&self) -> Result<()> {
        let state = json!({
            "active_trades": self.active_trades.iter().map(|trade| {
                json!({
                    "token_mint": trade.token_mint,
                    "entry_price": trade.entry_price,
                    "amount": trade.amount,
                    "timestamp": SystemTime::now()
                        .duration_since(SystemTime::UNIX_EPOCH)
                        .unwrap()
                        .as_secs(),
                    "last_price": *trade.last_price.blocking_lock(),
                    "success_count": trade.success_count,
                    "profit_loss": trade.profit_loss
                })
            }).collect::<Vec<_>>(),
            
            "known_tokens": self.known_tokens.iter().map(|entry| {
                json!({
                    "mint": entry.key(),
                    "last_seen": entry.value().elapsed().as_secs(),
                    "reason": "pending_validation"  // You can add more detailed reasons
                })
            }).collect::<Vec<_>>(),
            
            "metrics": {
                "total_trades": self.metrics.blocking_lock().total_trades,
                "successful_trades": self.metrics.blocking_lock().successful_trades,
                "failed_trades": self.metrics.blocking_lock().failed_trades,
                "total_profit_loss": self.metrics.blocking_lock().total_profit_loss,
                "start_time": self.metrics.blocking_lock().start_time,
                "last_restart": self.metrics.blocking_lock().last_restart
            },
            
            "last_prices": self.last_prices.iter().map(|entry| {
                json!({
                    "mint": entry.key(),
                    "price": entry.value(),
                    "last_update": SystemTime::now()
                        .duration_since(SystemTime::UNIX_EPOCH)
                        .unwrap()
                        .as_secs()
                })
            }).collect::<Vec<_>>(),
            
            "system_info": {
                "uptime_seconds": SystemTime::now()
                    .duration_since(SystemTime::UNIX_EPOCH)
                    .unwrap()
                    .as_secs() - self.metrics.blocking_lock().start_time,
                "active_trades_count": self.active_trades.len(),
                "known_tokens_count": self.known_tokens.len(),
                "tracked_prices_count": self.last_prices.len(),
                "last_save": SystemTime::now()
                    .duration_since(SystemTime::UNIX_EPOCH)
                    .unwrap()
                    .as_secs()
            },
            
            "trading_parameters": {
                "min_supply": MIN_SUPPLY,
                "liquidity_min": LIQUIDITY_MIN,
                "liquidity_max": LIQUIDITY_MAX,
                "trade_amount": TRADE_AMOUNT,
                "max_trades": MAX_TRADES,
                "take_profit": 20.0,
                "stop_loss": -5.0
            }
        });

        let mut file = File::create(&self.state_file).await?;
        file.write_all(serde_json::to_string_pretty(&state)?.as_bytes()).await?;
        
        info!("💾 Detailed system state saved to {}", self.state_file.display());
        Ok(())
    }
    async fn load_full_state(&self) -> Result<()> {
        if self.state_file.exists() {
            let mut file = File::open(&self.state_file).await?;
            let mut contents = String::new();
            file.read_to_string(&mut contents).await?;
            
            let states: Vec<TradeState> = serde_json::from_str(&contents)?;
            
            for state in states {
                let age = SystemTime::now()
                    .duration_since(SystemTime::UNIX_EPOCH)
                    .unwrap()
                    .as_secs() - state.timestamp;
                    
                if age < 3600 {
                    self.active_trades.insert(
                        state.token_mint.clone(),
                        ActiveTrade {
                            token_mint: state.token_mint,
                            entry_price: state.entry_price,
                            amount: state.amount,
                            start_time: Instant::now(),
                            last_price: Arc::new(Mutex::new(state.last_price)),
                            success_count: state.success_count,
                            profit_loss: state.profit_loss,
                        }
                    );
                }
            }
        }

        if self.metrics_file.exists() {
            let mut file = File::open(&self.metrics_file).await?;
            let mut contents = String::new();
            file.read_to_string(&mut contents).await?;
            
            let stored_metrics: SystemMetrics = serde_json::from_str(&contents)?;
            let mut metrics = self.metrics.lock().await;
            *metrics = stored_metrics;
            metrics.last_restart = SystemTime::now()
                .duration_since(SystemTime::UNIX_EPOCH)
                .unwrap()
                .as_secs();
        }
        
        info!("📂 System state restored successfully");
        self.print_system_status().await;
        Ok(())
    }

    async fn check_liquidity_and_price(&self, token_mint: &str) -> Result<(f64, f64)> {
        let quote = get_quote(SOL_MINT, token_mint, TRADE_AMOUNT).await?;
        
        let in_amount = quote["inAmount"].as_str()
            .ok_or_else(|| anyhow!("Invalid input amount"))?
            .parse::<f64>()? / 1e9;
            
        let out_amount = quote["outAmount"].as_str()
            .ok_or_else(|| anyhow!("Invalid output amount"))?
            .parse::<f64>()?;
            
        let price = in_amount / out_amount;
        let liquidity = in_amount * price;

        Ok((liquidity, price))
    }

    async fn execute_trade(&self, token_mint: &str, is_buy: bool, amount: u64) -> Result<String> {
        let (input_mint, output_mint) = if is_buy {
            (SOL_MINT, token_mint)
        } else {
            (token_mint, SOL_MINT)
        };

        let quote = get_quote(input_mint, output_mint, amount).await?;
        let swap_data = get_swap_data(quote).await?;
        let signature = send_priority_tx(swap_data).await?;
        
        Ok(signature)
    }

    async fn print_system_status(&self) {
        let metrics = self.metrics.lock().await;
        let uptime = SystemTime::now()
            .duration_since(SystemTime::UNIX_EPOCH)
            .unwrap()
            .as_secs() - metrics.start_time;
        
        info!("📊 System Status:");
        info!("   Active Trades: {}", self.active_trades.len());
        info!("   Total Trades: {}", metrics.total_trades);
        info!("   Success Rate: {:.2}%", 
            if metrics.total_trades > 0 {
                (metrics.successful_trades as f64 / metrics.total_trades as f64) * 100.0
            } else {
                0.0
            });
        info!("   Total P/L: {:.4} SOL", metrics.total_profit_loss);
        info!("   Uptime: {}h {}m", uptime / 3600, (uptime % 3600) / 60);
        info!("   Last Restart: {} minutes ago", 
            (SystemTime::now()
                .duration_since(SystemTime::UNIX_EPOCH)
                .unwrap()
                .as_secs() - metrics.last_restart) / 60);
    }

    async fn validate_new_token(&self, token_data: &Value) -> Result<bool> {
        let token_mint = token_data["mint"].as_str()
            .ok_or_else(|| anyhow!("Invalid mint address"))?;

        info!("🔍 Validating token: {}", token_mint);

        // Check known tokens
        if self.known_tokens.contains_key(token_mint) {
            info!("⏭️ Token already known: {}", token_mint);
            return Ok(false);
        }

        // Check active trades
        if self.active_trades.contains_key(token_mint) {
            info!("⏭️ Already trading: {}", token_mint);
            return Ok(false);
        }

        // Extract and validate token data
        let mint_data = match token_data.get("data").and_then(|d| d.get("parsed")).and_then(|p| p.get("info")) {
            Some(data) => data,
            None => {
                info!("⏭️ Invalid token data structure");
                return Ok(false);
            }
        };

        // Supply check
        let supply = mint_data["supply"].as_str()
            .unwrap_or("0")
            .parse::<u64>()?;

        info!("📊 Token supply: {}", supply);
        
        if supply < MIN_SUPPLY {
            info!("⏭️ Supply too low: {} < {}", supply, MIN_SUPPLY);
            self.known_tokens.insert(token_mint.to_string(), Instant::now());
            return Ok(false);
        }

        // Token attributes
        let is_frozen = mint_data["freezeAuthority"].is_null();
        let is_burnt = !mint_data["mintAuthority"].is_null();
        let is_mutable = mint_data["mintAuthority"].is_null();

        info!("🔒 Token attributes - Frozen: {}, Burnt: {}, Mutable: {}", 
            is_frozen, is_burnt, is_mutable);

        if !is_frozen || !is_burnt || is_mutable {
            info!("⏭️ Token attributes invalid");
            self.known_tokens.insert(token_mint.to_string(), Instant::now());
            return Ok(false);
        }

        // Check liquidity
        match self.check_liquidity_and_price(token_mint).await {
            Ok((liquidity, price)) => {
                info!("💧 Liquidity: {} SOL, Price: {} SOL", liquidity, price);
                
                if !(LIQUIDITY_MIN..=LIQUIDITY_MAX).contains(&liquidity) {
                    info!("⏭️ Liquidity outside range: {} SOL", liquidity);
                    self.known_tokens.insert(token_mint.to_string(), Instant::now());
                    return Ok(false);
                }

                // Cache the initial price
                self.last_prices.insert(token_mint.to_string(), price);
            }
            Err(e) => {
                info!("⏭️ Failed to check liquidity: {}", e);
                self.known_tokens.insert(token_mint.to_string(), Instant::now());
                return Ok(false);
            }
        }

        info!("✅ Token validated successfully: {}", token_mint);
        Ok(true)
    }

    async fn save_full_state(&self) -> Result<()> {
        // Save trading state
        let state = json!({
            "active_trades": self.active_trades.iter().map(|trade| {
                let last_price = futures::executor::block_on(trade.last_price.lock());
                json!({
                    "token_mint": trade.token_mint,
                    "entry_price": trade.entry_price,
                    "amount": trade.amount,
                    "timestamp": SystemTime::now()
                        .duration_since(SystemTime::UNIX_EPOCH)
                        .unwrap()
                        .as_secs(),
                    "last_price": *last_price,
                    "success_count": trade.success_count,
                    "profit_loss": trade.profit_loss
                })
            }).collect::<Vec<_>>(),
            
            "known_tokens": self.known_tokens.iter().map(|entry| {
                json!({
                    "mint": entry.key(),
                    "last_seen": entry.value().elapsed().as_secs()
                })
            }).collect::<Vec<_>>(),
            
            "metrics": {
                "total_trades": self.metrics.blocking_lock().total_trades,
                "successful_trades": self.metrics.blocking_lock().successful_trades,
                "failed_trades": self.metrics.blocking_lock().failed_trades,
                "total_profit_loss": self.metrics.blocking_lock().total_profit_loss,
                "start_time": self.metrics.blocking_lock().start_time,
                "last_restart": self.metrics.blocking_lock().last_restart,
            },
            
            "last_prices": self.last_prices.iter().map(|entry| {
                json!({
                    "mint": entry.key(),
                    "price": entry.value()
                })
            }).collect::<Vec<_>>(),
            
            "system_info": {
                "uptime_seconds": SystemTime::now()
                    .duration_since(SystemTime::UNIX_EPOCH)
                    .unwrap()
                    .as_secs() - self.metrics.blocking_lock().start_time,
                "active_trades_count": self.active_trades.len(),
                "known_tokens_count": self.known_tokens.len(),
                "tracked_prices_count": self.last_prices.len()
            }
        });

        let mut file = File::create(&self.state_file).await?;
        file.write_all(serde_json::to_string_pretty(&state)?.as_bytes()).await?;
        
        info!("💾 System state saved to {}", self.state_file.display());
        Ok(())
    }

    async fn print_detailed_status(&self) {
        info!("🔍 Detailed System Status:");
        info!("├── Active Trades: {}", self.active_trades.len());
        
        for trade in self.active_trades.iter() {
            let last_price = *trade.last_price.blocking_lock();
            let profit_percent = (last_price - trade.entry_price) / trade.entry_price * 100.0;
            
            info!("│   ├── Token: {}", trade.token_mint);
            info!("│   │   ├── Entry: {} SOL", trade.entry_price);
            info!("│   │   ├── Current: {} SOL", last_price);
            info!("│   │   ├── P/L: {:.2}%", profit_percent);
            info!("│   │   └── Age: {}s", trade.start_time.elapsed().as_secs());
        }
        
        info!("├── Known Tokens: {}", self.known_tokens.len());
        info!("├── Tracked Prices: {}", self.last_prices.len());
        
        let metrics = self.metrics.blocking_lock();
        info!("└── Performance:");
        info!("    ├── Success Rate: {:.2}%", 
            if metrics.total_trades > 0 {
                (metrics.successful_trades as f64 / metrics.total_trades as f64) * 100.0
            } else {
                0.0
            });
        info!("    ├── Total P/L: {:.4} SOL", metrics.total_profit_loss);
        info!("    └── Uptime: {}h {}m", 
            metrics.start_time / 3600,
            (metrics.start_time % 3600) / 60);
    }

    
    async fn monitor_trades(&self) -> Result<()> {
        let mut interval = tokio::time::interval(Duration::from_secs(1));
        let mut shutdown_rx = self.shutdown_signal.subscribe();

        loop {
            tokio::select! {
                _ = interval.tick() => {
                    for trade in self.active_trades.iter() {
                        let token_mint = &trade.token_mint;
                        
                        match self.check_liquidity_and_price(token_mint).await {
                            Ok((liquidity, current_price)) => {
                                if let Ok(mut last_price) = trade.last_price.try_lock() {
                                    *last_price = current_price;
                                }

                                let profit_percent = (current_price - trade.entry_price) / trade.entry_price * 100.0;
                                
                                if liquidity < LIQUIDITY_MIN || liquidity > LIQUIDITY_MAX {
                                    info!("⚠️ Liquidity outside range for {}, executing sell", token_mint);
                                    match self.execute_trade(token_mint, false, trade.amount).await {
                                        Ok(sig) => {
                                            info!("💰 Emergency sell executed - TX: {}", sig);
                                            self.active_trades.remove(token_mint);
                                            self.save_full_state().await?;
                                        }
                                        Err(e) => error!("Failed to execute emergency sell: {}", e)
                                    }
                                    continue;
                                }

                                if profit_percent >= 20.0 {
                                    info!("🎯 Take profit hit for {}: {:.2}%", token_mint, profit_percent);
                                    match self.execute_trade(token_mint, false, trade.amount).await {
                                        Ok(sig) => {
                                            info!("💰 Sold for profit - TX: {}", sig);
                                            let mut metrics = self.metrics.lock().await;
                                            metrics.successful_trades += 1;
                                            metrics.total_profit_loss += profit_percent;
                                            self.active_trades.remove(token_mint);
                                            self.save_full_state().await?;
                                        }
                                        Err(e) => error!("Take profit failed: {}", e)
                                    }
                                } else if profit_percent <= -5.0 {
                                    warn!("⚠️ Stop loss hit for {}: {:.2}%", token_mint, profit_percent);
                                    match self.execute_trade(token_mint, false, trade.amount).await {
                                        Ok(sig) => {
                                            info!("🛑 Stop loss executed - TX: {}", sig);
                                            let mut metrics = self.metrics.lock().await;
                                            metrics.failed_trades += 1;
                                            metrics.total_profit_loss -= profit_percent.abs();
                                            self.active_trades.remove(token_mint);
                                            self.save_full_state().await?;
                                        }
                                        Err(e) => error!("Stop loss failed: {}", e)
                                    }
                                }
                            }
                            Err(e) => warn!("Failed to fetch price for {}: {}", token_mint, e)
                        }
                    }
                }
                _ = shutdown_rx.recv() => {
                    info!("🛑 Received shutdown signal in monitor_trades");
                    break;
                }
            }
        }
        Ok(())
    }

    async fn run(self: Arc<Self>) -> Result<()> {
        self.load_full_state().await?;
        
        let monitor_system = self.clone();
        let monitor_handle = tokio::spawn(async move {
            if let Err(e) = monitor_system.monitor_trades().await {
                error!("Trade monitor error: {}", e);
            }
        });

        let ws_url = Url::parse(WS_URL)?;
        let mut reconnection_delay = Duration::from_secs(1);
        let mut shutdown_rx = self.shutdown_signal.subscribe();

        loop {
            tokio::select! {
                _ = shutdown_rx.recv() => {
                    info!("🛑 Received shutdown signal in main loop");
                    break;
                }
                res = async {
                    match connect_async(ws_url.clone()).await {
                        Ok((ws_stream, _)) => {
                            info!("📡 WebSocket connected");
                            let (mut write, mut read) = ws_stream.split();
                            
                            let subscribe_msg = json!({
                                "jsonrpc": "2.0",
                                "id": 1,
                                "method": "programSubscribe",
                                "params": [
                                    "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                                    {
                                        "encoding": "jsonParsed",
                                        "filters": [{"dataSize": 82}]
                                    }
                                ]
                            });

                            write.send(Message::Text(subscribe_msg.to_string())).await?;

                            while let Some(msg) = read.next().await {
                                match msg {
                                    Ok(Message::Text(text)) => {
                                        if let Ok(data) = serde_json::from_str::<Value>(&text) {
                                            if let Some(params) = data.get("params") {
                                                if let Some(token_data) = params.get("result") {
                                                    if self.active_trades.len() >= MAX_TRADES {
                                                        continue;
                                                    }

                                                    if let Ok(true) = self.validate_new_token(token_data).await {
                                                        if let Some(token_mint) = token_data["mint"].as_str() {
                                                            match self.execute_trade(token_mint, true, TRADE_AMOUNT).await {
                                                                Ok(signature) => {
                                                                    if let Ok((_, entry_price)) = self.check_liquidity_and_price(token_mint).await {
                                                                        self.active_trades.insert(
                                                                            token_mint.to_string(),
                                                                            ActiveTrade {
                                                                                token_mint: token_mint.to_string(),
                                                                                entry_price,
                                                                                amount: TRADE_AMOUNT,
                                                                                start_time: Instant::now(),
                                                                                last_price: Arc::new(Mutex::new(entry_price)),
                                                                                success_count: 0,
                                                                                profit_loss: 0.0,
                                                                            }
                                                                        );
                                                                        info!("✨ New trade opened - TX: {}", signature);
                                                                        self.save_full_state().await?;
                                                                    }
                                                                }
                                                                Err(e) => warn!("Failed to execute buy: {}", e)
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    Ok(Message::Close(_)) => break,
                                    Err(e) => {
                                        warn!("WebSocket error: {}", e);
                                        break;
                                    }
                                    _ => ()
                                }
                            }
                            Ok::<(), anyhow::Error>(())
                        }
                        Err(e) => {
                            error!("WebSocket connection error: {}. Retrying in {:?}...", e, reconnection_delay);
                            tokio::time::sleep(reconnection_delay).await;
                            reconnection_delay = min(reconnection_delay * 2, Duration::from_secs(30));
                            Ok(())
                        }
                    }
                } => {
                    if let Err(e) = res {
                        error!("WebSocket processing error: {}", e);
                    }
                }
            }
        }

        monitor_handle.await?;
        self.save_full_state().await?;
        Ok(())
    }
}

#[tokio::main]
async fn main() -> Result<()> {
    env_logger::init();
    info!("🚀 Starting trading system v2.0");

    let system = Arc::new(TradingSystem::new());
    let shutdown_signal = system.shutdown_signal.clone();

    ctrlc::set_handler({
        let shutdown_signal = shutdown_signal.clone();
        move || {
            info!("Received Ctrl+C, initiating graceful shutdown...");
            let _ = shutdown_signal.send(());
        }
    })?;

    system.run().await?;
    
    info!("👋 Trading system shutdown complete");
    Ok(())
}