//! # KuCoin Endpoints
//!
//! URL'ы и endpoint enum для KuCoin API.

use crate::core::types::AccountType;

// ═══════════════════════════════════════════════════════════════════════════════
// URLs
// ═══════════════════════════════════════════════════════════════════════════════

/// URL'ы для KuCoin API
#[derive(Debug, Clone)]
pub struct KuCoinUrls {
    pub spot_rest: &'static str,
    pub futures_rest: &'static str,
    pub spot_ws: &'static str,
    pub futures_ws: &'static str,
}

impl KuCoinUrls {
    /// Production URLs
    pub const MAINNET: Self = Self {
        spot_rest: "https://api.kucoin.com",
        futures_rest: "https://api-futures.kucoin.com",
        spot_ws: "wss://ws-api-spot.kucoin.com",
        futures_ws: "wss://ws-api-futures.kucoin.com",
    };

    /// Sandbox URLs
    pub const TESTNET: Self = Self {
        spot_rest: "https://openapi-sandbox.kucoin.com",
        futures_rest: "https://api-sandbox-futures.kucoin.com",
        spot_ws: "wss://ws-api-sandbox.kucoin.com",
        futures_ws: "wss://ws-api-sandbox-futures.kucoin.com",
    };

    /// Получить REST base URL для account type
    pub fn rest_url(&self, account_type: AccountType) -> &str {
        match account_type {
            AccountType::Spot | AccountType::Margin => self.spot_rest,
            AccountType::FuturesCross | AccountType::FuturesIsolated => self.futures_rest,
            _ => self.spot_rest,
        }
    }

    /// Получить WebSocket URL для account type
    pub fn ws_url(&self, account_type: AccountType) -> &str {
        match account_type {
            AccountType::Spot | AccountType::Margin => self.spot_ws,
            AccountType::FuturesCross | AccountType::FuturesIsolated => self.futures_ws,
            _ => self.spot_ws,
        }
    }
}

// ═══════════════════════════════════════════════════════════════════════════════
// ENDPOINTS
// ═══════════════════════════════════════════════════════════════════════════════

