use crate::{
    account::{AssetType, OptionType},
    responses::market_data::{GetSymbolDetailsResp, GetSymbolDetailsRespRaw},
    Client, Error,
};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct SymbolDetails {
        pub asset_type: AssetType,
        pub country: String,
        pub currency: String,
                pub description: String,
        pub exchange: String,
                        pub expiration_date: Option<String>,
                pub future_type: Option<String>,
        pub option_type: Option<OptionType>,
        pub price_format: PriceFormat,
        pub quantity_format: QuantityFormat,
            pub root: String,
                pub strike_price: String,
        pub symbol: String,
                pub underlying: String,
}
impl SymbolDetails {
                                                                    pub async fn fetch(
        client: &mut Client,
        symbols: Vec<&str>,
    ) -> Result<Vec<SymbolDetails>, Error> {
        let endpoint = format!("marketdata/symbols/{}", symbols.join(","));
        let resp: GetSymbolDetailsResp = client
            .get(&endpoint)
            .await?
            .json::<GetSymbolDetailsRespRaw>()
            .await?
            .into();
        if let Some(symbol_details) = resp.symbols {
            Ok(symbol_details)
        } else {
            Err(resp.error.unwrap_or(Error::UnknownTradeStationAPIError))
        }
    }
}
impl Client {
                                                                    pub async fn get_symbol_details(
        &mut self,
        symbols: Vec<&str>,
    ) -> Result<Vec<SymbolDetails>, Error> {
        SymbolDetails::fetch(self, symbols).await
    }
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct PriceFormat {
        pub format: Format,
                pub decimals: Option<String>,
                pub fraction: Option<String>,
                pub sub_fraction: Option<String>,
        pub increment_style: IncrementStyle,
                pub increment: Option<String>,
        pub increment_schedule: Option<Vec<IncrementSchedule>>,
        pub point_value: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum Format {
                Decimal,
                        Fraction,
                        SubFraction,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum IncrementStyle {
        Simple,
        Schedule,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct IncrementSchedule {
        pub increment: String,
        pub starts_at: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct QuantityFormat {
                pub format: Format,
        pub decimals: String,
        pub increment_style: IncrementStyle,
                pub increment: Option<String>,
        pub increment_schedule: Option<Vec<IncrementSchedule>>,
        pub minimum_trade_quantity: String,
}