from __future__ import annotations

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

from eth_account import Account
from hyperliquid.exchange import Exchange

from src.config.hyperliquid_env import load_hyperliquid_env


def _journal(payload: dict) -> Path:
    path = Path("runtime/reports") / f"hyperliquid_deadman_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}.json"
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(payload, indent=2, default=str, sort_keys=True), encoding="utf-8")
    return path


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description="Hyperliquid scheduleCancel smoke. Testnet only.")
    parser.add_argument("--env", choices=["testnet"], required=True)
    parser.add_argument("--seconds", type=int, default=60)
    args = parser.parse_args(argv)
    result = {"env": args.env, "mainnet_blocked": True}
    if args.env != "testnet" or os.getenv("CTB_HL_ENV", "").lower() != "testnet":
        result.update(status="skipped", reason="testnet env required")
        print(json.dumps(result, indent=2)); return 0
    if os.getenv("CTB_TESTNET_TRADING_ALLOWED", "").lower() != "true":
        result.update(status="skipped", reason="CTB_TESTNET_TRADING_ALLOWED must be true")
        print(json.dumps(result, indent=2)); return 0
    try:
        cfg = load_hyperliquid_env("testnet", validation_mode="signed", allow_errors=False)
    except Exception as exc:
        result.update(status="skipped", reason="testnet_env_load_failed", errors=[type(exc).__name__, str(exc)])
        print(json.dumps(result, indent=2)); return 0
    account = Account.from_key(cfg.api_private_key)
    exchange = Exchange(account, "https://api.hyperliquid-testnet.xyz", account_address=cfg.account_address)
    cancel_time_ms = int((time.time() + args.seconds) * 1000)
    set_resp = exchange.schedule_cancel(cancel_time_ms)
    clear_resp = exchange.schedule_cancel(None)
    status = "ok" if set_resp.get("status") != "err" and clear_resp.get("status") != "err" else "error"
    reason = None if status == "ok" else "testnet_schedule_cancel_rejected"
    result.update(status=status, reason=reason, cancel_time_ms=cancel_time_ms, schedule_response=set_resp, clear_response=clear_resp, cancel_plan_removed=(clear_resp.get("status") != "err"))
    path = _journal(result)
    result["journal"] = str(path)
    print(json.dumps(result, indent=2, default=str, sort_keys=True))
    return 0 if result.get("status") in {"ok", "skipped"} else 1


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