/// KuCoin API endpoints
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum KuCoinEndpoint {
    // === ОБЩИЕ ===
    Timestamp,

    // === SPOT MARKET DATA ===
    SpotPrice,
    SpotOrderbook,
    SpotKlines,
    SpotTicker,
    SpotAllTickers,
    SpotSymbols,

    // === SPOT TRADING ===
    SpotCreateOrder,
    SpotCancelOrder,
    SpotGetOrder,
    SpotOpenOrders,
    SpotAllOrders,
    SpotCancelAllOrders,

    // === SPOT OCO ===
    SpotOcoOrder,

    // === SPOT BATCH ORDERS (HF Pro) ===
    SpotBatchOrders,

    // === FUTURES BATCH ORDERS ===
    FuturesBatchOrders,

    // === SPOT ACCOUNT ===
    SpotAccounts,
    SpotAccountDetail,

    // === FUTURES MARKET DATA ===
    FuturesPrice,
    FuturesOrderbook,
    FuturesKlines,
    FuturesTicker,
    FuturesAllTickers,
    FuturesContracts,
    FundingRate,

    // === FUTURES TRADING ===
    FuturesCreateOrder,
    FuturesCancelOrder,
    FuturesGetOrder,
    FuturesOpenOrders,
    FuturesAllOrders,
    FuturesCancelAllOrders,

    // === FUTURES AMEND ORDER ===
    FuturesAmendOrder,

    // === FUTURES ACCOUNT ===
    FuturesAccount,
    FuturesPositions,
    FuturesPosition,
    FuturesSetLeverage,

    // === ACCOUNT TRANSFERS ===
    /// POST /api/v3/accounts/inner-transfer — transfer between account types
    InnerTransfer,
    /// GET /api/v1/accounts/inner-transfer — transfer history (paginated)
    TransferHistory,

    // === CUSTODIAL FUNDS ===
    /// GET /api/v3/deposit-addresses — deposit address for an asset/chain
    DepositAddress,
    /// POST /api/v1/withdrawals — submit withdrawal request
    Withdraw,
    /// GET /api/v1/deposits — deposit history
    DepositHistory,
    /// GET /api/v1/withdrawals — withdrawal history
    WithdrawalHistory,

    // === SUB-ACCOUNTS ===
    /// POST /api/v2/sub/user/created — create sub-account
    SubAccountCreate,
    /// GET /api/v2/sub/user — list sub-accounts
    SubAccountList,
    /// POST /api/v2/accounts/sub-transfer — transfer to/from sub-account
    SubAccountTransfer,
    /// GET /api/v1/sub-accounts/{subUserId} — get sub-account balance
    SubAccountBalance,

    // === SPOT MARKET DATA EXTENSIONS ===
    /// GET /api/v1/market/histories — recent spot trades (public)
    SpotRecentTrades,
    /// GET /api/v1/market/orderbook/level2 — full order book (public)
    FullOrderbook,

    // === SPOT FILL HISTORY ===
    /// GET /api/v1/fills — spot trade fills (signed)
    SpotFills,

    // === FUTURES MARKET DATA EXTENSIONS ===
    /// GET /api/v1/trade/history — futures recent trades (public)
    FuturesTradeHistory,
    /// GET /api/v1/contract/funding-rates — futures funding rate history (public)
    FuturesFundingRates,
    /// GET /api/v1/mark-price/{symbol}/current — futures mark price (public)
    FuturesMarkPrice,
    /// GET /api/v1/index-price/{symbol}/current — futures index price (public)
    FuturesIndexPrice,
    /// GET /api/v1/premium-index/{symbol}/current — futures premium index (public)
    FuturesPremiumIndex,

    // === FUTURES FILL HISTORY ===
    /// GET /api/v1/fills — futures trade fills (signed, futures base URL)
    FuturesFills,

    // === WEBSOCKET ===
    WsPublicToken,
    WsPrivateToken,

    // === C3 ADDITIONS ===
    /// GET /api/v1/accounts/transferable — query transferable quota for an asset
    TransferQuotas,
    /// DELETE /api/v1/withdrawals/{withdrawalId} — cancel a pending withdrawal by ID
    WithdrawalCancel,
    /// GET /api/v1/withdrawals/quotas — query withdrawal quota for an asset/chain
    WithdrawalQuotas,

    // === FUNDING HISTORY ===
    /// GET /api/v1/funding-history — personal funding payment records (futures domain)
    FuturesFundingHistory,

    // === ACCOUNT LEDGER ===
    /// GET /api/v1/accounts/ledgers — spot/main account ledger (paginated)
    SpotLedger,

    // === FUTURES OPEN INTEREST ===
    /// GET /api/v1/contracts/{symbol} — futures contract details including OI (public, futures domain)
    FuturesContractDetail,

    // === NEW ADDITIONS ===
    /// GET /api/v1/contracts/risk-limit/{symbol} — risk limit tiers (public, futures domain)
    FuturesRiskLimit,
}

