"""
Configuration for Multi-Pair Live Trading.

Extends the base live trading config with multi-pair specific settings.
"""
import os
from pathlib import Path
from dataclasses import dataclass, field
from dotenv import load_dotenv

load_dotenv()


@dataclass
class OKXConfig:
    """OKX API configuration."""
    api_key: str = field(default_factory=lambda: "")
    secret: str = field(default_factory=lambda: "")
    password: str = field(default_factory=lambda: "")
    demo_mode: bool = field(default_factory=lambda: True)
    
    def __post_init__(self):
        """Load credentials based on demo mode setting."""
        self.demo_mode = os.getenv("OKX_DEMO_MODE", "true").lower() in ("true", "1", "yes")
        
        if self.demo_mode:
            self.api_key = os.getenv("OKX_DEMO_API_KEY", os.getenv("OKX_API_KEY", ""))
            self.secret = os.getenv("OKX_DEMO_SECRET", os.getenv("OKX_SECRET", ""))
            self.password = os.getenv("OKX_DEMO_PASSWORD", os.getenv("OKX_PASSWORD", ""))
        else:
            self.api_key = os.getenv("OKX_API_KEY", "")
            self.secret = os.getenv("OKX_SECRET", "")
            self.password = os.getenv("OKX_PASSWORD", "")
    
    def validate(self) -> None:
        """Validate that required credentials are present."""
        mode = "demo" if self.demo_mode else "live"
        if not self.api_key:
            raise ValueError(f"OKX API key not set for {mode} mode")
        if not self.secret:
            raise ValueError(f"OKX secret not set for {mode} mode")
        if not self.password:
            raise ValueError(f"OKX password not set for {mode} mode")


@dataclass
class MultiPairLiveConfig:
    """
    Configuration for multi-pair live trading.
    
    Combines trading parameters, strategy settings, and risk management.
    """
    # Asset Universe (top 10 by market cap perpetuals)
    assets: list[str] = field(default_factory=lambda: [
        "BTC/USDT:USDT", "ETH/USDT:USDT", "SOL/USDT:USDT", "XRP/USDT:USDT",
        "BNB/USDT:USDT", "DOGE/USDT:USDT", "ADA/USDT:USDT", "AVAX/USDT:USDT",
        "LINK/USDT:USDT", "DOT/USDT:USDT"
    ])
    
    # Timeframe
    timeframe: str = "1h"
    candles_to_fetch: int = 500  # Enough for feature calculation
    
    # Z-Score Thresholds
    z_window: int = 24
    z_entry_threshold: float = 1.0
    z_exit_threshold: float = 0.0  # Exit at mean reversion
    
    # ML Thresholds
    prob_threshold: float = 0.5
    
    # Position sizing
    max_position_usdt: float = -1.0  # If <= 0, use all available funds
    min_position_usdt: float = 10.0
    leverage: int = 1
    margin_mode: str = "cross"
    max_concurrent_positions: int = 1  # Trade one pair at a time
    
    # Risk Management - ATR-Based Stops
    atr_period: int = 14
    sl_atr_multiplier: float = 10.0
    tp_atr_multiplier: float = 8.0
    
    # Fallback fixed percentages
    base_sl_pct: float = 0.06
    base_tp_pct: float = 0.05
    
    # ATR bounds
    min_sl_pct: float = 0.02
    max_sl_pct: float = 0.10
    min_tp_pct: float = 0.02
    max_tp_pct: float = 0.15
    
    # Funding Rate Filter
    funding_threshold: float = 0.0005  # 0.05%
    
    # Trade Management
    min_hold_bars: int = 0
    cooldown_bars: int = 0
    
    # Execution
    sleep_seconds: int = 3600  # Run every hour
    slippage_pct: float = 0.001
    
    def get_asset_short_name(self, symbol: str) -> str:
        """Convert symbol to short name (e.g., BTC/USDT:USDT -> btc)."""
        return symbol.split("/")[0].lower()
    
    def get_pair_count(self) -> int:
        """Calculate number of unique pairs from asset list."""
        n = len(self.assets)
        return n * (n - 1) // 2


@dataclass
class PathConfig:
    """File paths configuration."""
    base_dir: Path = field(
        default_factory=lambda: Path(__file__).parent.parent.parent
    )
    data_dir: Path = field(default=None)
    logs_dir: Path = field(default=None)
    model_path: Path = field(default=None)
    positions_file: Path = field(default=None)
    trade_log_file: Path = field(default=None)
    
    def __post_init__(self):
        self.data_dir = self.base_dir / "data"
        self.logs_dir = self.base_dir / "logs"
        # Use the same model as backtesting
        self.model_path = self.base_dir / "data" / "multi_pair_model.pkl"
        self.positions_file = self.base_dir / "live_trading" / "multi_pair_positions.json"
        self.trade_log_file = self.base_dir / "live_trading" / "multi_pair_trade_log.csv"
        
        # Ensure directories exist
        self.data_dir.mkdir(parents=True, exist_ok=True)
        self.logs_dir.mkdir(parents=True, exist_ok=True)


def get_multi_pair_config() -> tuple[OKXConfig, MultiPairLiveConfig, PathConfig]:
    """Get all configuration objects for multi-pair trading."""
    okx = OKXConfig()
    trading = MultiPairLiveConfig()
    paths = PathConfig()
    return okx, trading, paths
