use {
    anyhow::{anyhow, Result},
    base64::{engine::general_purpose::STANDARD as BASE64, Engine},
    chrono::Utc,
    dashmap::DashMap,
    log::{debug, error, info, warn},
    reqwest::Client,
    serde::{Deserialize, Serialize},
    serde_json::{json, Value},
    solana_client::nonblocking::rpc_client::RpcClient,
    solana_sdk::{
        compute_budget::ComputeBudgetInstruction,
        hash::Hash,
        instruction::Instruction,
        message::Message as SolanaMessage,
        pubkey::Pubkey,
        signature::{Keypair, Signer},
        transaction::Transaction,
    },
    std::{
        collections::HashMap,
        convert::TryInto,
        str::FromStr,
        sync::Arc,
        time::{Duration, Instant},
    },
    tokio::{
        sync::RwLock,
        time::{sleep, interval, Interval},
    },
};

// Constants
pub const JUPITER_API: &str = "https://quote-api.jup.ag/v6";
pub const RAYDIUM_AMM_ID: &str = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8";
pub const SOL_MINT: &str = "So11111111111111111111111111111111111111112";

const MAX_TRADES: usize = 5;
const TAKE_PROFIT: f64 = 20.0;
const STOP_LOSS: f64 = -3.0;
const MIN_LIQUIDITY: f64 = 50.0;
const MAX_LIQUIDITY: f64 = 20000.0;
const PRIORITY_FEE: u64 = 1_000_000;
const TRADE_AMOUNT: u64 = 10_000_000;
const MAX_RETRIES: u32 = 6;
const INITIAL_RETRY_DELAY: u64 = 100;
const MAX_RETRY_DELAY: u64 = 1000;
const CACHE_DURATION: i64 = 5;
const RPC_SWITCH_THRESHOLD: u32 = 5;
const VALIDATION_TIMEOUT: Duration = Duration::from_secs(3);
const MIN_ACCOUNT_DATA_LEN: usize = 16;
const SUPPLY_MIN: u64 = 1_000_000;
const SUPPLY_MAX: u64 = 1_000_000_000_000;

pub struct HeliusRateConfig {
    pub rpc_limit: u32,
    pub api_limit: u32,
    pub tx_limit: u32,
    pub gpa_limit: u32
}

impl Default for HeliusRateConfig {
    fn default() -> Self {
        Self {
            rpc_limit: 50,
            api_limit: 10,
            tx_limit: 5,
            gpa_limit: 25
        }
    }
}

pub struct RateLimiter {
    rpc_interval: Interval,
    api_interval: Interval,
    tx_interval: Interval,
    is_limited: RwLock<bool>
}

impl RateLimiter {
    const RPC_LIMIT: u64 = 600;  // Optimized rate
    const API_LIMIT: u64 = 100;
    const TX_LIMIT: u64 = 50;
    const RETRY_DELAY: Duration = Duration::from_millis(100);

    pub fn new(_config: &HeliusRateConfig) -> Self {
        Self {
            rpc_interval: interval(Duration::from_millis(1000 / Self::RPC_LIMIT)),
            api_interval: interval(Duration::from_millis(1000 / Self::API_LIMIT)),
            tx_interval: interval(Duration::from_millis(1000 / Self::TX_LIMIT)),
            is_limited: RwLock::new(false)
        }
    }

    pub async fn wait_rpc(&mut self) {
        self.rpc_interval.tick().await;
        tokio::time::sleep(Self::RETRY_DELAY).await;
    }

    pub async fn wait_api(&mut self) {
        self.api_interval.tick().await;
    }

    pub async fn wait_tx(&mut self) {
        self.tx_interval.tick().await;
    }

    pub fn reset(&mut self) {
        self.rpc_interval = interval(Duration::from_millis(1000 / Self::RPC_LIMIT));
        self.api_interval = interval(Duration::from_millis(1000 / Self::API_LIMIT));
        self.tx_interval = interval(Duration::from_millis(1000 / Self::TX_LIMIT));
    }
}






#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ValidationMetrics {
    pub token: String,
    pub attempts: u32,
    pub total_time_ms: u64,
    pub supply_check: Option<u64>,
    pub liquidity_check: Option<f64>,
    pub mint_authority_check: Option<bool>,
    pub tokens_burnt_check: Option<bool>,
    pub error_message: Option<String>,
    pub timestamp: chrono::DateTime<Utc>,
    pub validation_history: Vec<ValidationAttempt>,
}

