"""
Breakout strategy for XAUUSD
Auto-generated by StrategyCodeGenerator.
Strategy ID: breakout_strategy_for_xauusd
"""
from strategy_sdk.interfaces import StrategyPlugin
from strategy_sdk.types import (
    MarketSnapshot,
    PortfolioStateView,
    StrategyInitContext,
    StrategyIntent,
    StrategyManifest,
    StrategyRiskOpinion,
)


class BreakoutStrategyForXauusd(StrategyPlugin):
    """Breakout strategy for XAUUSD"""

    def __init__(self, params=None):
        self._params = params or {}
        self._ctx = None

    def manifest(self):
        return StrategyManifest(
            strategy_id="breakout_strategy_for_xauusd",
            name="Breakout strategy for XAUUSD",
            version="1.0.0",
            kind="signal",
            entrypoint="strategies.breakout_strategy_for_xauusd",
            description="Breakout strategy for XAUUSD",
            author="AI",
            tags=[["ai-generated"]],
            capabilities=[["intraday"]],
            supported_symbols=["XAUUSD"],
            supported_timeframes=["M5", "M15", "H1"],
            params_schema={"ema_short": {"type": "int", "default": 9, "range": [5, 20]}, "ema_long": {"type": "int", "default": 21, "range": [15, 50]}, "atr_period": {"type": "int", "default": 14, "range": [7, 21]}},
            default_mode="plugin",
            trust_level="sandbox",
        )

    def initialize(self, ctx: StrategyInitContext) -> None:
        self._ctx = ctx
        self._params.update(ctx.config)

    def on_market_snapshot(self, snapshot: MarketSnapshot) -> StrategyIntent:
        bars = snapshot.bars
        if not bars or len(bars) < 20:
            return StrategyIntent(
                strategy_id=self.manifest().strategy_id,
                strategy_version="1.0.0",
                config_revision="sandbox",
                instance_id="brk",
                action="HOLD",
                side="BUY",
                confidence=0.0,
                reason="insufficient bars",
            )

        highs = [float(b.get("high", 0)) for b in bars]
        lows = [float(b.get("low", 0)) for b in bars]
        closes = [float(b.get("close", 0)) for b in bars]
        n = len(closes)
        atr_period = int(self._params.get("atr_period", 14))
        lookback = int(self._params.get("ema_long", 20))
        lookback = max(lookback, 5)
        lookback = min(lookback, len(bars) - 1)

        highest_bb = max(highs[-(lookback+1):-1]) if n > lookback + 1 else max(highs[:-1])
        lowest_bb = min(lows[-(lookback+1):-1]) if n > lookback + 1 else min(lows[:-1])
        entry = closes[-1]
        atr = sum(h - l for h, l in zip(highs[-atr_period:], lows[-atr_period:])) / atr_period

        if entry > highest_bb:
            return StrategyIntent(
                strategy_id=self.manifest().strategy_id,
                strategy_version="1.0.0",
                config_revision="sandbox",
                instance_id="brk",
                action="BUY",
                side="BUY",
                confidence=0.72,
                reason=f"breakout above {lookback}-bar high {highest_bb:.1f}",
                entry_plan={"entry": entry},
                exit_plan={"sl": entry - 1.5 * atr, "tp": entry + 3.0 * atr},
            )
        if entry < lowest_bb:
            return StrategyIntent(
                strategy_id=self.manifest().strategy_id,
                strategy_version="1.0.0",
                config_revision="sandbox",
                instance_id="brk",
                action="SELL",
                side="SELL",
                confidence=0.72,
                reason=f"breakdown below {lookback}-bar low {lowest_bb:.1f}",
                entry_plan={"entry": entry},
                exit_plan={"sl": entry + 1.5 * atr, "tp": entry - 3.0 * atr},
            )
        return StrategyIntent(
            strategy_id=self.manifest().strategy_id,
            strategy_version="1.0.0",
            config_revision="sandbox",
            instance_id="brk",
            action="HOLD",
            side="BUY",
            confidence=0.0,
            reason="no breakout",
        )

    def on_risk_check(
        self,
        intent: StrategyIntent,
        portfolio: PortfolioStateView,
    ) -> StrategyRiskOpinion:
        # NOTE: allow=True by design. Per-strategy risk opinions are advisory only.
        # Hard blocking (circuit breaker, daily loss, session filter, spread, position
        # limits) is enforced centrally by bridge/risk_manager.py.
        reasons = []
        if intent.action == "HOLD":
            return StrategyRiskOpinion(allow=True, reasons=["no action"])
        if intent.confidence < 0.5:
            reasons.append("low confidence")
        if portfolio.position_side != "FLAT" and portfolio.position_side == intent.side:
            reasons.append("already positioned")
        if not reasons:
            reasons.append("signal OK")
        return StrategyRiskOpinion(
            allow=True,
            severity="WARN" if reasons else "INFO",
            score=intent.confidence,
            reasons=reasons,
        )

    def shutdown(self) -> None:
        pass
