from __future__ import annotations

import argparse
import json
from datetime import datetime, timezone
from pathlib import Path

from src.hyperliquid.api_health import ApiHealthMonitor
from src.hyperliquid.market_data import HyperliquidMarketData
from src.market.collector import MarketContextCollector
from src.market.confluence import build_market_confluence_report
from src.market.context import DEFAULT_CONTEXT_UNIVERSE
from src.market.event_risk import load_event_risk_context
from src.market.fundamentals import CoinGeckoFundamentalsClient
from src.market.snapshot import build_normalized_market_snapshot
from src.tools.tradingview_community_ideas import summarize_community_ideas
from src.tools.tradingview_community_track_record import summarize_track_record


def _build_research_sentiment_context(*, coins: tuple[str, ...], runtime_dir: str = "runtime") -> tuple[dict[str, dict], dict]:
    ideas = summarize_community_ideas(runtime_dir)
    track = summarize_track_record(runtime_dir)
    raw_by_coin_ideas = ideas.get("by_coin")
    raw_by_coin_track = track.get("by_coin")
    by_coin_ideas = raw_by_coin_ideas if isinstance(raw_by_coin_ideas, dict) else {}
    by_coin_track = raw_by_coin_track if isinstance(raw_by_coin_track, dict) else {}
    rows: dict[str, dict] = {}
    for coin in coins:
        coin = coin.upper()
        rows[coin] = {
            "source": "tradingview_community_research_context",
            "status": "loaded_research_only",
            "score": "50.00",
            "recent_ideas_count": int(by_coin_ideas.get(coin, 0) or 0),
            "track_record": by_coin_track.get(coin, {"evaluated": 0, "correct": 0, "hitrate_pct": "0.00"}),
            "research_only": True,
            "live_order_allowed": False,
            "mainnet_signed_action": False,
        }
    return rows, {"ideas": ideas, "track_record": track, "research_only": True, "live_order_allowed": False, "mainnet_signed_action": False}


def build_report(*, env: str = "mainnet", coins: tuple[str, ...] = DEFAULT_CONTEXT_UNIVERSE) -> dict:
    health = ApiHealthMonitor()
    snapshot = MarketContextCollector(HyperliquidMarketData(env=env), health).collect(coins=coins)
    event_risk_by_coin, event_risk_summary = load_event_risk_context(coins=coins)
    confluence = build_market_confluence_report(snapshot, event_risk=event_risk_by_coin)
    fundamentals_snapshot = CoinGeckoFundamentalsClient().collect(coins)
    fundamentals_by_coin = {coin: fundamentals_snapshot.for_coin(coin) for coin in snapshot.contexts}
    sentiment_by_coin, sentiment_summary = _build_research_sentiment_context(coins=coins)
    normalized_snapshot = build_normalized_market_snapshot(snapshot, confluence, fundamentals=fundamentals_by_coin, sentiment=sentiment_by_coin, event_risk=event_risk_by_coin)
    payload = {
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "env": env,
        "mode": "read_only_market_snapshot",
        "live_order_allowed": False,
        "mainnet_signed_action": False,
        "api_health": health.report(),
        "fundamentals": fundamentals_snapshot.to_dict(),
        "research_sentiment": sentiment_summary,
        "event_risk": event_risk_summary,
        "market_snapshot": normalized_snapshot.to_dict(),
        "confluence": confluence.to_dict(),
    }
    return payload


def format_report(payload: dict) -> str:
    conf = payload["confluence"]
    lines = [
        "Market Snapshot / Confluence Light:",
        f"mode={payload['mode']}, version={conf.get('score_version', 'unknown')}, regime={conf['market_regime']}, eligible={conf['eligible_count']}, live=nein",
    ]
    for coin, row in sorted(conf["scores"].items(), key=lambda item: item[1]["final_score"], reverse=True):
        lines.append(
            f"- {coin}: final_trade_score={row.get('final_trade_score', row['final_score'])}, rec={row['recommendation']}, "
            f"trend={row['trend_score']}, momentum={row['momentum_score']}, vol={row['volatility_score']}, "
            f"liq={row['liquidity_score']}, deriv={row['derivatives_score']}, risk={row.get('risk_score', 'n/a')}, regime={row['regime_score']}, blockers={row['blockers'] or 'keine'}"
        )
    return "\n".join(lines)


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description="Build read-only HyperLiquid market snapshot + confluence light report.")
    parser.add_argument("--env", choices=["mainnet", "testnet"], default="mainnet")
    parser.add_argument("--coins", default=",".join(DEFAULT_CONTEXT_UNIVERSE))
    parser.add_argument("--output", default="runtime/reports/market_confluence_latest.json")
    parser.add_argument("--json", action="store_true")
    args = parser.parse_args(argv)
    coins = tuple(c.strip().upper() for c in args.coins.split(",") if c.strip())
    payload = build_report(env=args.env, coins=coins)
    output = Path(args.output)
    output.parent.mkdir(parents=True, exist_ok=True)
    output.write_text(json.dumps(payload, indent=2, sort_keys=True, default=str), encoding="utf-8")
    if args.json:
        print(json.dumps({"status": "ok", "output": str(output), "report": payload}, indent=2, sort_keys=True, default=str))
    else:
        print(format_report(payload))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
