Compiling solana_rust_bot v0.1.0 (C:\solana_rust_bot)
error: unexpected closing delimiter: `}`
   --> src/main.rs:945:1
    |
926 |     async fn main() -> Result<(), Box<dyn StdError + Send + Sync>> {
    |                                                                    - this opening brace...
...
943 |     }
    |     - ...matches this closing brace
944 |
945 | }
    | ^ unexpected closing delimiter

error: could not compile `solana_rust_bot` (bin "solana_rust_bot") due to 1 previous error
PS C:\solana_rust_bot> cargo build --release --jobs 14
   Compiling solana_rust_bot v0.1.0 (C:\solana_rust_bot)
error: unexpected end of macro invocation
   --> src/main.rs:408:28
    |
408 |           let swap_request = json!({
    |  ____________________________^
409 | |             "quoteResponse": quote,
410 | |             "userPublicKey": self.config.wallet.public_key,
411 | |             "wrapUnwrapSOL": true,
...   |
415 | |             "maxAccounts: 64"
416 | |         });
    | |__________^ missing tokens in macro arguments
    |
note: while trying to match `@`
   --> C:\Users\Orsen\.cargo\registry\src\index.crates.io-6f17d22bba15001f\serde_json-1.0.132\src\macros.rs:79:6
    |
79  |     (@array [$($elems:expr,)*]) => {
    |      ^
    = note: this error originates in the macro `$crate::json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0412]: cannot find type `BotState` in this scope
   --> src/main.rs:165:26
    |
165 |     pub state: Arc<Mutex<BotState>>,
    |                          ^^^^^^^^ not found in this scope
    |
help: you might be missing a type parameter
    |
160 | pub struct TradingBot<BotState> {
    |                      ++++++++++

error[E0422]: cannot find struct, variant or union type `BotState` in this scope
   --> src/main.rs:201:41
    |
201 |         let state = Arc::new(Mutex::new(BotState {
    |                                         ^^^^^^^^ not found in this scope

error[E0412]: cannot find type `BotState` in this scope
   --> src/main.rs:298:31
    |
298 |             let loaded_state: BotState = serde_json::from_str(&state_json)?;
    |                               ^^^^^^^^ not found in this scope

error[E0412]: cannot find type `BotState` in this scope
   --> src/main.rs:316:40
    |
316 |     pub fn print_status(&self, state: &BotState) {
    |                                        ^^^^^^^^ not found in this scope

error[E0405]: cannot find trait `StdError` in this scope
   --> src/main.rs:731:58
    |
731 |     async fn monitor_trades(&self) -> Result<(), Box<dyn StdError + Send + Sync>> {
    |                                                          ^^^^^^^^ not found in this scope
    |
help: consider importing this trait
    |
1   + use serde::ser::StdError;
    |

error[E0405]: cannot find trait `StdError` in this scope
   --> src/main.rs:749:78
    |
749 |     async fn update_trade_status(&self, trade: &Trade) -> Result<(), Box<dyn StdError + Send + Sync>> { 
    |                                                                              ^^^^^^^^ not found in this scope
    |
help: consider importing this trait
    |
1   + use serde::ser::StdError;
    |

error[E0405]: cannot find trait `StdError` in this scope
   --> src/main.rs:783:123
    |
783 | ...on: &str) -> Result<(), Box<dyn StdError + Send + Sync>> {
    |                                    ^^^^^^^^ not found in this scope
    |
help: consider importing this trait
    |
1   + use serde::ser::StdError;
    |

error[E0405]: cannot find trait `StdError` in this scope
   --> src/main.rs:831:50
    |
831 |     async fn run_ui(&self) -> Result<(), Box<dyn StdError + Send + Sync>> {
    |                                                  ^^^^^^^^ not found in this scope
    |
help: consider importing this trait
    |
1   + use serde::ser::StdError;
    |

error[E0405]: cannot find trait `StdError` in this scope
   --> src/main.rs:926:39
    |
926 | async fn main() -> Result<(), Box<dyn StdError + Send + Sync>> {
    |                                       ^^^^^^^^ not found in this scope
    |
help: consider importing this trait
    |
1   + use serde::ser::StdError;
    |

warning: unused import: `env_logger::Env`
  --> src/main.rs:11:5
   |
11 | use env_logger::Env;
   |     ^^^^^^^^^^^^^^^
   |
   = note: `#[warn(unused_imports)]` on by default

warning: unused import: `Level`
  --> src/main.rs:27:41
   |
27 | use tracing::{debug, error, info, warn, Level};
   |                                         ^^^^^

error[E0277]: `dyn StdError` cannot be sent between threads safely
   --> src/main.rs:192:77
    |
192 |         let wallet = Arc::new(read_keypair_file(&config.wallet.keypair_path)?);
    |                                                                             ^ `dyn StdError` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `dyn StdError`, which is required by `Result<TradingBot, Box<dyn StdError + std::marker::Send + Sync>>: FromResidual<Result<std::convert::Infallible, Box<dyn StdError>>>`
    = help: the trait `FromResidual<Result<std::convert::Infallible, E>>` is implemented for `Result<T, F>`   
    = note: required for `Unique<dyn StdError>` to implement `std::marker::Send`
note: required because it appears within the type `Box<dyn StdError>`
   --> C:\Users\Orsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\alloc\src\boxed.rs:235:12
    |
235 | pub struct Box<
    |            ^^^
    = note: required for `Box<dyn StdError + std::marker::Send + Sync>` to implement `From<Box<dyn StdError>>`
    = note: required for `Result<TradingBot, Box<dyn StdError + std::marker::Send + Sync>>` to implement `FromResidual<Result<std::convert::Infallible, Box<dyn StdError>>>`

error[E0277]: `dyn StdError` cannot be shared between threads safely
   --> src/main.rs:192:77
    |
192 |         let wallet = Arc::new(read_keypair_file(&config.wallet.keypair_path)?);
    |                                                                             ^ `dyn StdError` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `dyn StdError`, which is required by `Result<TradingBot, Box<dyn StdError + std::marker::Send + Sync>>: FromResidual<Result<std::convert::Infallible, Box<dyn StdError>>>`
    = help: the trait `FromResidual<Result<std::convert::Infallible, E>>` is implemented for `Result<T, F>`   
    = note: required for `Unique<dyn StdError>` to implement `Sync`
note: required because it appears within the type `Box<dyn StdError>`
   --> C:\Users\Orsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\alloc\src\boxed.rs:235:12
    |
235 | pub struct Box<
    |            ^^^
    = note: required for `Box<dyn StdError + std::marker::Send + Sync>` to implement `From<Box<dyn StdError>>`
    = note: required for `Result<TradingBot, Box<dyn StdError + std::marker::Send + Sync>>` to implement `FromResidual<Result<std::convert::Infallible, Box<dyn StdError>>>`

error[E0277]: the size for values of type `dyn StdError` cannot be known at compilation time
   --> src/main.rs:192:77
    |
192 |         let wallet = Arc::new(read_keypair_file(&config.wallet.keypair_path)?);
    |                                                                             ^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `dyn StdError`, which is required by `Result<TradingBot, Box<dyn StdError + std::marker::Send + Sync>>: FromResidual<Result<std::convert::Infallible, Box<dyn StdError>>>`
    = help: the trait `FromResidual<Result<std::convert::Infallible, E>>` is implemented for `Result<T, F>`   
    = note: required for `Box<dyn StdError>` to implement `StdError`
    = note: required for `Box<dyn StdError + std::marker::Send + Sync>` to implement `From<Box<dyn StdError>>`
    = note: required for `Result<TradingBot, Box<dyn StdError + std::marker::Send + Sync>>` to implement `FromResidual<Result<std::convert::Infallible, Box<dyn StdError>>>`

error[E0599]: no method named `try_pubkey` found for struct `Arc<Keypair>` in the current scope
   --> src/main.rs:195:36
    |
195 |         let loaded_pubkey = wallet.try_pubkey().to_string();
    |                                    ^^^^^^^^^^
    |
   ::: C:\Users\Orsen\.cargo\registry\src\index.crates.io-6f17d22bba15001f\solana-sdk-1.18.26\src\signer\mod.rs:76:8
    |
76  |     fn try_pubkey(&self) -> Result<Pubkey, SignerError>;
    |        ---------- the method is available for `Arc<Keypair>` here
    |
    = help: items from traits can only be used if the trait is in scope
help: trait `Signer` which provides `try_pubkey` is implemented but not in scope; perhaps you want to import it
    |
1   + use solana_sdk::signature::Signer;
    |
help: there is a method `pubkey` with a similar name
    |
195 |         let loaded_pubkey = wallet.pubkey().to_string();
    |                                    ~~~~~~

error[E0308]: mismatched types
   --> src/main.rs:197:24
    |
197 |               return Err(anyhow!("Wallet mismatch: loaded {} but config specified {}",
    |  ____________________---_^
    | |                    |
    | |                    arguments to this enum variant are incorrect
198 | |                 loaded_pubkey, config.wallet.public_key));
    | |________________________________________________________^ expected `Box<dyn Error + Send + Sync>`, found `Error`
    |
    = note: expected struct `Box<dyn StdError + std::marker::Send + Sync>`
               found struct `anyhow::Error`
help: the type constructed contains `anyhow::Error` due to the type of the argument passed
   --> src/main.rs:197:20
    |
197 |                return Err(anyhow!("Wallet mismatch: loaded {} but config specified {}",
    |   ____________________^   -
    |  |________________________|
198 | ||                 loaded_pubkey, config.wallet.public_key));
    | ||________________________________________________________-^
    | |_________________________________________________________|
    |                                                           this argument influences the type of `Err`    
note: tuple variant defined here
   --> C:\Users\Orsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\result.rs:536:5
    |
536 |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
    |     ^^^
help: call `Into::into` on this expression to convert `anyhow::Error` into `Box<dyn StdError + std::marker::Send + Sync>`
    |
198 |                 loaded_pubkey, config.wallet.public_key).into());
    |                                                         +++++++

