"""Tests for the OpenHedgeAgent client."""

from __future__ import annotations

import pytest

from openhedge.client import OpenHedgeAgent
from openhedge.modules.agent import AgentModule
from openhedge.modules.vault import VaultModule
from openhedge.modules.market import MarketModule
from openhedge.modules.trade import TradeModule
from openhedge.modules.trade_raw import TradeRawModule
from openhedge.modules.portfolio import PortfolioModule
from openhedge.modules.leaderboard import LeaderboardModule
from openhedge.modules.stream import StreamModule
from tests.conftest import FAKE_API_KEY, FAKE_PRIVATE_KEY


class TestOpenHedgeAgentInit:
    def test_creates_with_required_params(self):
        agent = OpenHedgeAgent(api_key=FAKE_API_KEY)
        assert repr(agent).startswith("<OpenHedgeAgent")

    def test_creates_with_all_params(self):
        agent = OpenHedgeAgent(
            api_key=FAKE_API_KEY,
            wallet_private_key=FAKE_PRIVATE_KEY,
            network="base-testnet",
            timeout=10.0,
            max_retries=5,
        )
        assert agent._network == "base-testnet"
        assert agent._max_retries == 5

    def test_invalid_network_raises(self):
        with pytest.raises(ValueError, match="Unknown network"):
            OpenHedgeAgent(api_key=FAKE_API_KEY, network="polygon")

    def test_repr_masks_api_key(self):
        agent = OpenHedgeAgent(api_key="oh_secret_key_12345")
        assert "oh_sec..." in repr(agent)
        assert "secret_key_12345" not in repr(agent)


class TestModuleAccessors:
    def test_agent_module(self, agent):
        assert isinstance(agent.agent, AgentModule)
        # Same instance on second access (cached)
        assert agent.agent is agent.agent

    def test_vault_module(self, agent):
        assert isinstance(agent.vault, VaultModule)

    def test_market_module(self, agent):
        assert isinstance(agent.market, MarketModule)

    def test_trade_module(self, agent):
        assert isinstance(agent.trade, TradeModule)

    def test_trade_raw_module(self, agent):
        assert isinstance(agent.trade_raw, TradeRawModule)

    def test_portfolio_module(self, agent):
        assert isinstance(agent.portfolio, PortfolioModule)

    def test_leaderboard_module(self, agent):
        assert isinstance(agent.leaderboard, LeaderboardModule)

    def test_stream_module(self, agent):
        assert isinstance(agent.stream, StreamModule)


class TestAsyncContextManager:
    async def test_context_manager(self):
        async with OpenHedgeAgent(api_key=FAKE_API_KEY) as agent:
            assert agent is not None
        # After exit, client is closed (no error on double close)

    async def test_close_is_idempotent(self, agent):
        await agent.close()
        await agent.close()  # should not raise


class TestWalletAddress:
    def test_address_with_key(self, agent):
        addr = agent.address
        assert addr is not None
        assert addr.startswith("0x")
        assert len(addr) == 42

    def test_address_without_key(self, readonly_agent):
        assert readonly_agent.address is None
