from __future__ import annotations

import argparse
from decimal import Decimal
import json
import os
from pathlib import Path
from typing import Any

from src.config.hyperliquid_env import load_hyperliquid_env, mask_address
from src.hyperliquid.account_state import HyperliquidAccountStateClient
from src.reconciliation.hyperliquid_reconciler import LocalOrderRecord, ReconcilerSnapshot, reconcile_hyperliquid_state


def _load_live_local_orders() -> list[LocalOrderRecord]:
    path = Path("runtime/live/tiny_autonomous_live/state.json")
    try:
        state = json.loads(path.read_text(encoding="utf-8"))
    except Exception:
        return []
    rows: list[LocalOrderRecord] = []
    for coin, entry in (state.get("open_entries") or {}).items():
        rows.append(LocalOrderRecord(coin=str(coin).upper(), client_order_id=str(entry.get("client_order_id", "")), order_role="entry", size=Decimal(str(entry.get("size") or "0"))))
    return rows


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description="Read-only Hyperliquid reconciliation smoke; no orders.")
    parser.add_argument("--env", choices=["mainnet", "testnet"], default=os.getenv("CTB_HL_ENV", "mainnet"))
    parser.add_argument("--readonly", action="store_true", required=True)
    parser.add_argument("--json", action="store_true")
    parser.add_argument("--address", default=None, help="Master/subaccount address for read-only reconciliation; never use private key")
    args = parser.parse_args(argv)
    try:
        env_cfg = load_hyperliquid_env(args.env, allow_errors=False, validation_mode="readonly")
        address = args.address or env_cfg.account_address
        env_file_path = str(env_cfg.env_file_path)
        credential_warning = env_cfg.credential_warning
        warnings = list(env_cfg.warnings)
    except Exception as exc:
        output = {"env": args.env, "readonly": True, "status": "skipped", "reason": "env_load_failed", "errors": [type(exc).__name__, str(exc)], "positions": {}, "open_orders": [], "stops_missing_count": 0, "block_new_entries": False, "recommended_actions": []}
        print(json.dumps(output, indent=2, sort_keys=True))
        return 0
    output: dict[str, Any] = {"env": args.env, "readonly": True, "env_file_path": env_file_path, "address_masked": mask_address(address), "credential_warning": credential_warning, "warnings": warnings, "private_key_used": False, "positions": {}, "open_orders": [], "stops_by_position": {}, "exposure_mismatch": [], "stops_missing_count": 0, "block_new_entries": False, "recommended_actions": []}
    if not address:
        output["status"] = "skipped"
        output["reason"] = "address_missing"
        print(json.dumps(output, indent=2, sort_keys=True))
        return 0
    client = HyperliquidAccountStateClient(env=args.env)
    positions = client.get_open_positions(address)
    open_orders = client.get_open_orders(address)
    local_orders = _load_live_local_orders()
    result = reconcile_hyperliquid_state(ReconcilerSnapshot(positions=positions, open_orders=open_orders, local_orders=local_orders), max_position_notional_usd=Decimal("100"), mids={})
    output.update({
        "status": "ok",
        "equity": str(client.get_account_equity(address)),
        "free_usdc": str(client.get_free_usdc(address)),
        "margin_usage_pct": str(client.get_margin_usage(address)),
        "positions": positions,
        "open_orders": open_orders,
        "stops_by_position": result.stops_by_position,
        "exposure_mismatch": result.exposure_mismatch,
        "stops_missing_count": result.stops_missing_count,
        "block_new_entries": result.block_new_entries,
        "recommended_actions": result.recommended_actions,
        "alerts": result.alerts,
    })
    print(json.dumps(output, indent=2, default=str, sort_keys=True))
    return 0


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