"""Technical Analysis Agent — RSI, MACD, EMA trend, Bollinger, momentum.
Produces a directional bias (CALL/PUT) and a 0-100 conviction score."""
from .base import Agent, AgentResult
from .indicators import atr, bollinger, ema, macd, rsi, sma


class TechnicalAnalysisAgent(Agent):
    name = "technical"

    def run(self, context: dict) -> AgentResult:
        bars = context["history"]
        closes = [b["close"] for b in bars]
        price = closes[-1]
        notes: list[str] = []
        bull, bear = 0.0, 0.0

        r = rsi(closes)
        m = macd(closes)
        ema9, ema21 = ema(closes, 9), ema(closes, 21)
        sma50 = sma(closes, 50)
        bb = bollinger(closes)
        a = atr(bars) or 0.0
        mom5 = (price / closes[-6] - 1) * 100 if len(closes) > 6 else 0.0

        if r is not None:
            if r >= 60:
                bull += 15; notes.append(f"RSI {r} — bullish momentum")
            elif r <= 40:
                bear += 15; notes.append(f"RSI {r} — bearish momentum")
            else:
                notes.append(f"RSI {r} — neutral")
            if r >= 78:
                bull -= 8; notes.append("RSI overbought — reduced bullish conviction")
            if r <= 22:
                bear -= 8; notes.append("RSI oversold — reduced bearish conviction")

        if m:
            macd_line, signal_line, hist = m
            if hist > 0:
                bull += 20; notes.append(f"MACD histogram positive ({hist:+.3f})")
            else:
                bear += 20; notes.append(f"MACD histogram negative ({hist:+.3f})")

        if ema9 and ema21:
            if ema9 > ema21:
                bull += 20; notes.append("EMA9 above EMA21 — short-term uptrend")
            else:
                bear += 20; notes.append("EMA9 below EMA21 — short-term downtrend")

        if sma50:
            if price > sma50:
                bull += 15; notes.append("Price above SMA50 — bullish structure")
            else:
                bear += 15; notes.append("Price below SMA50 — bearish structure")

        if bb:
            _, _, _, pct_b = bb
            if pct_b > 0.8:
                bull += 10; notes.append(f"Bollinger %B {pct_b} — trading near upper band")
            elif pct_b < 0.2:
                bear += 10; notes.append(f"Bollinger %B {pct_b} — trading near lower band")

        if mom5 > 1.5:
            bull += 10; notes.append(f"5-day momentum {mom5:+.1f}%")
        elif mom5 < -1.5:
            bear += 10; notes.append(f"5-day momentum {mom5:+.1f}%")

        direction = "CALL" if bull >= bear else "PUT"
        raw = max(bull, bear)
        edge = abs(bull - bear)
        score = round(min(100.0, raw * 0.7 + edge * 0.9), 1)

        indicators = {
            "rsi": r,
            "macd": {"line": m[0], "signal": m[1], "histogram": m[2]} if m else None,
            "ema9": round(ema9, 2) if ema9 else None,
            "ema21": round(ema21, 2) if ema21 else None,
            "sma50": round(sma50, 2) if sma50 else None,
            "bollinger": {"upper": bb[0], "mid": bb[1], "lower": bb[2], "pct_b": bb[3]} if bb else None,
            "atr": a,
            "momentum_5d_pct": round(mom5, 2),
        }
        return AgentResult(agent=self.name, score=score, direction=direction,
                           data={"indicators": indicators, "bull_points": bull, "bear_points": bear},
                           notes=notes)