impl Default for ValidationMetrics {
    fn default() -> Self {
        Self {
            token: String::new(),
            attempts: 0,
            total_time_ms: 0,
            supply_check: None,
            liquidity_check: None,
            mint_authority_check: None,
            tokens_burnt_check: None,
            error_message: None,
            timestamp: Utc::now(),
            validation_history: Vec::new(),
        }
    }
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ValidationAttempt {
    pub attempt_number: u32,
    pub timestamp: chrono::DateTime<Utc>,
    pub success: bool,
    pub response_time_ms: u64,
    pub metrics: HashMap<String, String>,
}

#[derive(Clone)]
pub struct Config {
    pub rpc_url: String,
    pub ws_url: String,
    pub fallback_ws: String,
    pub helius_api_key: String,
}

#[derive(Clone, Debug)]
pub enum TradeStatus {
    Active,
    PendingClose {
        reason: String,
        timestamp: chrono::DateTime<Utc>,
    },
    Closed {
        final_pl: f64,
        timestamp: chrono::DateTime<Utc>,
    },
    Failed {
        error: String,
        timestamp: chrono::DateTime<Utc>,
    },
}

#[derive(Clone, Debug)]
pub struct Trade {
    pub entry_price: f64,
    pub current_price: f64,
    pub amount: u64,
    pub profit_loss: f64,
    pub timestamp: i64,
    pub take_profit: f64,
    pub stop_loss: f64,
    pub attempts: u32,
    pub last_update: Instant,
    pub status: TradeStatus,
    pub execution_history: Vec<TradeExecution>,
}

#[derive(Clone, Debug)]
pub struct TradeExecution {
    pub timestamp: chrono::DateTime<Utc>,
    pub action: String,
    pub price: f64,
    pub amount: u64,
    pub success: bool,
    pub execution_time_ms: u64,
    pub error: Option<String>,
}

#[derive(Clone, Debug)]
pub struct TradeMetrics {
    pub timestamp: i64,
    pub detection_time: Duration,
    pub validation_time: Duration,
    pub execution_time: Duration,
    pub total_time: Duration,
    pub attempts: u8,
    pub success: bool,
    pub error: Option<String>,
    pub price_impact: Option<f64>,
    pub network_latency: Duration,
}

#[derive(Clone)]
pub struct PoolStatus {
    pub token: String,
    pub creation_time: Instant,
    pub last_validation: Instant,
    pub validation_attempts: u8,
    pub liquidity: f64,
    pub is_tradeable: bool,
    pub has_failed: bool,
    pub error_reason: Option<String>,
    pub validation_history: Vec<ValidationAttempt>,
    pub market_metrics: MarketMetrics,
}

#[derive(Clone, Debug)]
pub struct MarketMetrics {
    pub volume_24h: f64,
    pub price_change_24h: f64,
    pub total_liquidity: f64,
    pub num_holders: u64,
    pub last_update: chrono::DateTime<Utc>,
}

#[derive(Debug, Clone)]
pub struct PreparedTradeData {
    pub trade_data: Vec<u8>,
    pub blockhash: Option<Hash>,
    pub priority_fee: u64,
}

#[derive(Debug, Default)]
pub struct PerformanceMetrics {
    pub total_validations: u64,
    pub successful_validations: u64,
    pub total_trades: u64,
    pub successful_trades: u64,
    pub average_execution_time: Duration,
    pub peak_tps: u32,
    pub last_reset: chrono::DateTime<Utc>,
}

pub struct Bot {
    pub config: Config,
    pub keypair: Keypair,
    pub http_client: Client,
    pub active_trades: DashMap<String, Trade>,
    pub rpc_client: RpcClient,
    pub fallback_rpc_client: RpcClient,
    pub jupiter_program_id: Pubkey,
    pub pool_status: Arc<DashMap<String, PoolStatus>>,
    pub trade_metrics: Arc<RwLock<Vec<TradeMetrics>>>,
    pub current_tps: Arc<RwLock<u32>>,
    pub validation_cache: Arc<DashMap<String, ValidationMetrics>>,
    pub performance_metrics: Arc<RwLock<PerformanceMetrics>>,
    pub rate_limiter: RateLimiter,  // Add this line    
}

impl Trade {
    pub fn new(entry_price: f64, amount: u64) -> Self {
        Self {
            entry_price,
            current_price: entry_price,
            amount,
            profit_loss: 0.0,
            timestamp: Utc::now().timestamp(),
            take_profit: TAKE_PROFIT,
            stop_loss: STOP_LOSS,
            attempts: 0,
            last_update: Instant::now(),
            status: TradeStatus::Active,
            execution_history: Vec::new(),
        }
    }

    pub fn calculate_pl(&self) -> f64 {
        ((self.current_price - self.entry_price) / self.entry_price) * 100.0
    }

