from __future__ import annotations

from dataclasses import asdict
import json
import time
from pathlib import Path

from src.ctb_copy.models import WalletSnapshot
from src.hyperliquid.market_data import HyperliquidMarketData, ReadOnlyTransport


class HyperliquidWalletCollector:
    """Read-only wallet collector for shadow-copy research.

    It intentionally uses Info endpoint payloads only and does not import any
    exchange/order executor. Pagination/backfill can be layered on top, but v0
    captures current state plus fills from a bounded time range.
    """

    def __init__(self, env: str | None = None, transport: ReadOnlyTransport | None = None) -> None:
        self.market = HyperliquidMarketData(env=env, transport=transport)

    def collect_wallet_snapshot(self, wallet_address: str, start_time_ms: int | None = None, observed_at_ms: int | None = None) -> WalletSnapshot:
        observed = observed_at_ms or int(time.time() * 1000)
        raw = {
            "clearinghouseState": self.market._post({"type": "clearinghouseState", "user": wallet_address}),
            "openOrders": self.market._post({"type": "openOrders", "user": wallet_address}),
            "portfolio": self.market._post({"type": "portfolio", "user": wallet_address}),
        }
        if start_time_ms is not None:
            raw["userFillsByTime"] = self.market._post({"type": "userFillsByTime", "user": wallet_address, "startTime": start_time_ms})
        return WalletSnapshot(wallet_address=wallet_address, observed_at_ms=observed, source="hyperliquid_info:wallet", raw=raw)

    def write_jsonl(self, snapshots: list[WalletSnapshot], path: str | Path) -> Path:
        target = Path(path)
        target.parent.mkdir(parents=True, exist_ok=True)
        with target.open("a", encoding="utf-8") as f:
            for snapshot in snapshots:
                f.write(json.dumps(asdict(snapshot), sort_keys=True) + "\n")
        return target
