"""Builds the compact, secret-free description of a proposed trade that the AI analyst sees."""
import pandas as pd


def _f(x, n=5):
    try:
        return round(float(x), n)
    except Exception:
        return None


def _session(now):
    h, names = now.hour, []
    if 0 <= h < 9:
        names.append("Tokyo")
    if 7 <= h < 16:
        names.append("London")
    if 12 <= h < 21:
        names.append("New York")
    return " + ".join(names) or "quiet"


def build_context(eng, sig, side, dist, qty, unit_loss, equity, df, now):
    sym = eng.symbol
    pip = spread = None
    try:
        pip = eng.b.pip_size(sym)
        spread = eng.b.spread_pips(sym)
    except Exception:
        pass
    pp = (lambda x: round(x / pip, 1)) if pip else (lambda x: _f(x, 6))
    closed = eng.j.trades(eng.v, "closed")[-8:]
    d = sig.to_dict() if hasattr(sig, "to_dict") else {}
    factors = d.get("factors", {})
    mtf = {k: (v.get("side") if isinstance(v, dict) else v) for k, v in (factors.get("mtf") or {}).items()}
    day_pnl = ((eng.own_equity() if hasattr(eng, "own_equity") else eng.b.equity()) - (eng.day_start or 0)) / (eng.day_start or 1) * 100
    return {
        "symbol": sym, "timeframe": eng.cfg["primary_timeframe"], "utc_time": str(now), "weekday": now.day_name(),
        "session": _session(now),
        "proposal": {"side": sig.side, "entry": _f(sig.price), "stop_pips": pp(dist), "target_pips": pp(dist * eng.p["rr"]),
                     "reward_to_risk": eng.p["rr"], "risk_pct_of_account": round(eng.p["risk_pct"] * 100, 2), "lots": _f(qty, 2)},
        "signal": {"confidence_pct": sig.confidence,
                   "agreeing_factors": [k for k, v in factors.get("bull" if sig.side == "BUY" else "bear", {}).items() if v],
                   "disagreeing_factors": [k for k, v in factors.get("bull" if sig.side == "BUY" else "bear", {}).items() if not v],
                   "rsi": _f(d.get("rsi"), 1), "adx": _f(d.get("adx"), 1), "stoch_k": _f(d.get("stoch_k"), 1),
                   "bollinger_pct_b": _f(d.get("bb_pct"), 2)},
        "higher_timeframes": mtf,
        "market": {"spread_pips": _f(spread, 2), "atr_pips": pp(sig.atr)},
        "last_12_candles_ohlc": [[_f(o), _f(h), _f(l), _f(c)] for o, h, l, c in
                                  df[["open", "high", "low", "close"]].tail(12).to_numpy()],
        "recent_closed_trades": [{"side": t["side"], "result_r": _f(t["pnl"] / t["risk_amount"], 2) if t.get("risk_amount") else None,
                                  "exit": t.get("exit_reason")} for t in closed],
        "account_state": {"drawdown_pct": _f(eng.drawdown_pct(), 2), "today_pnl_pct": _f(day_pnl, 2)},
    }