    pub fn should_close(&self) -> bool {
        let current_pl = self.calculate_pl();
        current_pl >= self.take_profit || current_pl <= self.stop_loss
    }

    pub fn update_status(&mut self, new_price: f64) -> TradeStatus {
        self.current_price = new_price;
        self.profit_loss = self.calculate_pl();
        
        let status = if self.should_close() {
            TradeStatus::PendingClose {
                reason: if self.profit_loss >= self.take_profit {
                    "Take Profit".to_string()
                } else {
                    "Stop Loss".to_string()
                },
                timestamp: Utc::now(),
            }
        } else {
            TradeStatus::Active
        };

        self.status = status.clone();
        status
    }

    pub fn add_execution(&mut self, execution: TradeExecution) {
        self.execution_history.push(execution);
    }
}

#[allow(dead_code)]
impl Bot {
    pub async fn is_rate_limited(&self) -> bool {
        *self.rate_limiter.is_limited.read().await
    }

    pub async fn reset_rate_limits(&self) {
        *self.rate_limiter.is_limited.write().await = false;
    }

    async fn execute_rapid_trade_optimized(
        &self,
        token: &str,
        is_buy: bool,
        priority_fee: u64,
        _rpc_type: &str,
        prepared_data: Option<&PreparedTradeData>
    ) -> Result<String> {
        let client = self.select_rpc_client().await;
        let amount = if is_buy { TRADE_AMOUNT } else { 0 };
        
        let quote = self.get_jupiter_quote_enhanced(token, SOL_MINT, amount).await?;
        let blockhash = match prepared_data.and_then(|data| data.blockhash) {
            Some(hash) => hash,
            None => self.get_latest_blockhash_with_retries().await?,
        };

        let priority_ix = ComputeBudgetInstruction::set_compute_unit_price(priority_fee);
        let swap_data = self.prepare_swap_data_enhanced(&quote).await?;
        let tx_data = BASE64.decode(&swap_data)?;

        let swap_ix = Instruction {
            program_id: self.jupiter_program_id,
            accounts: vec![],
            data: tx_data,
        };

        let message = SolanaMessage::new(
            &[priority_ix, swap_ix],
            Some(&self.keypair.pubkey())
        );

        let mut transaction = Transaction::new_unsigned(message);
        transaction.sign(&[&self.keypair], blockhash);

        let signature = client.send_transaction(&transaction).await?;
        
        if is_buy {
            let trade = Trade::new(
                self.get_token_price(token).await?,
                amount
            );
            self.active_trades.insert(token.to_string(), trade);
        }

        Ok(signature.to_string())
    }


    pub async fn get_token_price(&self, token: &str) -> Result<f64> {
        let request = json!({
            "jsonrpc": "2.0",
            "id": 1,
            "method": "getTokenPrice",
            "params": [
                token,
                {
                    "source": "raydium",
                    "priority": "high"
                }
            ]
        });

        let response = self
            .http_client
            .post(&self.config.rpc_url)
            .header(
                "Authorization",
                format!("Bearer {}", self.config.helius_api_key),
            )
            .json(&request)
            .send()
            .await?
            .json::<Value>()
            .await?;

        response["result"]["price"]
            .as_f64()
            .ok_or_else(|| anyhow!("Invalid price data"))
    }

    async fn get_token_price_fallback(&self, token: &str) -> Result<f64> {
        let request = json!({
            "jsonrpc": "2.0",
            "id": 1,
            "method": "getTokenPrice",
            "params": [token]
        });

        let response = self
            .http_client
            .post(self.config.fallback_ws.replace("wss://", "https://"))  // Fixed needless borrow
            .json(&request)
            .send()
            .await?
            .json::<Value>()
            .await?;

        response["result"]["price"]
            .as_f64()
            .ok_or_else(|| anyhow!("Invalid price data"))
    }

    // Making these methods public to avoid dead code warnings
    pub async fn pre_validate_token(&self, token: &str) -> Result<bool> {
        let pubkey = Pubkey::from_str(token)?;
        let client = self.select_rpc_client().await;

        if let Ok(data) = client.get_account_data(&pubkey).await {
            Ok(data.len() >= MIN_ACCOUNT_DATA_LEN)
        } else {
            Ok(false)
        }
    }

    pub async fn update_trade_metrics(&self, success: bool, duration: Duration) {
        let mut metrics = self.performance_metrics.write().await;
        metrics.total_trades += 1;
        if success {
            metrics.successful_trades += 1;
        }
        
        let total_time = metrics.average_execution_time.as_nanos() as u64 * (metrics.total_trades - 1);
        let new_average = Duration::from_nanos(
            (total_time + duration.as_nanos() as u64) / metrics.total_trades
        );
        metrics.average_execution_time = new_average;
    }

