"""Base strategy class defining the strategy interface."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, Optional

if TYPE_CHECKING:
    from sd_api.models.quote import Quote, QuoteSnapshot
    from sd_api.models.kline import KlineBar
    from sd_api.strategy.context import StrategyContext


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

    Subclass this and override any of the ``on_*`` hooks you need::

        class MyStrategy(BaseStrategy):
            def on_quote(self, quote: Quote, ctx: StrategyContext) -> None:
                if quote.symbol == "XAUUSD" and quote.latency_ms is not None:
                    print(f"Got quote: {quote.bid}/{quote.ask} (latency={quote.latency_ms}ms)")

    All hooks receive a ``StrategyContext`` which provides access to the client,
    store, and persistent state.
    """

    name: str = "BaseStrategy"

    # ── lifecycle hooks ──────────────────────────────────────────────────

    def on_init(self, ctx: "StrategyContext") -> None:
        """Called once when the strategy is initialised."""
        pass

    def on_start(self, ctx: "StrategyContext") -> None:
        """Called when the strategy runner starts."""
        pass

    def on_stop(self, ctx: "StrategyContext") -> None:
        """Called when the strategy runner stops."""
        pass

    # ── data hooks ───────────────────────────────────────────────────────

    def on_quote(self, quote: "Quote", ctx: "StrategyContext") -> None:
        """Called for each incoming single-symbol quote."""
        pass

    def on_snapshot(self, snapshot: "QuoteSnapshot", ctx: "StrategyContext") -> None:
        """Called for each incoming full-market snapshot."""
        pass

    def on_bar(self, bar: "KlineBar", ctx: "StrategyContext") -> None:
        """Called for each completed K-line bar (when using bar-based strategies)."""
        pass

    def on_signal(self, signal: Any, ctx: "StrategyContext") -> None:
        """Called when an analytical signal is generated."""
        pass