impl KuCoinEndpoint {
    /// Получить путь endpoint'а
    pub fn path(&self) -> &'static str {
        match self {
            // Общие
            Self::Timestamp => "/api/v1/timestamp",

            // Spot Market Data
            Self::SpotPrice => "/api/v1/market/orderbook/level1",
            Self::SpotOrderbook => "/api/v1/market/orderbook/level2_100",
            Self::SpotKlines => "/api/v1/market/candles",
            Self::SpotTicker => "/api/v1/market/stats",
            Self::SpotAllTickers => "/api/v1/market/allTickers",
            Self::SpotSymbols => "/api/v2/symbols",

            // Spot Trading
            Self::SpotCreateOrder => "/api/v1/orders",
            Self::SpotCancelOrder => "/api/v1/orders/{orderId}",
            Self::SpotGetOrder => "/api/v1/orders/{orderId}",
            Self::SpotOpenOrders => "/api/v1/orders",
            Self::SpotAllOrders => "/api/v1/orders",
            Self::SpotCancelAllOrders => "/api/v1/orders",

            // Spot OCO
            Self::SpotOcoOrder => "/api/v3/oco/order",

            // Spot Batch Orders (HF Pro account — up to 5 limit orders, same pair)
            Self::SpotBatchOrders => "/api/v1/hf/orders/multi",

            // Futures Batch Orders (up to 20 orders)
            Self::FuturesBatchOrders => "/api/v1/orders/multi",

            // Spot Account
            Self::SpotAccounts => "/api/v1/accounts",
            Self::SpotAccountDetail => "/api/v1/accounts/{accountId}",

            // Futures Market Data
            Self::FuturesPrice => "/api/v1/ticker",
            Self::FuturesOrderbook => "/api/v1/level2/depth100",
            Self::FuturesKlines => "/api/v1/kline/query",
            Self::FuturesTicker => "/api/v1/ticker",
            Self::FuturesAllTickers => "/api/v1/allTickers",
            Self::FuturesContracts => "/api/v1/contracts/active",
            Self::FundingRate => "/api/v1/funding-rate/{symbol}/current",

            // Futures Trading
            Self::FuturesCreateOrder => "/api/v1/orders",
            Self::FuturesCancelOrder => "/api/v1/orders/{orderId}",
            Self::FuturesGetOrder => "/api/v1/orders/{orderId}",
            Self::FuturesOpenOrders => "/api/v1/orders",
            Self::FuturesAllOrders => "/api/v1/orders",
            Self::FuturesCancelAllOrders => "/api/v1/orders",

            // Futures Amend Order
            Self::FuturesAmendOrder => "/api/v1/orders/{orderId}",

            // Futures Account
            Self::FuturesAccount => "/api/v1/account-overview",
            Self::FuturesPositions => "/api/v1/positions",
            Self::FuturesPosition => "/api/v1/position",
            Self::FuturesSetLeverage => "/api/v1/position/risk-limit-level/change",

            // Account Transfers
            Self::InnerTransfer => "/api/v3/accounts/inner-transfer",
            Self::TransferHistory => "/api/v1/accounts/inner-transfer",

            // Custodial Funds
            Self::DepositAddress => "/api/v3/deposit-addresses",
            Self::Withdraw => "/api/v1/withdrawals",
            Self::DepositHistory => "/api/v1/deposits",
            Self::WithdrawalHistory => "/api/v1/withdrawals",

            // Sub-Accounts
            Self::SubAccountCreate => "/api/v2/sub/user/created",
            Self::SubAccountList => "/api/v2/sub/user",
            Self::SubAccountTransfer => "/api/v2/accounts/sub-transfer",
            Self::SubAccountBalance => "/api/v1/sub-accounts/{subUserId}",

            // Spot Market Data Extensions
            Self::SpotRecentTrades => "/api/v1/market/histories",
            Self::FullOrderbook => "/api/v1/market/orderbook/level2",

            // Spot Fill History
            Self::SpotFills => "/api/v1/fills",

            // Futures Market Data Extensions
            Self::FuturesTradeHistory => "/api/v1/trade/history",
            Self::FuturesFundingRates => "/api/v1/contract/funding-rates",
            Self::FuturesMarkPrice => "/api/v1/mark-price/{symbol}/current",
            Self::FuturesIndexPrice => "/api/v1/index-price/{symbol}/current",
            Self::FuturesPremiumIndex => "/api/v1/premium-index/{symbol}/current",

            // Futures Fill History
            Self::FuturesFills => "/api/v1/fills",

            // WebSocket
            Self::WsPublicToken => "/api/v1/bullet-public",
            Self::WsPrivateToken => "/api/v1/bullet-private",

            // C3 Additions
            Self::TransferQuotas => "/api/v1/accounts/transferable",
            Self::WithdrawalCancel => "/api/v1/withdrawals/{withdrawalId}",
            Self::WithdrawalQuotas => "/api/v1/withdrawals/quotas",

            // Funding History
            Self::FuturesFundingHistory => "/api/v1/funding-history",

            // Account Ledger
            Self::SpotLedger => "/api/v1/accounts/ledgers",

            // Futures Open Interest (via contract detail)
            Self::FuturesContractDetail => "/api/v1/contracts/{symbol}",

            // New Additions
            Self::FuturesRiskLimit => "/api/v1/contracts/risk-limit/{symbol}",
        }
    }

    /// Требует ли endpoint авторизации
    pub fn requires_auth(&self) -> bool {
        match self {
            // Public endpoints
            Self::Timestamp
            | Self::SpotPrice
            | Self::SpotOrderbook
            | Self::SpotKlines
            | Self::SpotTicker
            | Self::SpotAllTickers
            | Self::SpotSymbols
            | Self::SpotRecentTrades
            | Self::FullOrderbook
            | Self::FuturesPrice
            | Self::FuturesOrderbook
            | Self::FuturesKlines
            | Self::FuturesTicker
            | Self::FuturesAllTickers
            | Self::FuturesContracts
            | Self::FundingRate
            | Self::FuturesTradeHistory
            | Self::FuturesFundingRates
            | Self::FuturesMarkPrice
            | Self::FuturesIndexPrice
            | Self::FuturesPremiumIndex
            | Self::FuturesContractDetail
            | Self::FuturesRiskLimit
            | Self::WsPublicToken => false,

            // Private endpoints
            _ => true,
        }
    }

    /// HTTP метод для endpoint'а
    pub fn method(&self) -> &'static str {
        match self {
            Self::SpotCreateOrder
            | Self::FuturesCreateOrder
            | Self::FuturesAmendOrder
            | Self::SpotOcoOrder
            | Self::SpotBatchOrders
            | Self::FuturesBatchOrders
            | Self::WsPublicToken
            | Self::WsPrivateToken
            | Self::InnerTransfer
            | Self::Withdraw
            | Self::SubAccountCreate
            | Self::SubAccountTransfer => "POST",

            Self::SpotCancelOrder
            | Self::SpotCancelAllOrders
            | Self::FuturesCancelOrder
            | Self::FuturesCancelAllOrders
            | Self::WithdrawalCancel => "DELETE",

            _ => "GET",
        }
    }
}

