"""
Base Strategy Interface - All strategies must implement this
"""
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Optional
import pandas as pd


@dataclass
class TradingSignal:
    """
    Complete trading signal with ALL parameters
    Strategy calculates everything, bot just executes
    """
    # Core signal
    symbol: str
    side: str  # 'LONG' or 'SHORT'
    entry_price: float

    # Exit parameters (calculated by strategy)
    stop_loss: float
    take_profit: float

    # Trailing stop (optional, calculated by strategy)
    trailing_stop_activation: Optional[float] = None  # Price level to activate trailing
    trailing_stop_distance: Optional[float] = None    # Distance in % from peak

    # Position sizing (calculated by strategy)
    leverage: int = 250
    risk_pct: float = 0.05  # % of capital to risk

    # Metadata
    strategy_name: str = 'UNKNOWN'
    score: float = 0.0
    timeframe: str = '1m'
    timestamp: any = None

    def to_dict(self):
        """Convert to dict for logging"""
        return {
            'symbol': self.symbol,
            'side': self.side,
            'entry': self.entry_price,
            'sl': self.stop_loss,
            'tp': self.take_profit,
            'leverage': self.leverage,
            'strategy': self.strategy_name,
            'score': self.score
        }


class BaseStrategy(ABC):
    """
    Abstract base class for all trading strategies

    Each strategy must:
    1. Generate signals with complete SL/TP/trailing parameters
    2. Be fully self-contained (no dependency on external config)
    3. Be easily swappable
    """

    def __init__(self, name: str):
        self.name = name

    @abstractmethod
    def generate_signal(self, df: pd.DataFrame, symbol: str) -> Optional[TradingSignal]:
        """
        Generate a complete trading signal

        Args:
            df: OHLCV dataframe
            symbol: Trading pair symbol

        Returns:
            TradingSignal with ALL parameters calculated, or None
        """
        pass

    @abstractmethod
    def get_strategy_info(self) -> dict:
        """
        Return strategy metadata

        Returns:
            Dict with strategy info (name, description, expected_return, etc.)
        """
        pass