error[E0599]: no method named `pubkey` found for struct `Arc<Keypair>` in the current scope
   --> src/main.rs:258:64
    |
258 |         let balance = self.rpc_client.get_balance(&self.wallet.pubkey())?;
    |                                                                ^^^^^^
    |
   ::: C:\Users\Orsen\.cargo\registry\src\index.crates.io-6f17d22bba15001f\solana-sdk-1.18.26\src\signer\mod.rs:72:8
    |
72  |     fn pubkey(&self) -> Pubkey {
    |        ------ the method is available for `Arc<Keypair>` here
    |
    = help: items from traits can only be used if the trait is in scope
help: trait `Signer` which provides `pubkey` is implemented but not in scope; perhaps you want to import it   
    |
1   + use solana_sdk::signature::Signer;
    |
help: there is a method `try_pubkey` with a similar name
    |
258 |         let balance = self.rpc_client.get_balance(&self.wallet.try_pubkey())?;
    |                                                                ~~~~~~~~~~

error[E0610]: `u64` is a primitive type and therefore doesn't have fields
   --> src/main.rs:259:35
    |
259 |         let sol_balance = balance.ui_amount.unwrap_or_default() as f64 / 1e9;
    |                                   ^^^^^^^^^

error[E0308]: mismatched types
   --> src/main.rs:265:24
    |
265 |               return Err(anyhow!(
    |  ____________________---_^
    | |                    |
    | |                    arguments to this enum variant are incorrect
266 | |                 "Insufficient SOL balance. Need: {} SOL, Have: {} SOL",
267 | |                 min_required,
268 | |                 sol_balance
269 | |             ));
    | |_____________^ expected `Box<dyn Error + Send + Sync>`, found `Error`
    |
    = note: expected struct `Box<dyn StdError + std::marker::Send + Sync>`
               found struct `anyhow::Error`
help: the type constructed contains `anyhow::Error` due to the type of the argument passed
   --> src/main.rs:265:20
    |
265 |                return Err(anyhow!(
    |   ____________________^   -
    |  |________________________|
266 | ||                 "Insufficient SOL balance. Need: {} SOL, Have: {} SOL",
267 | ||                 min_required,
268 | ||                 sol_balance
269 | ||             ));
    | ||_____________-^
    | |______________|
    |                this argument influences the type of `Err`
note: tuple variant defined here
   --> C:\Users\Orsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\result.rs:536:5
    |
536 |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
    |     ^^^
help: call `Into::into` on this expression to convert `anyhow::Error` into `Box<dyn StdError + std::marker::Send + Sync>`
    |
269 |             ).into());
    |              +++++++

