"""
Configuration for Live Trading.

Loads OKX API credentials from environment variables.
Uses demo/sandbox mode by default for paper trading.
"""
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."""
        # Check demo mode first
        self.demo_mode = os.getenv("OKX_DEMO_MODE", "true").lower() in ("true", "1", "yes")
        
        if self.demo_mode:
            # Load demo-specific credentials if available
            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:
            # Load live credentials
            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 TradingConfig:
    """Trading parameters configuration."""
    # Trading pairs
    eth_symbol: str = "ETH/USDT:USDT"  # ETH perpetual (primary trading asset)
    btc_symbol: str = "BTC/USDT:USDT"  # BTC perpetual (context asset)
    
    # Timeframe
    timeframe: str = "1h"
    candles_to_fetch: int = 500  # Enough for feature calculation
    
    # Position sizing
    max_position_usdt: float = -1.0    # Max position size in USDT. If <= 0, use all available funds
    min_position_usdt: float = 10.0    # Min position size in USDT
    leverage: int = 1                  # Leverage (1x = no leverage)
    margin_mode: str = "cross"         # "cross" or "isolated"
    
    # Risk management
    stop_loss_pct: float = 0.06        # 6% stop loss
    take_profit_pct: float = 0.05      # 5% take profit
    max_concurrent_positions: int = 1  # Max open positions
    
    # Strategy parameters (from regime_strategy.py)
    z_entry_threshold: float = 1.0     # Enter when |Z| > 1.0
    z_window: int = 24                 # 24h rolling Z-score window
    model_prob_threshold: float = 0.5  # ML model probability threshold
    funding_threshold: float = 0.005   # Funding rate filter threshold
    
    # Execution
    sleep_seconds: int = 3600          # Run every hour (1h candles)
    slippage_pct: float = 0.001        # 0.1% slippage buffer


@dataclass
class PathConfig:
    """File paths configuration."""
    base_dir: Path = field(
        default_factory=lambda: Path(__file__).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)
    cq_data_path: Path = field(default=None)
    
    def __post_init__(self):
        self.data_dir = self.base_dir / "data"
        self.logs_dir = self.base_dir / "logs"
        self.model_path = self.base_dir / "live_trading" / "regime_model.pkl"
        self.positions_file = self.base_dir / "live_trading" / "positions.json"
        self.trade_log_file = self.base_dir / "live_trading" / "trade_log.csv"
        self.cq_data_path = self.data_dir / "cq_training_data.csv"
        
        # Ensure directories exist
        self.data_dir.mkdir(parents=True, exist_ok=True)
        self.logs_dir.mkdir(parents=True, exist_ok=True)


def get_config():
    """Get all configuration objects."""
    okx = OKXConfig()
    trading = TradingConfig()
    paths = PathConfig()
    return okx, trading, paths