// ═══════════════════════════════════════════════════════════════════════════════
// SYMBOL FORMATTING
// ═══════════════════════════════════════════════════════════════════════════════

/// Форматирование символа для KuCoin
///
/// # Futures Symbol Format
/// - USDT-margined perpetuals: `XBTUSDTM` (mini contracts, linear)
/// - USD-margined perpetuals: `XBTUSDM` (inverse, coin-margined)
/// - BTC → XBT mapping only applies to futures contracts
///
/// # Examples
/// - Spot: `BTC-USDT`, `ETH-BTC`
/// - USDT Futures: `XBTUSDTM`, `ETHUSDTM`
/// - USD Futures: `XBTUSDM`, `ETHUSDM`
pub fn format_symbol(base: &str, quote: &str, account_type: AccountType) -> String {
    match account_type {
        AccountType::Spot | AccountType::Margin => {
            // Spot: BASE-QUOTE with hyphen
            format!("{}-{}", base, quote)
        }
        AccountType::FuturesCross | AccountType::FuturesIsolated => {
            // BTC → XBT mapping for futures contracts (ISO 4217 standard)
            let base = if base.to_uppercase() == "BTC" { "XBT" } else { base };

            // Distinguish between USDT-margined and USD-margined futures
            // CRITICAL: USDT-margined uses "USDTM", USD-margined uses "USDM"
            match quote.to_uppercase().as_str() {
                "USDT" => format!("{}USDTM", base),  // USDT-margined perpetual (mini, linear)
                "USD" => format!("{}USDM", base),    // USD-margined perpetual (inverse, coin-margined)
                _ => format!("{}{}M", base, quote.to_uppercase()), // Generic fallback
            }
        }
        _ => {
            // Unsupported account types default to spot format
            format!("{}-{}", base, quote)
        }
    }
}

/// Маппинг интервала kline для Spot API (возвращает строки)
///
/// # Spot API Format
/// Parameter: `type` (string)
/// Values: `"1min"`, `"1hour"`, `"1day"`, etc.
pub fn map_kline_interval(interval: &str) -> &'static str {
    match interval {
        "1m" => "1min",
        "3m" => "3min",
        "5m" => "5min",
        "15m" => "15min",
        "30m" => "30min",
        "1h" => "1hour",
        "2h" => "2hour",
        "4h" => "4hour",
        "6h" => "6hour",
        "8h" => "8hour",
        "12h" => "12hour",
        "1d" => "1day",
        "1w" => "1week",
        "1M" => "1month",
        _ => "1hour",
    }
}

/// Map kline interval to Futures granularity (minutes as integer)
///
/// # Futures API Format
/// Parameter: `granularity` (integer representing minutes)
/// Values: `1`, `60`, `1440`, etc.
///
/// # Differences from Spot
/// - Futures uses integer minutes instead of strings
/// - No 3-minute or 6-hour intervals for Futures
/// - No monthly interval for Futures
pub fn map_futures_granularity(interval: &str) -> u32 {
    match interval {
        "1m" => 1,
        "5m" => 5,
        "15m" => 15,
        "30m" => 30,
        "1h" => 60,
        "2h" => 120,
        "4h" => 240,
        "8h" => 480,
        "12h" => 720,
        "1d" => 1440,
        "1w" => 10080,
        _ => 60, // default 1 hour
    }
}
