# src/strategies/base.py

from abc import ABC, abstractmethod
import pandas as pd
from src.core.strategy import Signal


class Strategy(ABC):
    """
    Clase base para todas las estrategias.

    Flujo:
    - Engine llama a set_data(data)
    - set_data → init_indicators
    - Engine llama a generate_signal(idx)
    """

    def __init__(self, name: str, params: dict | None = None):
        self.name = name
        self.params = params or {}
        self.data: pd.DataFrame | None = None

    def set_data(self, data: pd.DataFrame):
        """
        Inyecta el DataFrame y calcula indicadores.
        """
        self.data = self.init_indicators(data.copy())

    @abstractmethod
    def init_indicators(self, data: pd.DataFrame) -> pd.DataFrame:
        """
        Calcula y añade indicadores al DataFrame.
        """
        pass

    @abstractmethod
    def generate_signal(self, idx: int) -> Signal:
        """
        Devuelve BUY / SELL / HOLD para el índice idx.
        """
        pass

    def __repr__(self):
        params = ", ".join(f"{k}={v}" for k, v in self.params.items())
        return f"{self.name}({params})"
