"""
signals_consumer.py — Lecture du cache signal_aggregator pour market_spy.py
Import : from signals_consumer import get_signal_snapshot, signal_log_entry

Usage dans market_spy.py (observation mode) :
    snap = get_signal_snapshot()
    if snap:
        logger.info(f"   📡 Signaux: {signal_log_entry(snap)}")
"""

import os
import json
import logging
from datetime import datetime, timezone

log = logging.getLogger(__name__)

SCRIPT_DIR  = os.path.dirname(os.path.abspath(__file__))
CACHE_FILE  = os.path.join(SCRIPT_DIR, "signal_cache.json")
CACHE_MAX_AGE_SEC = 180   # Cache > 3min → ignoré (agrégateur probablement mort)


def get_signal_snapshot() -> dict | None:
    """
    Lit le cache JSON écrit par signal_aggregator.py.
    Retourne None si le cache est absent, corrompu ou trop vieux.
    Ne lève jamais d'exception (FAIL_OPEN).
    """
    try:
        if not os.path.exists(CACHE_FILE):
            return None

        mtime = os.path.getmtime(CACHE_FILE)
        age   = datetime.now(timezone.utc).timestamp() - mtime
        if age > CACHE_MAX_AGE_SEC:
            log.debug(f"Cache signal trop vieux ({age:.0f}s > {CACHE_MAX_AGE_SEC}s)")
            return None

        with open(CACHE_FILE) as f:
            data = json.load(f)

        # Validation minimale
        required = {"score_total", "funding_oi", "netflow", "interpretation"}
        if not required.issubset(data.keys()):
            log.debug("Cache signal incomplet")
            return None

        return data

    except Exception as e:
        log.debug(f"Lecture cache signal échouée: {e}")
        return None


def signal_log_entry(snap: dict) -> str:
    """
    Retourne une ligne de log lisible pour un snapshot signal.
    Ex: "score=13.5/20 (BULLISH) | funding=+0.00800% | netflow=+234500$ (ratio=0.55)"
    """
    if not snap:
        return "N/A"
    score   = snap.get("score_total", 0)
    interp  = snap.get("interpretation", "?")
    funding = snap.get("funding_oi", {}).get("avg_funding_pct", 0)
    netflow = snap.get("netflow", {}).get("net_flow_usd", 0)
    ratio   = snap.get("netflow", {}).get("buy_ratio", 0.5)
    mod     = snap.get("size_modulator", 1.0)
    veto    = " ⚠️VETO" if snap.get("veto_active") else ""
    return (
        f"score={score:.1f}/20 ({interp}){veto} | "
        f"funding={funding:+.5f}% | "
        f"netflow={netflow:+.0f}$ (ratio={ratio:.3f}) | "
        f"size_mod=×{mod:.2f}"
    )


def get_size_modulator(snap: dict | None, default: float = 1.0) -> float:
    """
    Retourne le modulateur de taille (0.5-1.0) depuis le snapshot.
    Retourne default si snap=None (fail-open).
    NOTE: En observation mode, ce modulateur N'EST PAS appliqué — utilisé seulement pour log.
    """
    if snap is None:
        return default
    return snap.get("size_modulator", default)


def is_veto_active(snap: dict | None) -> bool:
    """
    Retourne True si le veto est actif.
    NOTE: En observation mode obs_mode=True, toujours False.
    """
    if snap is None:
        return False
    if snap.get("obs_mode", True):
        return False   # Jamais de veto en obs mode
    return snap.get("veto_active", False)
