use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// Generic Kraken API response wrapper.
#[derive(Debug, Deserialize)]
pub struct KrakenResponse<T> {
    pub error: Vec<String>,
    pub result: Option<T>,
}

// === Market types ===

#[derive(Debug, Deserialize, Serialize)]
pub struct TickerInfo {
    /// Ask [price, whole_lot_volume, lot_volume]
    pub a: Vec<String>,
    /// Bid [price, whole_lot_volume, lot_volume]
    pub b: Vec<String>,
    /// Last trade [price, lot_volume]
    pub c: Vec<String>,
    /// Volume [today, last_24h]
    pub v: Vec<String>,
    /// Volume weighted average price [today, last_24h]
    pub p: Vec<String>,
    /// Number of trades [today, last_24h]
    pub t: Vec<u64>,
    /// Low [today, last_24h]
    pub l: Vec<String>,
    /// High [today, last_24h]
    pub h: Vec<String>,
    /// Opening price today
    pub o: String,
}

pub type TickerResult = HashMap<String, TickerInfo>;

/// Orderbook — parsed manually from Kraken's array format.
#[derive(Debug, Serialize)]
pub struct OrderBook {
    pub asks: Vec<OrderBookLevel>,
    pub bids: Vec<OrderBookLevel>,
}

#[derive(Debug, Serialize)]
pub struct OrderBookLevel {
    pub price: String,
    pub volume: String,
    pub timestamp: u64,
}

// === Account types ===

pub type BalanceResult = HashMap<String, String>;

#[derive(Debug, Deserialize, Serialize)]
pub struct TradeInfo {
    pub ordertxid: Option<String>,
    pub pair: Option<String>,
    pub time: Option<f64>,
    #[serde(rename = "type")]
    pub trade_type: Option<String>,
    pub ordertype: Option<String>,
    pub price: Option<String>,
    pub cost: Option<String>,
    pub fee: Option<String>,
    pub vol: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct TradesHistoryResult {
    pub trades: Option<HashMap<String, TradeInfo>>,
    #[allow(dead_code)]
    pub count: Option<u64>,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct OrderInfo {
    pub status: Option<String>,
    pub opentm: Option<f64>,
    pub descr: Option<OrderDescr>,
    pub vol: Option<String>,
    pub vol_exec: Option<String>,
    pub cost: Option<String>,
    pub fee: Option<String>,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct OrderDescr {
    pub pair: Option<String>,
    #[serde(rename = "type")]
    pub order_type: Option<String>,
    pub ordertype: Option<String>,
    pub price: Option<String>,
    pub order: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct OpenOrdersResult {
    pub open: Option<HashMap<String, OrderInfo>>,
}

// === Trading types ===

#[derive(Debug, Deserialize, Serialize)]
pub struct AddOrderResult {
    pub descr: Option<AddOrderDescr>,
    pub txid: Option<Vec<String>>,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct AddOrderDescr {
    pub order: Option<String>,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct CancelOrderResult {
    pub count: Option<u64>,
}