    pub async fn log_error_metrics(&self, token: &str, error_type: &str, error: impl std::fmt::Display) {
        warn!("❌ {} error for {}: {}", error_type, token, error);
        let mut metrics = self.performance_metrics.write().await;
        metrics.last_reset = Utc::now();
    }

    pub async fn display_market_event(&self, event_type: &str, message: &str) {
        let timestamp = Utc::now().format("%H:%M:%S.%3f");
        let (color, symbol) = match event_type {
            "DETECTED" => ("\x1b[36m", "🔍"),
            "SUCCESS" => ("\x1b[32m", "✅"),
            "ERROR" => ("\x1b[31m", "❌"),
            "EXECUTE" => ("\x1b[35m", "⚡"),
            _ => ("\x1b[37m", "ℹ️"),
        };

        println!(
            "{}\x1b[1m[{}] {} {}\x1b[0m {}",
            color, timestamp, symbol, event_type, message
        );
    }
    pub async fn new(config: Config, keypair: Keypair) -> Result<Self> {
        let rpc_url = config.rpc_url.clone();
        let fallback_rpc = config.fallback_ws.replace("wss://", "https://");
        
        // Initialize rate limiter with default config
        let rate_limiter = RateLimiter::new(&HeliusRateConfig::default());
    
        Ok(Self {
            config: config.clone(),
            keypair,
            http_client: Client::builder()
                .timeout(Duration::from_secs(5))
                .build()?,
            active_trades: DashMap::new(),
            rpc_client: RpcClient::new(rpc_url),
            fallback_rpc_client: RpcClient::new(fallback_rpc),
            jupiter_program_id: Pubkey::from_str("JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB")?,
            pool_status: Arc::new(DashMap::new()),
            trade_metrics: Arc::new(RwLock::new(Vec::new())),
            current_tps: Arc::new(RwLock::new(0)),
            validation_cache: Arc::new(DashMap::new()),
            performance_metrics: Arc::new(RwLock::new(PerformanceMetrics::default())),
            rate_limiter,
        })
    }
    

    async fn select_rpc_client(&self) -> &RpcClient {
        let current_tps = *self.current_tps.read().await;
        if current_tps > RPC_SWITCH_THRESHOLD {
            &self.fallback_rpc_client
        } else {
            &self.rpc_client
        }
    }

    async fn get_token_price_parallel(&self, token: &str) -> Result<f64> {
        let (primary, fallback) = tokio::join!(
            self.get_token_price(token),
            self.get_token_price_fallback(token)
        );

        primary.or(fallback)
    }

    async fn get_token_price_with_enhanced_retries(&self, token: &str) -> Result<f64> {
        let delays = [0, 25, 50, 100];
        let mut last_error = None;

        for (attempt, &delay) in delays.iter().enumerate() {
            if attempt > 0 {
                sleep(Duration::from_millis(delay)).await;
            }

            match self.get_token_price(token).await {
                Ok(price) => return Ok(price),
                Err(e) => {
                    match self.get_token_price_fallback(token).await {
                        Ok(price) => return Ok(price),
                        Err(fallback_e) => {
                            last_error = Some(format!("Primary: {}, Fallback: {}", e, fallback_e));
                        }
                    }
                }
            }
        }

        Err(anyhow!("Price fetch failed: {}", last_error.unwrap_or_default()))
    }

    pub async fn get_jupiter_quote_enhanced(
        &self,
        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 = self.http_client
            .get(&url)
            .timeout(Duration::from_secs(2))
            .send()
            .await?
            .json::<Value>()
            .await?;

        if let Some(error) = response.get("error") {
            return Err(anyhow!("Jupiter API error: {}", error));
        }

        Ok(response)
    }

    async fn prepare_swap_data_enhanced(&self, quote: &Value) -> Result<String> {
        let swap_request = json!({
            "quoteResponse": quote,
            "userPublicKey": self.keypair.pubkey().to_string(),
            "computeUnitPriceMicroLamports": PRIORITY_FEE,
            "priorityFeeLamports": PRIORITY_FEE,
            "asLegacyTransaction": false,
            "maxAccounts": 64,
            "useSharedAccounts": true,
            "useTokenLedger": false
        });

        let response = self.http_client
            .post(format!("{}/swap", JUPITER_API))
            .json(&swap_request)
            .timeout(Duration::from_secs(2))
            .send()
            .await?
            .json::<Value>()
            .await?;

        response["swapTransaction"]
            .as_str()
            .ok_or_else(|| anyhow!("Invalid swap data"))
            .map(String::from)
    }

