from __future__ import annotations

from typing import Any

from src.ctb_copy.collectors.hyperliquid_vault_collector import HyperliquidVaultCollector
from src.ctb_copy.collectors.hyperliquid_wallet_collector import HyperliquidWalletCollector


class FakeTransport:
    def __init__(self) -> None:
        self.calls: list[dict[str, Any]] = []

    def post(self, url: str, payload: dict[str, Any], timeout: int = 10) -> Any:
        self.calls.append(payload)
        match payload["type"]:
            case "vaultSummaries":
                return [{"name": "Vault A", "vaultAddress": "0xabc", "tvl": "1000"}, None]
            case "clearinghouseState":
                return {"assetPositions": [], "marginSummary": {"accountValue": "100"}}
            case "openOrders":
                return []
            case "portfolio":
                return [["accountValueHistory", []]]
            case "userFillsByTime":
                return []
        raise AssertionError(f"unexpected payload {payload}")


def test_vault_collector_uses_readonly_info_endpoint_payload() -> None:
    transport = FakeTransport()
    snapshots = HyperliquidVaultCollector(transport=transport).collect_vault_summaries(observed_at_ms=123)

    assert [call["type"] for call in transport.calls] == ["vaultSummaries"]
    assert len(snapshots) == 1
    assert snapshots[0].vault_id == "0xabc"
    assert snapshots[0].observed_at_ms == 123
    assert snapshots[0].source == "hyperliquid_info:vaultSummaries"


def test_wallet_collector_captures_state_orders_portfolio_and_optional_fills() -> None:
    transport = FakeTransport()
    snapshot = HyperliquidWalletCollector(transport=transport).collect_wallet_snapshot("0xabc", start_time_ms=100, observed_at_ms=200)

    assert [call["type"] for call in transport.calls] == ["clearinghouseState", "openOrders", "portfolio", "userFillsByTime"]
    assert snapshot.wallet_address == "0xabc"
    assert snapshot.raw["clearinghouseState"]["marginSummary"]["accountValue"] == "100"
