use crate::coex::exchange_team::*;
use crate::coex::order_team::*;
use crate::future::Position;
use csv::{DeserializeRecordsIter, StringRecord};
use rust_decimal::prelude::ToPrimitive;
use rust_decimal::Decimal;
use serde::Deserialize;
use crate::future::FuturesExchangeInfo;

// use super::strategy_test;
use super::{
    exists_record, insert_one_record, try_join_all, try_select_record, AllData, ExchangeInfo,
    FilteredDataValue, FromRow, HashMap, RealtimePriceData, TradeFee,
};
use crate::signal_association::signal_decision::*;
use tokio::time::{sleep, Duration, Instant};

#[derive(Debug, FromRow)]
struct ServerEpoch {
    server_epoch: u64,
}

#[derive(Debug, FromRow)]
struct Record {
    symbol: String,
    suggested_price: Decimal,
    close_time: u64,
    registered_server_epoch: u64,
    registerer: u16,
    is_long: u8,
}

pub async fn execute_list_up_for_buy(
    all_data: &AllData,
    future_exchange_info_map: &HashMap<String, FuturesExchangeInfo>
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    // crate::strategy_team::strategy_001::list_up_for_buy(all_data).await;
    // crate::strategy_team::strategy_002::list_up_for_buy(all_data).await;
    // crate::strategy_team::strategy_003::list_up_for_buy(all_data).await;
    // crate::strategy_team::strategy_004::list_up_for_buy(all_data).await;
    // crate::strategy_team::strategy_005::list_up_for_buy(all_data).await;
    // crate::strategy_team::strategy_006::list_up_for_buy(all_data).await;
    // crate::strategy_team::strategy_007::list_up_for_buy(all_data).await;
    // crate::strategy_team::strategy_008::list_up_for_buy(all_data).await;
    // crate::strategy_team::strategy_009::list_up_for_buy(all_data).await;
    crate::strategy_team::future_strategy_long::list_up_for_buy(all_data, &future_exchange_info_map).await;
    crate::strategy_team::future_strategy_short::list_up_for_buy(all_data, &future_exchange_info_map).await;

    Ok(())
}

pub async fn execute_list_up_for_sell(
    all_data: &AllData,
    exchange_info_map: &HashMap<String, ExchangeInfo>,
    trade_fee_map: &HashMap<String, TradeFee>,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    // crate::strategy_team::strategy_001::list_up_for_sell(&all_data, &exchange_info_map, &trade_fee_map).await;
    // crate::strategy_team::strategy_002::list_up_for_sell(&all_data, &exchange_info_map, &trade_fee_map).await;
    // crate::strategy_team::strategy_003::list_up_for_sell(&all_data, &exchange_info_map, &trade_fee_map).await;
    // crate::strategy_team::strategy_004::list_up_for_sell(&all_data, &exchange_info_map, &trade_fee_map).await;
    // crate::strategy_team::strategy_005::list_up_for_sell(&all_data, &exchange_info_map, &trade_fee_map).await;
    // crate::strategy_team::strategy_006::list_up_for_sell(
    //     &all_data,
    //     &exchange_info_map,
    //     &trade_fee_map,
    // )
    // .await;
    // crate::strategy_team::strategy_007::list_up_for_sell(
    //     &all_data,
    //     &exchange_info_map,
    //     &trade_fee_map,
    // )
    // .await;
    // crate::strategy_team::strategy_008::list_up_for_sell(
    //     &all_data,
    //     &exchange_info_map,
    //     &trade_fee_map,
    // )
    // .await;

    // crate::strategy_team::strategy_009::list_up_for_sell(
    //     &all_data,
    //     &exchange_info_map,
    //     &trade_fee_map,
    // )
    // .await;
    crate::strategy_team::future_strategy_long::list_up_for_sell(&all_data).await;
    crate::strategy_team::future_strategy_short::list_up_for_sell(&all_data).await;
    Ok(())
}

pub async fn insert_pre_suggested_coins(
    registerer: i32,
    is_long: bool,
    filtered_coins: &HashMap<String, FilteredDataValue>
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let mut insert_table_name = String::from("pre_suggested_coin_list");
    let insert_columns = vec![
        "symbol",
        "close_time",
        "suggested_price",
        "current_price",
        "stoploss",
        "target_price",
        "registered_server_epoch",
        "profit_percent",
        "minimum_profit_percent",
        "maximum_profit_percent",
        "registerer",
        "is_long",
    ];

    for (symbol, filtered_data) in filtered_coins {
        let mut insert_values = vec![
                symbol.clone(),                          // symbol
                filtered_data.closetime.to_string(),     // close_time
                filtered_data.current_price.to_string(), // suggested_price
                filtered_data.current_price.to_string(), // current_price
                filtered_data.stoploss.to_string(),      // stoploss
                filtered_data.target_price.to_string(),  // target_price
                get_server_epoch().await.to_string(),    // registered_server_epoch
                0.0.to_string(),                         // profit_percent
                0.0.to_string(),                         // minimum_profit_percent
                0.0.to_string(),                         // maximum_profit_percent
                registerer.to_string(),                  // registerer
            ];

        if is_long == true {
            insert_values.push(1.to_string()); // is_long
        } else {
            insert_values.push(0.to_string()); // is_long
        }

        insert_one_record(&insert_table_name, &insert_columns, &insert_values).await;
    }

    Ok(())
}

pub async fn insert_future_coins(
    position: Position,
    server_epoch: i64,
    filtered_coins: &HashMap<String, FilteredDataValue>
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let mut insert_table_name = String::from("future_ordered_coin_list");
    let insert_columns = vec![
        "order_type",
        "status",
        "symbol",
        "order_id",
        "position",
        "registered_server_epoch",
        "transact_time",
        "close_time",
        "used_usdt",
        "expected_get_usdt",
        "pnl",
        "entry_price",
        "current_price",
        "base_qty_ordered",
        "pure_profit_percent",
        "minimum_profit_percent",
        "maximum_profit_percent",
    ];

    for (symbol, filtered_data) in filtered_coins {
        let mut insert_values = vec![
                String::from("POSITIONING"),            // order_type
                String::from("LISTUP"),                 // status
                symbol.clone(),                         // symbol
                0.to_string(),                          // order_id
                position.to_string(),                   // position
                server_epoch.to_string(),               // registered_server_epoch
                0.to_string(),                          // transact_time
                filtered_data.closetime.to_string(),    // close_time
                0.0.to_string(),                        // used_usdt
                0.0.to_string(),                        // expected_get_usdt
                0.0.to_string(),                        // pnl
                0.0.to_string(),                        // entry_price
                0.0.to_string(),                        // current_price
                0.0.to_string(),                        // base_qty_ordered
                0.0.to_string(),                        // pure_profit_percent
                0.0.to_string(),                        // minimum_profit_percent
                0.0.to_string(),                        // maximum_profit_percent
            ];

        insert_one_record(&insert_table_name, &insert_columns, &insert_values).await;
    }

    Ok(())
}