    pub fn should_execute_trade(&self, token: &str, price: f64) -> bool {
        price > 0.0
            && price < 0.01
            && !self.active_trades.contains_key(token)
            && self.active_trades.len() < MAX_TRADES
    }

    async fn get_latest_blockhash_with_retries(&self) -> Result<Hash> {
        for attempt in 0..3 {
            match self.rpc_client.get_latest_blockhash().await {
                Ok(hash) => return Ok(hash),
                Err(_e) if attempt < 2 => {
                    sleep(Duration::from_millis(50 * (attempt + 1) as u64)).await;
                    continue;
                }
                Err(e) => return Err(anyhow!("Failed to get blockhash: {}", e))
            }
        }
        Err(anyhow!("Failed to get blockhash after retries"))
    }
    async fn validate_pool_comprehensive(&self, token: &str) -> Result<(bool, ValidationMetrics)> {
        let start_time = Instant::now();
        let mut metrics = ValidationMetrics {
            token: token.to_string(),
            attempts: 0,
            total_time_ms: 0,
            supply_check: None,
            liquidity_check: None,
            mint_authority_check: None,
            tokens_burnt_check: None,
            error_message: None,
            timestamp: Utc::now(),
            validation_history: Vec::new(),
        };

        if let Some(cached) = self.validation_cache.get(token) {
            if (Utc::now().timestamp() - cached.timestamp.timestamp()) < CACHE_DURATION {
                return Ok((true, cached.clone()));
            }
        }

        let token_pubkey = Pubkey::from_str(token).map_err(|e| {
            let error = format!("Invalid token pubkey: {}", e);
            metrics.error_message = Some(error.clone());
            anyhow!(error)
        })?;

        let mut backoff = Duration::from_millis(INITIAL_RETRY_DELAY);
        let validation_start = Instant::now();

        while metrics.attempts < MAX_RETRIES && validation_start.elapsed() < VALIDATION_TIMEOUT {
            metrics.attempts += 1;
            debug!("Validation attempt {} for token {}", metrics.attempts, token);

            let client = self.select_rpc_client().await;
            
            let (supply_result, liquidity_result, tokens_burnt_result, mint_authority_result) = tokio::join!(
                self.get_token_supply_with_retries(&token_pubkey, client),
                self.get_pool_liquidity_with_retries(&token_pubkey, client),
                self.check_tokens_burnt_with_retries(token, client),
                self.check_mint_authority_with_retries(&token_pubkey, client)
            );

            let attempt = ValidationAttempt {
                attempt_number: metrics.attempts,
                timestamp: Utc::now(),
                success: supply_result.is_ok() && liquidity_result.is_ok() && 
                        tokens_burnt_result.is_ok() && mint_authority_result.is_ok(),
                response_time_ms: validation_start.elapsed().as_millis() as u64,
                metrics: HashMap::new(),
            };
            metrics.validation_history.push(attempt);

            match (&supply_result, &liquidity_result, &tokens_burnt_result, &mint_authority_result) {
                (Ok(supply), Ok(liquidity), Ok(burnt), Ok(mint)) => {
                    metrics.supply_check = Some(*supply);
                    metrics.liquidity_check = Some(*liquidity);
                    metrics.tokens_burnt_check = Some(*burnt);
                    metrics.mint_authority_check = Some(*mint);

                    if self.evaluate_validation_results(&metrics) {
                        metrics.total_time_ms = start_time.elapsed().as_millis() as u64;
                        self.validation_cache.insert(token.to_string(), metrics.clone());
                        self.update_pool_status(token, &metrics).await;
                        return Ok((true, metrics));
                    }
                }
                _ => {
                    if self.should_continue_validation(
                        &supply_result,
                        &liquidity_result,
                        &tokens_burnt_result,
                        &mint_authority_result,
                    ).await {
                        sleep(backoff).await;
                        backoff = Duration::from_millis(
                            (backoff.as_millis() as f64 * 1.5)
                                .min(MAX_RETRY_DELAY as f64) as u64
                        );
                        continue;
                    }
                }
            }
        }

        metrics.total_time_ms = start_time.elapsed().as_millis() as u64;
        metrics.error_message = Some(format!(
            "Validation failed after {} attempts",
            metrics.attempts
        ));

        Ok((false, metrics))
    }