error[E0308]: mismatched types
   --> src/main.rs:280:24
    |
280 |             return Err(anyhow!("Jupiter API connection failed"));
    |                    --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Error + Send + Sync>`, found `Error`
    |                    |
    |                    arguments to this enum variant are incorrect
    |
    = note: expected struct `Box<dyn StdError + std::marker::Send + Sync>`
               found struct `anyhow::Error`
help: the type constructed contains `anyhow::Error` due to the type of the argument passed
   --> src/main.rs:280:20
    |
280 |             return Err(anyhow!("Jupiter API connection failed"));
    |                    ^^^^----------------------------------------^
    |                        |
    |                        this argument influences the type of `Err`
note: tuple variant defined here
   --> C:\Users\Orsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\result.rs:536:5
    |
536 |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
    |     ^^^
help: call `Into::into` on this expression to convert `anyhow::Error` into `Box<dyn StdError + std::marker::Send + Sync>`
    |
280 |             return Err(anyhow!("Jupiter API connection failed").into());
    |                                                                +++++++

error[E0308]: mismatched types
   --> src/main.rs:366:24
    |
366 |             return Err(anyhow!("Slippage too high: {:.2}%", slippage));
    |                    --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Error + Send + Sync>`, found `Error`
    |                    |
    |                    arguments to this enum variant are incorrect
    |
    = note: expected struct `Box<dyn StdError + std::marker::Send + Sync>`
               found struct `anyhow::Error`
help: the type constructed contains `anyhow::Error` due to the type of the argument passed
   --> src/main.rs:366:20
    |
366 |             return Err(anyhow!("Slippage too high: {:.2}%", slippage));
    |                    ^^^^----------------------------------------------^
    |                        |
    |                        this argument influences the type of `Err`
note: tuple variant defined here
   --> C:\Users\Orsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\result.rs:536:5
    |
536 |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
    |     ^^^
help: call `Into::into` on this expression to convert `anyhow::Error` into `Box<dyn StdError + std::marker::Send + Sync>`
    |
366 |             return Err(anyhow!("Slippage too high: {:.2}%", slippage).into());
    |                                                                      +++++++

error[E0308]: mismatched types
   --> src/main.rs:400:28
    |
400 |                 return Err(anyhow!("No valid routes found for trade"));
    |                        --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Error + Send + Sync>`, found `Error`
    |                        |
    |                        arguments to this enum variant are incorrect
    |
    = note: expected struct `Box<dyn StdError + std::marker::Send + Sync>`
               found struct `anyhow::Error`
help: the type constructed contains `anyhow::Error` due to the type of the argument passed
   --> src/main.rs:400:24
    |
400 |                 return Err(anyhow!("No valid routes found for trade"));
    |                        ^^^^------------------------------------------^
    |                            |
    |                            this argument influences the type of `Err`
note: tuple variant defined here
   --> C:\Users\Orsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\result.rs:536:5
    |
536 |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
    |     ^^^
help: call `Into::into` on this expression to convert `anyhow::Error` into `Box<dyn StdError + std::marker::Send + Sync>`
    |
400 |                 return Err(anyhow!("No valid routes found for trade").into());
    |                                                                      +++++++

error[E0308]: mismatched types
   --> src/main.rs:432:21
    |
432 |                 Err(anyhow!("No swap transaction found in response"))
    |                 --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Error + Send + Sync>`, found `Error`
    |                 |
    |                 arguments to this enum variant are incorrect
    |
    = note: expected struct `Box<dyn StdError + std::marker::Send + Sync>`
               found struct `anyhow::Error`
help: the type constructed contains `anyhow::Error` due to the type of the argument passed
   --> src/main.rs:432:17
    |
432 |                 Err(anyhow!("No swap transaction found in response"))
    |                 ^^^^------------------------------------------------^
    |                     |
    |                     this argument influences the type of `Err`
note: tuple variant defined here
   --> C:\Users\Orsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\result.rs:536:5
    |
536 |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
    |     ^^^
help: call `Into::into` on this expression to convert `anyhow::Error` into `Box<dyn StdError + std::marker::Send + Sync>`
    |
432 |                 Err(anyhow!("No swap transaction found in response").into())
    |                                                                     +++++++

error[E0308]: mismatched types
   --> src/main.rs:470:25
    |
470 |                     Err(anyhow!("Helius error: {:?}", error))
    |                     --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Error + Send + Sync>`, found `Error`
    |                     |
    |                     arguments to this enum variant are incorrect
    |
    = note: expected struct `Box<dyn StdError + std::marker::Send + Sync>`
               found struct `anyhow::Error`
help: the type constructed contains `anyhow::Error` due to the type of the argument passed
   --> src/main.rs:470:21
    |
470 |                     Err(anyhow!("Helius error: {:?}", error))
    |                     ^^^^------------------------------------^
    |                         |
    |                         this argument influences the type of `Err`
note: tuple variant defined here
   --> C:\Users\Orsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\result.rs:536:5
    |
536 |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
    |     ^^^
help: call `Into::into` on this expression to convert `anyhow::Error` into `Box<dyn StdError + std::marker::Send + Sync>`
    |
470 |                     Err(anyhow!("Helius error: {:?}", error).into())
    |                                                             +++++++

error[E0308]: mismatched types
   --> src/main.rs:472:25
    |
472 |                     Err(anyhow!("Transaction failed without error details"))
    |                     --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Error + Send + Sync>`, found `Error`
    |                     |
    |                     arguments to this enum variant are incorrect
    |
    = note: expected struct `Box<dyn StdError + std::marker::Send + Sync>`
               found struct `anyhow::Error`
help: the type constructed contains `anyhow::Error` due to the type of the argument passed
   --> src/main.rs:472:21
    |
472 |                     Err(anyhow!("Transaction failed without error details"))
    |                     ^^^^---------------------------------------------------^
    |                         |
    |                         this argument influences the type of `Err`
note: tuple variant defined here
   --> C:\Users\Orsen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\result.rs:536:5
    |
536 |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
    |     ^^^
help: call `Into::into` on this expression to convert `anyhow::Error` into `Box<dyn StdError + std::marker::Send + Sync>`
    |
472 |                     Err(anyhow!("Transaction failed without error details").into())
    |                                                                            +++++++

