// Tech Lead mini-task (Wave 4): replaced stubs with full type definitions
// per 05_detail_design.md §2.3

use serde::{Deserialize, Serialize};
use crate::futures::models::de;

// --- Balance ---

/// Account balance for a single asset.
#[derive(Debug, Deserialize)]
pub struct Balance {
    pub asset: String,
    /// Some testnet deployments return this field as `"balance"` instead of `"walletBalance"`.
    #[serde(rename = "walletBalance", alias = "balance")]
    pub wallet_balance: String,
    #[serde(rename = "crossWalletBalance")]
    pub cross_wallet_balance: String,
    #[serde(rename = "crossUnPnl")]
    pub cross_unpnl: String,
    #[serde(rename = "availableBalance")]
    pub available_balance: String,
    #[serde(rename = "maxWithdrawAmount")]
    pub max_withdraw_amount: String,
    #[serde(rename = "updateTime")]
    pub update_time: u64,
}

// --- Position Side ---

/// Response for the position side dual (hedge mode) setting.
#[derive(Debug, Deserialize)]
pub struct PositionSideDualResponse {
    #[serde(rename = "dualSidePosition")]
    pub dual_side_position: bool,
}

// --- Leverage ---

/// Leverage bracket information for a symbol.
#[derive(Debug, Deserialize)]
pub struct LeverageBracket {
    pub symbol: String,
    pub brackets: Vec<Bracket>,
}

/// A single leverage bracket within a `LeverageBracket`.
///
/// `notional_cap`, `notional_floor`, `maint_margin_ratio`, and `cum` are returned
/// as JSON numbers on some deployments and as JSON strings on others — the
/// `string_or_number` deserializer normalises both forms to `String`.
#[derive(Debug, Deserialize)]
pub struct Bracket {
    pub bracket: u32,
    #[serde(rename = "initialLeverage")]
    pub initial_leverage: u32,
    #[serde(rename = "notionalCap", deserialize_with = "de::string_or_number")]
    pub notional_cap: String,
    #[serde(rename = "notionalFloor", deserialize_with = "de::string_or_number")]
    pub notional_floor: String,
    #[serde(rename = "maintMarginRatio", deserialize_with = "de::string_or_number")]
    pub maint_margin_ratio: String,
    #[serde(deserialize_with = "de::string_or_number")]
    pub cum: String,
}

/// Response from setting leverage for a symbol.
#[derive(Debug, Deserialize)]
pub struct SetLeverageResponse {
    pub leverage: u32,
    #[serde(rename = "maxNotionalValue")]
    pub max_notional_value: String,
    pub symbol: String,
}

// --- Cancel All Orders ---

/// Response from cancelling all open orders for a symbol.
#[derive(Debug, Deserialize)]
pub struct CancelAllResponse {
    pub code: i64,
    pub msg: String,
}

// --- Batch Orders ---

/// Per-item result in a batch order response.
/// May be a success (has `order_id`) or an error (has `code` + `msg`).
#[derive(Debug, Deserialize)]
pub struct BatchOrderResult {
    #[serde(rename = "orderId")]
    pub order_id: Option<i64>,
    pub code: Option<i64>,
    pub msg: Option<String>,
    pub symbol: Option<String>,
    pub status: Option<String>,
}

// --- Generic Status/Message Response ---

/// Generic status/message response (code + message).
#[derive(Debug, Deserialize)]
pub struct StatusMsgResponse {
    pub code: i64,
    pub msg: String,
}

// --- MMP (used in Wave 9) ---

/// Market Maker Protection (MMP) configuration response.
#[derive(Debug, Deserialize)]
pub struct MmpResponse {
    pub symbol: String,
    #[serde(rename = "quantityLimit")]
    pub quantity_limit: String,
    #[serde(rename = "deltaLimit")]
    pub delta_limit: String,
    #[serde(rename = "timeWindowMs")]
    pub time_window_ms: u64,
    #[serde(rename = "frozenTimeMs")]
    pub frozen_time_ms: u64,
}

/// Parameters for updating MMP configuration.
#[derive(Debug, Serialize)]
pub struct MmpUpdateParams {
    pub symbol: String,
    #[serde(rename = "quantityLimit")]
    pub quantity_limit: String,
    #[serde(rename = "deltaLimit")]
    pub delta_limit: String,
    #[serde(rename = "timeWindowMs")]
    pub time_window_ms: u64,
    #[serde(rename = "frozenTimeMs")]
    pub frozen_time_ms: u64,
}

// --- Wallet Transfer (used in Wave 9) ---

/// Parameters for a wallet asset transfer.
#[derive(Debug, Serialize)]
pub struct WalletTransferParams {
    pub asset: String,
    pub amount: String,
    #[serde(rename = "type")]
    pub transfer_type: u32,
}

/// Response from a wallet asset transfer — contains the transaction ID.
#[derive(Debug, Deserialize)]
pub struct WalletTransferResponse {
    #[serde(rename = "tranId")]
    pub tran_id: i64,
}

// --- ADL Quantile (used in Wave 9) ---

/// ADL (Auto-Deleveraging) quantile information for a symbol.
#[derive(Debug, Deserialize)]
pub struct AdlQuantileResponse {
    pub symbol: String,
    #[serde(rename = "adlQuantile")]
    pub adl_quantile: serde_json::Value,
}

// --- Commission Rate (used in Wave 9) ---

/// Commission rates for a trading symbol.
#[derive(Debug, Deserialize)]
pub struct CommissionRateResponse {
    pub symbol: String,
    #[serde(rename = "makerCommissionRate")]
    pub maker_commission_rate: String,
    #[serde(rename = "takerCommissionRate")]
    pub taker_commission_rate: String,
}

// --- Multi-Assets Mode (used in Wave 9) ---

/// Multi-assets margin mode setting.
#[derive(Debug, Deserialize)]
pub struct MultiAssetsModeResponse {
    #[serde(rename = "multiAssetsMargin")]
    pub multi_assets_margin: bool,
}