    async fn get_token_supply_with_retries(&self, token_pubkey: &Pubkey, client: &RpcClient) -> Result<u64> {
        let mut attempts = 0;
        let max_attempts = 3;

        while attempts < max_attempts {
            match client.get_token_supply(token_pubkey).await {
                Ok(supply) => return Ok(supply.ui_amount.unwrap_or(0.0) as u64),
                Err(e) => {
                    attempts += 1;
                    if attempts < max_attempts {
                        sleep(Duration::from_millis(100 * attempts as u64)).await;
                    } else {
                        return Err(anyhow!("Supply check failed: {}", e));
                    }
                }
            }
        }

        Err(anyhow!("Supply check failed after {} attempts", max_attempts))
    }

    async fn get_pool_liquidity_with_retries(&self, token_pubkey: &Pubkey, client: &RpcClient) -> Result<f64> {
        let mut attempts = 0;
        let max_attempts = 3;

        while attempts < max_attempts {
            match client.get_account_data(token_pubkey).await {
                Ok(data) if data.len() >= MIN_ACCOUNT_DATA_LEN => {
                    let liquidity_bytes = &data[8..16];
                    let liquidity_value = u64::from_le_bytes(liquidity_bytes.try_into()?);
                    return Ok((liquidity_value as f64) / 1_000_000.0);
                }
                Ok(_) => return Ok(0.0),
                Err(e) => {
                    attempts += 1;
                    if e.to_string().contains("AccountNotFound") && attempts < max_attempts {
                        sleep(Duration::from_millis(200 * attempts as u64)).await;
                    } else {
                        return Err(anyhow!("Liquidity check failed: {}", e));
                    }
                }
            }
        }

        Err(anyhow!("Could not determine pool liquidity after {} attempts", max_attempts))
    }

    async fn check_tokens_burnt_with_retries(&self, token: &str, client: &RpcClient) -> Result<bool> {
        let token_pubkey = Pubkey::from_str(token)?;
        let mut attempts = 0;
        let max_attempts = 3;

        while attempts < max_attempts {
            match client.get_account(&token_pubkey).await {
                Ok(account) => {
                    return Ok(account.data.is_empty() || account.data.first() == Some(&0));
                }
                Err(e) => {
                    attempts += 1;
                    if attempts < max_attempts {
                        sleep(Duration::from_millis(100 * attempts as u64)).await;
                    } else {
                        return Err(anyhow!("Burn check failed: {}", e));
                    }
                }
            }
        }

        Ok(false)
    }

    async fn check_mint_authority_with_retries(&self, token_pubkey: &Pubkey, client: &RpcClient) -> Result<bool> {
        let mut attempts = 0;
        let max_attempts = 3;

        while attempts < max_attempts {
            match client.get_account(token_pubkey).await {
                Ok(account) => {
                    return Ok(account.data.len() > 4);
                }
                Err(e) => {
                    attempts += 1;
                    if attempts < max_attempts {
                        sleep(Duration::from_millis(100 * attempts as u64)).await;
                    } else {
                        return Err(anyhow!("Mint authority check failed: {}", e));
                    }
                }
            }
        }

        Ok(false)
    }

    pub async fn monitor_positions_enhanced(&self) -> Result<()> {
        let positions: Vec<_> = self.active_trades.iter()
            .map(|entry| (entry.key().clone(), entry.value().clone()))
            .collect();

        for (token, trade_data) in positions {
            if trade_data.last_update.elapsed() < Duration::from_millis(500) {
                continue;
            }

            if let Ok(current_price) = self.get_token_price(&token).await {
                if let Some(mut trade) = self.active_trades.get_mut(&token) {
                    match trade.update_status(current_price) {
                        TradeStatus::PendingClose { reason, timestamp } => {
                            info!(
                                "🔄 Closing position for {} - Reason: {}",
                                token,
                                reason
                            );

                            match self.execute_rapid_trade_optimized(
                                &token,
                                false,
                                PRIORITY_FEE * 2,
                                "primary",
                                None
                            ).await {
                                Ok(_) => {
                                    trade.status = TradeStatus::Closed {
                                        final_pl: trade.calculate_pl(),
                                        timestamp,
                                    };
                                }
                                Err(e) => {
                                    error!("Failed to close position: {}", e);
                                    trade.status = TradeStatus::Failed {
                                        error: e.to_string(),
                                        timestamp,
                                    };
                                }
                            }
                        }
                        TradeStatus::Active => {
                            debug!(
                                "Position Update - Token: {}, P/L: {:.2}%",
                                token,
                                trade.calculate_pl()
                            );
                        }
                        _ => {}
                    }
                }
            }
        }

        Ok(())
    }

