"""
Strategy configuration — YAML-based parameter management.

Each strategy gets a YAML file in config/ with its parameters for
backtest, paper, and live environments. The StrategyConfig class
loads and validates these configs.
"""
from __future__ import annotations

import yaml
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any


CONFIG_DIR = Path(__file__).resolve().parent.parent / "config"


@dataclass
class StrategyConfig:
    """Unified strategy configuration across backtest / paper / live."""

    name: str
    instrument: str
    asset: str                          # Base currency (BTC, ETH, etc.)
    allocation: float = 10000.0         # Capital allocated
    order_size: float = 0.001           # Default order size (in base units)
    maker_fee: float = 0.0002
    taker_fee: float = 0.0005
    slippage_bps: float = 1.0
    testnet: bool = True

    # Signal parameters (strategy-specific)
    params: dict[str, Any] = field(default_factory=dict)

    # Risk
    max_position: float = 0.0           # 0 = based on allocation / price
    max_drawdown: float = 0.10
    stop_loss_pct: float = 0.0          # 0 = no stop

    # Derived
    fee_model: str = "taker"            # taker or maker

    @classmethod
    def from_yaml(cls, path: str | Path) -> StrategyConfig:
        with open(path) as f:
            data = yaml.safe_load(f)
        return cls(**data)

    def to_yaml(self, path: str | Path) -> None:
        with open(path, "w") as f:
            yaml.safe_dump(self.__dict__, f, default_flow_style=False)

    def effective_fee(self) -> float:
        return self.maker_fee if self.fee_model == "maker" else self.taker_fee

    @classmethod
    def load_by_name(cls, name: str, env: str = "paper") -> StrategyConfig:
        """Load a strategy config from config/{name}.yaml."""
        config_path = CONFIG_DIR / f"{name}.yaml"
        if not config_path.exists():
            raise FileNotFoundError(f"Config not found: {config_path}")
        cfg = cls.from_yaml(config_path)
        if env == "testnet":
            cfg.testnet = True
        elif env in ("mainnet", "live"):
            cfg.testnet = False
        return cfg
