"""Strategy interface and base classes."""

from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import Optional, List, Dict, Any
from enums import Signal


@dataclass
class TradingDecision:
    """Decision made by a strategy.
    
    Attributes:
        signal: Trading signal (buy, sell, hold, flat)
        confidence: Confidence level (0-1)
        amount: Optional trade amount
        price: Optional target price
        stop_loss: Optional stop loss price
        take_profit: Optional take profit price
        reason: Human-readable explanation
        metadata: Additional strategy-specific data
    """
    signal: Signal
    confidence: float = 0.0
    amount: Optional[float] = None
    price: Optional[float] = None
    stop_loss: Optional[float] = None
    take_profit: Optional[float] = None
    reason: str = ""
    metadata: Dict[str, Any] = field(default_factory=dict)


class Strategy(ABC):
    """Abstract base class for trading strategies.
    
    All strategies must implement this interface.
    Strategies receive market data and return trading decisions.
    """
    
    # Strategy metadata
    id: str = "base_strategy"
    name: str = "Base Strategy"
    version: str = "1.0.0"
    description: str = "Base strategy interface"
    
    # Configuration
    enabled: bool = True
    
    def __init__(self, config: Optional[Dict[str, Any]] = None):
        """Initialize strategy.
        
        Args:
            config: Strategy configuration parameters
        """
        self.config = config or {}
        self._initialized = False
    
    @abstractmethod
    async def analyze(
        self,
        ohlcv: List[Dict[str, float]],
        current_price: float,
        context: Optional[Dict[str, Any]] = None
    ) -> TradingDecision:
        """Analyze market data and return trading decision.
        
        Args:
            ohlcv: List of OHLCV candles
            current_price: Current market price
            context: Additional context (position, balance, etc.)
            
        Returns:
            Trading decision with signal and parameters
        """
        pass
    
    async def initialize(self) -> None:
        """Initialize strategy (called once at startup).
        
        Override this method if your strategy needs setup.
        """
        self._initialized = True
    
    async def on_signal(self, decision: TradingDecision, result: Dict[str, Any]) -> None:
        """Callback when a signal is executed.
        
        Override to track strategy performance.
        
        Args:
            decision: The decision that was executed
            result: Execution result
        """
        pass
    
    async def on_reset(self) -> None:
        """Reset strategy state.
        
        Called when bot restarts or strategy is reloaded.
        """
        self._initialized = False
    
    def validate(self) -> bool:
        """Validate strategy configuration.
        
        Returns:
            True if configuration is valid
            
        Raises:
            ValueError: If configuration is invalid
        """
        return True
    
    def get_indicators(self) -> List[str]:
        """List indicators used by this strategy.
        
        Returns:
            List of indicator names
        """
        return []
    
    def get_description(self) -> str:
        """Get strategy description.
        
        Returns:
            Human-readable description
        """
        return f"{self.name} v{self.version}: {self.description}"