    pub async fn handle_websocket_stream(&self) -> Result<()> {
        let (ws_stream, _) = connect_async(&self.config.ws_url).await?;
        let (_, mut read) = ws_stream.split();
    
        while let Some(msg) = read.next().await {
            match msg {
                Ok(Message::Text(event)) => {
                    let start_time = Instant::now();
                    let event_data = serde_json::from_str::<Value>(&event)?;
    
                    if let Some(token_address) = self.extract_early_token_fast(&event_data) {
                        info!("🎯 WS Token Detection: {} (Time: {}ms)", 
                            token_address, 
                            start_time.elapsed().as_millis()
                        );
    
                        // Parallel WebSocket validation
                        let validation_result = tokio::join!(
                            self.validate_ws_quick(&token_address, &event_data),
                            self.validate_ws_comprehensive(&token_address, &event_data)
                        );
    
                        match validation_result {
                            (Ok(true), _) | (_, Ok(true)) => {
                                let trade_data = self.extract_trade_data(&event_data)?;
                                let price = self.extract_price_from_ws(&event_data)?;
    
                                if self.should_execute_trade(&token_address, price) {
                                    self.execute_rapid_trade_optimized(
                                        &token_address,
                                        true,
                                        PRIORITY_FEE * 2,
                                        "ws_stream",
                                        Some(&PreparedTradeData {
                                            trade_data,
                                            blockhash: None,
                                            priority_fee: PRIORITY_FEE * 2,
                                        })
                                    ).await?;
                                }
                            }
                            _ => continue
                        }
                    }
                }
                Ok(Message::Close(_)) => break,
                _ => continue,
            }
        }
        Ok(())
    }
    
    async fn validate_ws_quick(&self, token: &str, data: &Value) -> Result<bool> {
        let account_data = self.extract_account_data(data)?;
        let liquidity = self.calculate_liquidity(&account_data)?;
            
        Ok(liquidity >= MIN_LIQUIDITY * 0.8)
    }
    
    async fn validate_ws_comprehensive(&self, token: &str, data: &Value) -> Result<bool> {
        let account_data = self.extract_account_data(data)?;
            
        let liquidity = self.calculate_liquidity(&account_data)?;
        let supply = self.extract_supply(&account_data)?;
        let mint_status = self.check_mint_status(&account_data)?;
    
        Ok(
            liquidity >= MIN_LIQUIDITY &&
            supply >= SUPPLY_MIN &&
            supply <= SUPPLY_MAX &&
            mint_status
        )
    }
    
    fn extract_trade_data(&self, data: &Value) -> Result<Vec<u8>> {
        let account_data = data
            .get("params")
            .and_then(|p| p.get("result"))
            .and_then(|r| r.get("value"))
            .and_then(|v| v.get("account"))
            .and_then(|a| a.get("data"))
            .ok_or_else(|| anyhow!("Missing trade data"))?;
    
        Ok(BASE64.decode(account_data.as_str().unwrap_or_default())?)
    }
    
    fn extract_price_from_ws(&self, data: &Value) -> Result<f64> {
        data.get("params")
            .and_then(|p| p.get("result"))
            .and_then(|r| r.get("value"))
            .and_then(|v| v.get("price"))
            .and_then(|p| p.as_f64())
            .ok_or_else(|| anyhow!("Missing price data"))
        }
    }
    fn extract_account_data(&self, data: &Value) -> Result<Vec<u8>> {
        let account_data = data
            .get("params")
            .and_then(|p| p.get("result"))
            .and_then(|r| r.get("value"))
            .and_then(|v| v.get("account"))
            .and_then(|a| a.get("data"))
            .and_then(|d| d.as_str())
            .ok_or_else(|| anyhow!("Missing account data"))?;

        BASE64.decode(account_data).map_err(|e| anyhow!("Decode error: {}", e))
    }

    fn calculate_liquidity(&self, account_data: &[u8]) -> Result<f64> {
        if account_data.len() < 16 {
            return Ok(0.0);
        }

        let liquidity_bytes = &account_data[8..16];
        let liquidity_value = u64::from_le_bytes(liquidity_bytes.try_into()?);
        Ok((liquidity_value as f64) / 1_000_000.0)
    }

    fn extract_supply(&self, account_data: &[u8]) -> Result<u64> {
        if account_data.len() < 36 {
            return Ok(0);
        }

        let supply_bytes = &account_data[36..44];
        Ok(u64::from_le_bytes(supply_bytes.try_into()?))
    }

    fn check_mint_status(&self, account_data: &[u8]) -> Result<bool> {
        if account_data.len() < 48 {
            return Ok(false);
        }

        // Check mint authority and freeze authority
        let mint_authority_bytes = &account_data[0..32];
        let freeze_authority_bytes = &account_data[32..64];
        
        let has_mint_authority = !mint_authority_bytes.iter().all(|&x| x == 0);
        let has_freeze_authority = !freeze_authority_bytes.iter().all(|&x| x == 0);

        Ok(!has_mint_authority && !has_freeze_authority)
    }