error[E0599]: no method named `extract_pool_info` found for reference `&TradingBot` in the current scope     
   --> src/main.rs:549:47
    |
549 |                 if let Some(pool_info) = self.extract_pool_info(program_data)? {
    |                                               ^^^^^^^^^^^^^^^^^ method not found in `&TradingBot`       

error[E0308]: mismatched types
    --> src/main.rs:650:31
     |
650  |             .get_token_supply(&token_mint)
     |              ---------------- ^^^^^^^^^^^ expected `&Pubkey`, found `&&str`
     |              |
     |              arguments to this method are incorrect
     |
     = note: expected reference `&Pubkey`
                found reference `&&str`
note: method defined here
    --> C:\Users\Orsen\.cargo\registry\src\index.crates.io-6f17d22bba15001f\solana-rpc-client-1.18.26\src\rpc_client.rs:3896:12
     |
3896 |     pub fn get_token_supply(&self, mint: &Pubkey) -> ClientResult<UiTokenAmount> {
     |            ^^^^^^^^^^^^^^^^

error[E0277]: `Result<solana_account_decoder::parse_token::UiTokenAmount, solana_client::client_error::ClientError>` is not a future
   --> src/main.rs:651:14
    |
651 |             .await?
    |             -^^^^^
    |             ||
    |             |`Result<solana_account_decoder::parse_token::UiTokenAmount, solana_client::client_error::ClientError>` is not a future
    |             help: remove the `.await`
    |
    = help: the trait `futures_util::Future` is not implemented for `Result<solana_account_decoder::parse_token::UiTokenAmount, solana_client::client_error::ClientError>`, which is required by `Result<solana_account_decoder::parse_token::UiTokenAmount, solana_client::client_error::ClientError>: std::future::IntoFuture`
    = note: Result<solana_account_decoder::parse_token::UiTokenAmount, solana_client::client_error::ClientError> must be a future or must implement `IntoFuture` to be awaited
    = note: required for `Result<solana_account_decoder::parse_token::UiTokenAmount, solana_client::client_error::ClientError>` to implement `std::future::IntoFuture`

error[E0308]: mismatched types
   --> src/main.rs:643:9
    |
630 |       async fn get_token_price(&self, token_mint: &str) -> Result<f64, Box<dyn std::error::Error + Send + Sync>...
    |                                                            ----------------------------------------------------- expected `Result<f64, Box<(dyn StdError + std::marker::Send + Sync + 'static)>>` because of return type
...
643 | /         response["data"][token_mint]["price"]
644 | |             .as_f64()
645 | |             .ok_or_else(|| anyhow!("Price not found"))
    | |______________________________________________________^ expected `Result<f64, Box<...>>`, found `Result<f64, Error>`
    |
    = note: expected enum `Result<_, Box<(dyn StdError + std::marker::Send + Sync + 'static)>>`
               found enum `Result<_, anyhow::Error>`
help: use `?` to coerce and return an appropriate `Err`, and wrap the resulting value in `Ok` so the expression remains of type `Result`
    |
643 ~         Ok(response["data"][token_mint]["price"]
644 |             .as_f64()
645 ~             .ok_or_else(|| anyhow!("Price not found"))?)
    |

Some errors have detailed explanations: E0277, E0308, E0405, E0412, E0422, E0599, E0610.
For more information about an error, try `rustc --explain E0277`.
warning: `solana_rust_bot` (bin "solana_rust_bot") generated 2 warnings
error: could not compile `solana_rust_bot` (bin "solana_rust_bot") due to 28 previous errors; 2 warnings emitted can u fix this please use std::{
    fs,
    io::{self, Write},
    sync::Arc,
    time::{Duration, Instant},
};

use anyhow::{anyhow, Result};
use chrono::Utc;
use colored::*;
use env_logger::Env;
use futures_util::{SinkExt, StreamExt};
use reqwest::Client as HttpClient;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use solana_client::rpc_client::RpcClient;
use solana_sdk::{
    commitment_config::CommitmentConfig,
    signature::{Keypair, read_keypair_file},
};
use tokio::{
    select,
    sync::{broadcast, Mutex},
    time::sleep,
};
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
use tracing::{debug, error, info, warn, Level};
use tracing_subscriber::{
    fmt::format::FmtSpan,
    EnvFilter,
};

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

// Configuration Structures
#[derive(Debug, Deserialize, Clone)]
pub struct Config {
    pub rpc: RpcConfig,
    pub urls: UrlConfig,
    pub wallet: WalletConfig,
    pub api_keys: ApiKeys,
    pub trading: TradingConfig,
    pub token_requirements: TokenRequirements,
    pub websocket: WebsocketConfig,
    pub logging: LoggingConfig,
}

#[derive(Debug, Deserialize, Clone)]
pub struct RpcConfig {
    pub solana_rpc_url: String,
    pub fallback_url: String,
}

#[derive(Debug, Deserialize, Clone)]
pub struct UrlConfig {
    pub ws_url: String,
    pub rpc_url: String,
}

#[derive(Debug, Deserialize, Clone)]
pub struct WalletConfig {
    pub keypair_path: String,
    pub public_key: String,
}

#[derive(Debug, Deserialize, Clone)]
pub struct ApiKeys {
    pub helius_api_key: String,
}

#[derive(Debug, Deserialize, Clone)]
pub struct TradingConfig {
    pub snipe_amount: u64,
    pub max_slippage: f64,
    pub priority_fee: u64,
    pub profit_target_percent: f64,
    pub stop_loss_percent: f64,
    pub max_concurrent_trades: usize,
    pub retry_interval: u64,
    pub max_buy_attempts: u32,
    pub enabled: bool,
    pub execution_enabled: bool,
    pub max_retry_attempts: u32,
}

#[derive(Debug, Deserialize, Clone)]
pub struct TokenRequirements {
    pub min_supply: u64,
    pub mutable: bool,
    pub burnt: bool,
    pub frozen: bool,
}

#[derive(Debug, Deserialize, Clone)]
pub struct WebsocketConfig {
    pub reconnect_interval: u64,
    pub heartbeat_interval: u64,
}

#[derive(Debug, Deserialize, Clone)]
pub struct LoggingConfig {
    pub show_balances: bool,
    pub debug_mode: bool,
}

// Trading Structures
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Trade {
    pub token_mint: String,
    pub entry_price: f64,
    pub amount: u64,
    pub take_profit_price: f64,
    pub stop_loss_price: f64,
    pub timestamp: i64,
    pub status: TradeStatus,
    pub buy_signature: Option<String>,
    pub sell_signature: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TradeStatus {
    Pending,
    Active {
        current_price: f64,
        profit_percent: f64,
    },
    Completed {
        exit_price: f64,
        profit: f64,
        duration_secs: u64,
    },
    Failed {
        reason: String,
        timestamp: i64,
    },
}

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct TradingMetrics {
    pub total_trades: u32,
    pub successful_trades: u32,
    pub failed_trades: u32,
    pub total_profit_sol: f64,
    pub best_trade_profit: f64,
    pub worst_trade_loss: f64,
    pub average_duration_secs: f64,
}

#[derive(Debug)]
pub struct PoolInfo {
    pub token_mint: String,
    pub liquidity: f64,
    pub price: f64,
}

// Main Bot Structure
pub struct TradingBot {
    pub config: Config,
    pub rpc_client: Arc<RpcClient>,
    pub fallback_rpc: Arc<RpcClient>,
    pub wallet: Arc<Keypair>,
    pub state: Arc<Mutex<BotState>>,
    pub shutdown: broadcast::Sender<()>,
}

impl TradingBot {
    pub async fn new() -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
        // Initialize tracing for better debug output
        Self::setup_logging()?;
        info!("🚀 Initializing Helius-powered Trading Bot");

        // Load config
        let config = Self::load_config()?;
        debug!("Configuration loaded successfully");

        // Initialize RPCs with Helius
        let rpc_client = Arc::new(RpcClient::new_with_commitment(
            &config.urls.rpc_url,
            CommitmentConfig::confirmed(),
        ));

        let fallback_rpc = Arc::new(RpcClient::new_with_commitment(
            &config.rpc.fallback_url,
            CommitmentConfig::confirmed(),
        ));

        // Load wallet
        info!("Loading wallet from {}", config.wallet.keypair_path);
        let wallet = Arc::new(read_keypair_file(&config.wallet.keypair_path)?);

        // Verify wallet matches config
        let loaded_pubkey = wallet.try_pubkey().to_string();
        if loaded_pubkey != config.wallet.public_key {
            return Err(anyhow!("Wallet mismatch: loaded {} but config specified {}",
                loaded_pubkey, config.wallet.public_key));
        }

        let state = Arc::new(Mutex::new(BotState {
            active_trades: Vec::new(),
            completed_trades: Vec::new(),
            metrics: TradingMetrics::default(),
            last_update: Utc::now(),
        }));

        let (shutdown_tx, _) = broadcast::channel(1);

        Ok(Self {
            config,
            rpc_client,
            fallback_rpc,
            wallet,
            state,
            shutdown: shutdown_tx,
        })
    }

    fn setup_logging() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let filter = if std::env::var("RUST_LOG").is_ok() {
            EnvFilter::from_default_env()
        } else {
            EnvFilter::new("info,solana_client=warn")
        };

        tracing_subscriber::fmt()
            .with_env_filter(filter)
            .with_thread_ids(true)
            .with_target(false)
            .with_file(true)
            .with_line_number(true)
            .with_ansi(true)
            .with_span_events(FmtSpan::CLOSE)
            .init();

        Ok(())
    }

    fn load_config() -> Result<Config, Box<dyn std::error::Error + Send + Sync>> {
        let config_str = fs::read_to_string("config.toml")
            .map_err(|e| anyhow!("Failed to read config.toml: {}", e))?;

        toml::from_str(&config_str)
            .map_err(|e| anyhow!("Failed to parse config: {}", e))
    }

    pub async fn verify_setup(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        info!("Verifying setup...");

        // Check Helius RPC
        let blockhash = self.rpc_client
            .get_latest_blockhash()
            .map_err(|e| anyhow!("Helius RPC connection failed: {}", e))?;
        info!("✅ Helius RPC connected");

        // Check wallet balance
        let balance = self.rpc_client.get_balance(&self.wallet.pubkey())?;
        let sol_balance = balance.ui_amount.unwrap_or_default() as f64 / 1e9;

        let min_required = (self.config.trading.snipe_amount as f64 / 1e9) * 2.0;
        info!("💰 Wallet balance: {} SOL", sol_balance);

        if sol_balance < min_required {
            return Err(anyhow!(
                "Insufficient SOL balance. Need: {} SOL, Have: {} SOL",
                min_required,
                sol_balance
            ));
        }

        // Verify Jupiter connection
        let client = HttpClient::new();
        let jupiter_response = client
            .get(&format!("{}/price?ids={}", JUPITER_API, SOL_MINT))
            .send()
            .await?;

        if !jupiter_response.status().is_success() {
            return Err(anyhow!("Jupiter API connection failed"));
        }
        info!("✅ Jupiter API connected");

        info!("✅ All systems verified!");
        Ok(())
    }

    pub async fn save_state(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let state = self.state.lock().await;
        let state_json = serde_json::to_string_pretty(&*state)?;
        fs::write("bot_state.json", state_json)?;
        debug!("State saved successfully");
        Ok(())
    }

    pub async fn load_state(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        if let Ok(state_json) = fs::read_to_string("bot_state.json") {
            let loaded_state: BotState = serde_json::from_str(&state_json)?;
            let mut state = self.state.lock().await;
            *state = loaded_state;

            info!("📊 Loaded state:");
            info!("  ├── Active trades: {}", state.active_trades.len());
            info!("  ├── Completed trades: {}", state.completed_trades.len());
            info!("  ├── Total profit: {} SOL", state.metrics.total_profit_sol);
            info!("  └── Success rate: {}%",
                (state.metrics.successful_trades as f64 /
                state.metrics.total_trades.max(1) as f64 * 100.0).round()
            );
        } else {
            info!("No previous state found, starting fresh");
        }
        Ok(())
    }

    pub fn print_status(&self, state: &BotState) {
        println!("\n=== Trading Bot Status ===");
        println!("📈 Performance Metrics:");
        println!("  ├── Total Trades: {}", state.metrics.total_trades);
        println!("  ├── Successful: {} ({}%)",
            state.metrics.successful_trades,
            (state.metrics.successful_trades as f64 /
            state.metrics.total_trades.max(1) as f64 * 100.0).round()
        );
        println!("  ├── Total Profit: {:.4} SOL", state.metrics.total_profit_sol);
        println!("  ├── Best Trade: +{:.4} SOL", state.metrics.best_trade_profit);
        println!("  └── Worst Trade: -{:.4} SOL", state.metrics.worst_trade_loss.abs());

        if !state.active_trades.is_empty() {
            println!("\n🔄 Active Trades:");
            for (i, trade) in state.active_trades.iter().enumerate() {
                if let TradeStatus::Active { current_price, profit_percent } = trade.status {
                    println!("  {}. {} ({:+.2}%)",
                        i + 1,
                        trade.token_mint,
                        profit_percent
                    );
                }
            }
        }

        println!("\n⏰ Last Update: {}",
            state.last_update.format("%Y-%m-%d %H:%M:%S")
        );
    }

    pub async fn execute_trade(&self, token_mint: &str, is_buy: bool) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
        let start = Instant::now();
        let trade_type = if is_buy { "BUY" } else { "SELL" };

        info!("🚀 Executing {} for {}", trade_type, token_mint);

        let (input_mint, output_mint, amount) = if is_buy {
            (SOL_MINT, token_mint, self.config.trading.snipe_amount)
        } else {
            (token_mint, SOL_MINT, self.config.trading.snipe_amount)
        };

        // Get Jupiter quote
        let quote = self.get_jupiter_quote(input_mint, output_mint, amount).await?;
        debug!("⚡ Quote received in {:?}", start.elapsed());

        // Validate slippage
        let slippage = self.calculate_slippage(&quote)?;
        if slippage > self.config.trading.max_slippage {
            return Err(anyhow!("Slippage too high: {:.2}%", slippage));
        }

        // Build swap transaction
        let swap_data = self.build_swap_transaction(&quote).await?;
        debug!("⚡ Swap built in {:?}", start.elapsed());

        // Send priority transaction via Helius
        let signature = self.send_priority_transaction(&swap_data).await?;
        info!("✨ {} complete - TX: {} (Elapsed: {:?})", trade_type, signature, start.elapsed());

        Ok(signature)
    }

    async fn get_jupiter_quote(&self, input_mint: &str, output_mint: &str, amount: u64) -> Result<Value, Box<dyn std::error::Error + Send + Sync>> {
        let url = format!(
            "{}/quote?inputMint={}&outputMint={}&amount={}&slippageBps={}&onlyDirectRoutes=true",
            JUPITER_API,
            input_mint,
            output_mint,
            amount,
            (self.config.trading.max_slippage * 100.0) as u32
        );

        let client = HttpClient::new();
        let response = client.get(&url)
            .send()
            .await?
            .error_for_status()?
            .json::<Value>()
            .await?;

        if let Some(routes) = response["data"]["routesInfos"].as_array() {
            if routes.is_empty() {
                return Err(anyhow!("No valid routes found for trade"));
            }
        }

        Ok(response)
    }

    async fn build_swap_transaction(&self, quote: &Value) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
        let swap_request = json!({
            "quoteResponse": quote,
            "userPublicKey": self.config.wallet.public_key,
            "wrapUnwrapSOL": true,
            "computeUnitPriceMicroLamports": self.config.trading.priority_fee,
            "priorityFeeLamports": self.config.trading.priority_fee,
            "asLegacyTransaction": false,
            "maxAccounts: 64"
        });

        let client = HttpClient::new();
        let response = client.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 => {
                debug!("Swap Response: {:?}", response);
                Err(anyhow!("No swap transaction found in response"))
            }
        }
    }

    async fn send_priority_transaction(&self, swap_data: &str) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
        let helius_request = json!({
            "jsonrpc": "2.0",
            "id": "helius-priority",
            "method": "sendTransaction",
            "params": [
                swap_data,
                {
                    "encoding": "base64",
                    "maxRetries": 0,
                    "skipPreflight": true,
                    "preflightCommitment": "processed",
                    "priorityFee": self.config.trading.priority_fee,
                    "maxAccountLocks": 64
                }
            ]
        });

        let client = HttpClient::new();
        let response = client.post(&self.config.urls.rpc_url)
            .header("Authorization", format!("Bearer {}", self.config.api_keys.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 signature format"))?
                .to_string()),
            None => {
                if let Some(error) = response.get("error") {
                    Err(anyhow!("Helius error: {:?}", error))
                } else {
                    Err(anyhow!("Transaction failed without error details"))
                }
            }
        }
    }

    pub async fn monitor_pools(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let ws_url = url::Url::parse(&self.config.urls.ws_url)?;
        info!("📡 Connecting to Helius WebSocket...");

        loop {
            match connect_async(ws_url.clone()).await {
                Ok((ws_stream, _)) => {
                    info!("✅ WebSocket connected");
                    let (mut write, mut read) = ws_stream.split();

                    // Subscribe to Raydium program
                    let subscribe_msg = json!({
                        "jsonrpc": "2.0",
                        "id": 1,
                        "method": "programSubscribe",
                        "params": [
                            RAYDIUM_AMM_PROGRAM,
                            {
                                "encoding": "jsonParsed",
                                "commitment": "confirmed"
                            }
                        ]
                    });

                    if let Err(e) = write.send(Message::Text(subscribe_msg.to_string())).await {
                        error!("WebSocket subscription failed: {}", e);
                        continue;
                    }

                    info!("✅ Subscribed to Raydium AMM program");

                    // Process messages
                    while let Some(msg) = read.next().await {
                        match msg {
                            Ok(Message::Text(text)) => {
                                if let Err(e) = self.process_pool_update(&text).await {
                                    warn!("Failed to process pool update: {}", e);
                                }
                            }
                            Ok(Message::Close(_)) => {
                                info!("WebSocket closed by server");
                                break;
                            }
                            Err(e) => {
                                error!("WebSocket error: {}", e);
                                break;
                            }
                            _ => {}
                        }
                    }
                }
                Err(e) => {
                    error!("WebSocket connection failed: {}", e);
                    sleep(Duration::from_secs(
                        self.config.websocket.reconnect_interval
                    )).await;
                }
            }
        }
    }

    async fn process_pool_update(&self, message: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let data: Value = serde_json::from_str(message)?;
        if let Some(params) = data.get("params") {
            if let Some(program_data) = params
                .get("result")
                .and_then(|r| r.get("value"))
                .and_then(|v| v.get("account"))
                .and_then(|a| a.get("data"))
            {
                // Extract pool data
                if let Some(pool_info) = self.extract_pool_info(program_data)? {
                    if self.validate_pool(&pool_info).await? {
                        let mut state = self.state.lock().await;

                        // Check if we're already trading this token
                        if state.active_trades.iter().any(|t| t.token_mint == pool_info.token_mint) {
                            return Ok(());
                        }

                        // Check concurrent trade limit
                        if state.active_trades.len() >= self.config.trading.max_concurrent_trades {
                            debug!("Maximum concurrent trades reached");
                            return Ok(());
                        }

                        info!("💫 New trading opportunity:");
                        info!("  ├── Token: {}", pool_info.token_mint);
                        info!("  ├── Liquidity: {} SOL", pool_info.liquidity);
                        info!("  └── Price: {} SOL", pool_info.price);

                        // Attempt to execute trade
                        if let Ok(signature) = self.execute_trade(&pool_info.token_mint, true).await {
                            let trade = Trade {
                                token_mint: pool_info.token_mint,
                                entry_price: pool_info.price,
                                amount: self.config.trading.snipe_amount,
                                take_profit_price: pool_info.price * (1.0 + self.config.trading.profit_target_percent / 100.0),
                                stop_loss_price: pool_info.price * (1.0 + self.config.trading.stop_loss_percent / 100.0),
                                timestamp: Utc::now().timestamp(),
                                status: TradeStatus::Active {
                                    current_price: pool_info.price,
                                    profit_percent: 0.0
                                },
                                buy_signature: Some(signature),
                                sell_signature: None,
                            };

                            state.active_trades.push(trade);
                            self.save_state().await?;
                        }
                    }
                }
            }
        }

        Ok(())
    }

    fn calculate_slippage(&self, quote: &Value) -> Result<f64, Box<dyn std::error::Error + Send + Sync>> {
        let route = quote["data"]["routesInfos"][0].as_object()
            .ok_or_else(|| anyhow!("Invalid route format"))?;

        let price_impact = route["priceImpactPct"]
            .as_f64()
            .unwrap_or_default();

        Ok(price_impact.abs())
    }

    async fn validate_pool(&self, pool_info: &PoolInfo) -> Result<bool, Box<dyn std::error::Error + Send + Sync>> {
        // Basic validations
        if pool_info.token_mint == SOL_MINT {
            return Ok(false);
        }

        // Supply check
        let token_supply = self.get_token_supply(&pool_info.token_mint).await?;
        if token_supply < self.config.token_requirements.min_supply {
            return Ok(false);
        }

        // Price validation
        if let Ok(current_price) = self.get_token_price(&pool_info.token_mint).await {
            if (current_price - pool_info.price).abs() / pool_info.price > 0.05 {
                return Ok(false);
            }
        }

        Ok(true)
    }

    async fn get_token_price(&self, token_mint: &str) -> Result<f64, Box<dyn std::error::Error + Send + Sync>> {
        let url = format!(
            "https://price.jup.ag/v6/price?ids={}&vsToken=SOL",
            token_mint
        );

        let client = HttpClient::new();
        let response = client.get(&url)
            .send()
            .await?
            .json::<Value>()
            .await?;

        response["data"][token_mint]["price"]
            .as_f64()
            .ok_or_else(|| anyhow!("Price not found"))
    }

    async fn get_token_supply(&self, token_mint: &str) -> Result<u64, Box<dyn std::error::Error + Send + Sync>> {
        let supply = self.rpc_client
            .get_token_supply(&token_mint)
            .await?
            .ui_amount
            .ok_or_else(|| anyhow!("Invalid token supply"))?;

        Ok(supply as u64)
    }

    pub async fn run(self: Arc<Self>) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        println!("{}", "\n=== Solana Trading Bot v1.0 ===".bright_green().bold());

        // Initialize bot
        self.load_state().await?;
        self.verify_setup().await?;

        // Start monitoring tasks
        let monitor_handle = {
            let bot = self.clone();
            tokio::spawn(async move {
                if let Err(e) = bot.monitor_trades().await {
                    error!("Trade monitor error: {}", e);
                }
            })
        };

        let pool_handle = {
            let bot = self.clone();
            tokio::spawn(async move {
                if let Err(e) = bot.monitor_pools().await {
                    error!("Pool monitor error: {}", e);
                }
            })
        };

        let ui_handle = {
            let bot = self.clone();
            tokio::spawn(async move {
                if let Err(e) = bot.run_ui().await {
                    error!("UI error: {}", e);
                }
            })
        };

        // Auto-save state periodically
        let save_handle = {
            let bot = self.clone();
            tokio::spawn(async move {
                let mut interval = tokio::time::interval(Duration::from_secs(30));
                loop {
                    interval.tick().await;
                    if let Err(e) = bot.save_state().await {
                        error!("Failed to save state: {}", e);
                    }
                }
            })
        };

        let mut shutdown_rx = self.shutdown.subscribe();

        select! {
            _ = shutdown_rx.recv() => {
                info!("Received shutdown signal");
            }
            _ = tokio::signal::ctrl_c() => {
                info!("Received Ctrl+C");
            }
        }

        // Graceful shutdown
        monitor_handle.abort();
        pool_handle.abort();
        ui_handle.abort();
        save_handle.abort();

        info!("Saving final state...");
        self.save_state().await?;

        println!("{}", "\nBot shutdown complete! 👋".bright_green());
        Ok(())
    }

    async fn monitor_trades(&self) -> Result<(), Box<dyn StdError + Send + Sync>> {
        let mut interval = tokio::time::interval(Duration::from_millis(500));

        loop {
            interval.tick().await;
            let mut state = self.state.lock().await;
            let trades_to_update: Vec<_> = state.active_trades.clone();
            drop(state);

            for trade in trades_to_update {
                if let Err(e) = self.update_trade_status(&trade).await {
                    warn!("Failed to update trade {}: {}", trade.token_mint, e);
                    continue;
                }
            }
        }
    }

    async fn update_trade_status(&self, trade: &Trade) -> Result<(), Box<dyn StdError + Send + Sync>> {
        if let TradeStatus::Active { .. } = trade.status {
            let current_price = self.get_token_price(&trade.token_mint).await?;
            let profit_percent = (current_price - trade.entry_price) / trade.entry_price * 100.0;

            let mut state = self.state.lock().await;
            if let Some(active_trade) = state.active_trades.iter_mut()
                .find(|t| t.token_mint == trade.token_mint)
            {
                // Update trade status
                active_trade.status = TradeStatus::Active {
                    current_price,
                    profit_percent,
                };

                // Check take profit
                if profit_percent >= self.config.trading.profit_target_percent {
                    info!("🎯 Take profit hit for {}: {:.2}%", trade.token_mint, profit_percent);
                    if let Ok(signature) = self.execute_trade(&trade.token_mint, false).await {
                        self.complete_trade(trade, current_price, signature, "Take Profit").await?;
                    }
                }
                // Check stop loss
                else if profit_percent <= -self.config.trading.stop_loss_percent {
                    warn!("⚠️ Stop loss hit for {}: {:.2}%", trade.token_mint, profit_percent);
                    if let Ok(signature) = self.execute_trade(&trade.token_mint, false).await {
                        self.complete_trade(trade, current_price, signature, "Stop Loss").await?;
                    }
                }
            }
        }
        Ok(())
    }

    async fn complete_trade(&self, trade: &Trade, exit_price: f64, signature: String, reason: &str) -> Result<(), Box<dyn StdError + Send + Sync>> {
        let mut state = self.state.lock().await;

        // Remove from active trades
        if let Some(pos) = state.active_trades.iter().position(|t| t.token_mint == trade.token_mint) {
            let mut trade = state.active_trades.remove(pos);

            // Calculate final metrics
            let profit = (exit_price - trade.entry_price) * (trade.amount as f64 / 1e9);
            let duration = chrono::Utc::now().timestamp() - trade.timestamp;

            // Update trade status
            trade.status = TradeStatus::Completed {
                exit_price,
                profit,
                duration_secs: duration as u64,
            };
            trade.sell_signature = Some(signature);

            // Update metrics
            let mut metrics = &mut state.metrics;
            metrics.total_trades += 1;
            if profit > 0.0 {
                metrics.successful_trades += 1;
                metrics.best_trade_profit = metrics.best_trade_profit.max(profit);
            } else {
                metrics.failed_trades += 1;
                metrics.worst_trade_loss = metrics.worst_trade_loss.min(profit);
            }
            metrics.total_profit_sol += profit;
            metrics.average_duration_secs = (metrics.average_duration_secs * (metrics.total_trades - 1) as f64
                + duration as f64) / metrics.total_trades as f64;

            // Add to completed trades
            state.completed_trades.push(trade);

            // Log completion
            info!("Trade completed - {}", reason);
            info!("  ├── Token: {}", trade.token_mint);
            info!("  ├── Profit: {:.4} SOL ({:.2}%)", profit, (exit_price - trade.entry_price) / trade.entry_price * 100.0);
            info!("  ├── Duration: {}s", duration);
            info!("  └── TX: {}", signature);
        }

        self.save_state().await?;
        Ok(())
    }

    async fn run_ui(&self) -> Result<(), Box<dyn StdError + Send + Sync>> {
        let mut interval = tokio::time::interval(Duration::from_secs(1));

        loop {
            interval.tick().await;
            self.clear_screen();

            let state = self.state.lock().await;

            // Header
            println!("{}", "=== Solana Trading Bot ===".bright_green().bold());
            println!("Runtime: {}", self.get_runtime_str());

            // Active Trades
            println!("\n{}", "Active Trades:".bright_blue().bold());
            if state.active_trades.is_empty() {
                println!("  No active trades");
            } else {
                for trade in &state.active_trades {
                    if let TradeStatus::Active { current_price, profit_percent } = trade.status {
                        let status = if profit_percent >= 0.0 {
                            format!("+{:.2}%", profit_percent).bright_green()
                        } else {
                            format!("{:.2}%", profit_percent).bright_red()
                        };

                        println!("  {} | Price: {} SOL | {}",
                            trade.token_mint.bright_yellow(),
                            current_price,
                            status
                        );
                    }
                }
            }

            // Performance Metrics
            println!("\n{}", "Performance:".bright_blue().bold());
            println!("  Total Trades: {}", state.metrics.total_trades);
            println!("  Success Rate: {:.1}%",
                if state.metrics.total_trades > 0 {
                    (state.metrics.successful_trades as f64 / state.metrics.total_trades as f64) * 100.0
                } else {
                    0.0
                }
            );

            let profit_color = if state.metrics.total_profit_sol >= 0.0 {
                state.metrics.total_profit_sol.to_string().bright_green()
            } else {
                state.metrics.total_profit_sol.to_string().bright_red()
            };
            println!("  Total Profit: {} SOL", profit_color);

            // Recent Trades
            println!("\n{}", "Recent Trades:".bright_blue().bold());
            for trade in state.completed_trades.iter().rev().take(5) {
                if let TradeStatus::Completed { profit, .. } = trade.status {
                    let profit_str = if profit >= 0.0 {
                        format!("+{:.4}", profit).bright_green()
                    } else {
                        format!("{:.4}", profit).bright_red()
                    };
                    println!("  {} | {} SOL",
                        trade.token_mint.bright_yellow(),
                        profit_str
                    );
                }
            }

            // Controls
            println!("\n{}", "Controls:".bright_blue().bold());
            println!("  Ctrl+C to exit");
        }
    }

    fn clear_screen(&self) {
        print!("\x1B[2J\x1B[1;1H");
        io::stdout().flush().unwrap();
    }

    fn get_runtime_str(&self) -> String {
        let state = self.state.lock().unwrap();
        let duration = chrono::Utc::now()
            .signed_duration_since(state.last_update)
            .num_seconds();

        let hours = duration / 3600;
        let minutes = (duration % 3600) / 60;
        let seconds = duration % 60;

        format!("{}h {}m {}s", hours, minutes, seconds)
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn StdError + Send + Sync>> {
    let bot = Arc::new(TradingBot::new().await?);

    // Handle Ctrl+C
       ctrlc::set_handler({
        let shutdown = bot.shutdown.clone();
        move || {
            let _ = shutdown.send(());
        }
    })?;

    if let Err(e) = bot.run().await {
        error!("Bot error: {}", e);
        std::process::exit(1);
    }

    Ok(())
}

 fully fix so its working and ready to run please lets see what u can do provide the full script with all functions coded properly to function as intended please