from __future__ import annotations

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

from src.tools.hl_reconcile import main as reconcile_main


def _load_json_from_reconcile(env: str) -> dict[str, Any]:
    # Reuse the existing CLI boundary but capture stdout without importing secrets.
    import contextlib
    import io

    buf = io.StringIO()
    with contextlib.redirect_stdout(buf):
        code = reconcile_main(["--env", env, "--readonly", "--json"])
    payload = json.loads(buf.getvalue())
    payload["reconcile_exit_code"] = code
    return payload


def assess(payload: dict[str, Any]) -> dict[str, Any]:
    alerts = list(payload.get("alerts") or [])
    reconcile_ok = payload.get("status") == "ok"
    critical = not reconcile_ok
    critical = critical or bool(payload.get("block_new_entries")) or bool(payload.get("stops_missing_count"))
    critical = critical or any(str(a).startswith((
        "position_without_stop",
        "stop_wrong_size",
        "stop_wrong_direction",
        "exchange_position_without_local_journal",
        "position_exposure_exceeded",
    )) for a in alerts)
    status = "critical" if critical else ("warning" if alerts else "ok")
    return {
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "status": status,
        "critical": critical,
        "block_new_entries": bool(payload.get("block_new_entries")) or critical,
        "alerts": alerts,
        "stops_missing_count": payload.get("stops_missing_count", 0),
        "positions_count": len(payload.get("positions") or {}),
        "open_orders_count": len(payload.get("open_orders") or []),
        "equity": payload.get("equity"),
        "free_usdc": payload.get("free_usdc"),
        "margin_usage_pct": payload.get("margin_usage_pct"),
        "private_key_used": payload.get("private_key_used"),
        "env": payload.get("env"),
        "address_masked": payload.get("address_masked"),
        "recommended_actions": payload.get("recommended_actions") or [],
    }


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description="Read-only Mainnet reconcile watchdog. Emits output only on critical unless --json is set.")
    parser.add_argument("--env", default="mainnet", choices=["mainnet", "testnet"])
    parser.add_argument("--json", action="store_true")
    parser.add_argument("--quiet-ok", action="store_true", default=False)
    parser.add_argument("--report-path", default="runtime/reports/hl_reconcile_watchdog_latest.json")
    args = parser.parse_args(argv)

    raw = _load_json_from_reconcile(args.env)
    result = assess(raw)
    output = {"watchdog": result, "reconcile": raw}
    report_path = Path(args.report_path)
    report_path.parent.mkdir(parents=True, exist_ok=True)
    report_path.write_text(json.dumps(output, indent=2, sort_keys=True, default=str), encoding="utf-8")

    if args.json or result["critical"] or not args.quiet_ok:
        print(json.dumps(output, indent=2, sort_keys=True, default=str))
    return 2 if result["critical"] else 0


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