    fn extract_trade_data(&self, data: &Value) -> Result<Vec<u8>> {
        let account_data = data
            .get("params")
            .and_then(|p| p.get("result"))
            .and_then(|r| r.get("value"))
            .and_then(|v| v.get("account"))
            .and_then(|a| a.get("data"))
            .ok_or_else(|| anyhow!("Missing trade data"))?;

        let decoded = BASE64.decode(account_data.as_str().unwrap_or_default())?;
        
        // Extract specific trade data bytes
        let trade_data = if decoded.len() >= 96 {
            decoded[64..96].to_vec()
        } else {
            vec![]
        };

        Ok(trade_data)
    }

    fn extract_price_from_ws(&self, data: &Value) -> Result<f64> {
        // Enhanced price extraction with fallback calculations
        if let Some(price) = data
            .get("params")
            .and_then(|p| p.get("result"))
            .and_then(|r| r.get("value"))
            .and_then(|v| v.get("price"))
            .and_then(|p| p.as_f64()) 
        {
            Ok(price)
        } else {
            // Fallback price calculation from account data
            let account_data = self.extract_account_data(data)?;
            if account_data.len() >= 24 {
                let price_bytes = &account_data[16..24];
                let raw_price = u64::from_le_bytes(price_bytes.try_into()?);
                Ok((raw_price as f64) / 1_000_000.0)
            } else {
                Err(anyhow!("Missing price data"))
            }
        }
    }
    fn evaluate_validation_results(&self, metrics: &ValidationMetrics) -> bool {
        let supply_valid = metrics.supply_check
            .map(|s| (SUPPLY_MIN..=SUPPLY_MAX).contains(&s))
            .unwrap_or(false);

        let liquidity_valid = metrics.liquidity_check
            .map(|l| (MIN_LIQUIDITY..=MAX_LIQUIDITY).contains(&l))
            .unwrap_or(false);

        let mint_valid = !metrics.mint_authority_check.unwrap_or(true);
        let tokens_burnt = metrics.tokens_burnt_check.unwrap_or(false);

        supply_valid && liquidity_valid && mint_valid && tokens_burnt
    }

    async fn update_pool_status(&self, token: &str, metrics: &ValidationMetrics) {
        let status = PoolStatus {
            token: token.to_string(),
            creation_time: Instant::now(),
            last_validation: Instant::now(),
            validation_attempts: metrics.attempts as u8,
            liquidity: metrics.liquidity_check.unwrap_or(0.0),
            is_tradeable: true,
            has_failed: false,
            error_reason: None,
            validation_history: metrics.validation_history.clone(),
            market_metrics: MarketMetrics {
                volume_24h: 0.0,
                price_change_24h: 0.0,
                total_liquidity: metrics.liquidity_check.unwrap_or(0.0),
                num_holders: 0,
                last_update: Utc::now(),
            },
        };

        self.pool_status.insert(token.to_string(), status);
    }

    async fn should_continue_validation(
        &self,
        supply: &Result<u64>,
        liquidity: &Result<f64>,
        burnt: &Result<bool>,
        mint: &Result<bool>
    ) -> bool {
        let errors: Vec<String> = vec![
            supply.as_ref().err(),
            liquidity.as_ref().err(),
            burnt.as_ref().err(),
            mint.as_ref().err(),
        ].into_iter()
        .filter_map(|e| e.map(|err| err.to_string()))
        .collect();

        errors.iter().any(|e| 
            e.contains("AccountNotFound") || 
            e.contains("Connection refused") || 
            e.contains("rate limited")
        )
    }

    async fn validate_ws_quick(&self, _token: &str, data: &Value) -> Result<bool> {
        let account_data = self.extract_account_data(data)?;
        let liquidity = self.calculate_liquidity(&account_data)?;
        
        Ok(liquidity >= MIN_LIQUIDITY * 0.8)
    }

    async fn validate_ws_comprehensive(&self, _token: &str, data: &Value) -> Result<bool> {
        let account_data = self.extract_account_data(data)?;
        
        let (liquidity, supply, mint_status) = tokio::join!(
            async { self.calculate_liquidity(&account_data) },
            async { self.extract_supply(&account_data) },
            async { self.check_mint_status(&account_data) }
        );

        let supply_value = supply?;
        
        Ok(
            liquidity? >= MIN_LIQUIDITY &&
            supply_value >= SUPPLY_MIN &&
            supply_value <= SUPPLY_MAX &&
            mint_status? 
        )
    
    }
       fix this script and do not weaken code or lessen code or remove code or make place holders