from __future__ import annotations

import argparse
import json

import wzrd.__main__ as cli
from wzrd.agent import SLOTS_PER_DAY, WZRDAgent


def test_cmd_earned_uses_live_formatter_without_crashing(monkeypatch, capsys):
    class FakeAgent:
        def authenticate(self, keypair=None):
            return None

        def earned(self, *, token=None):
            return {
                "agent_pubkey": "agent",
                "total_earned_ccm": 1_558_000_000_000,
                "pending_ccm": 558_000_000_000,
                "rank": 81,
                "contribution_streak_days": 3,
                "pipeline": {
                    "state": "claimable",
                    "relay_ready": True,
                    "hint": "ready to relay",
                },
            }

    monkeypatch.setattr("wzrd.agent.WZRDAgent", FakeAgent)

    cli.cmd_earned(argparse.Namespace(keypair=None))

    out = capsys.readouterr().out
    assert "Agent: agent" in out
    assert "Lifetime: 1,558" in out
    assert "Pending: 558" in out
    assert "Rank: #81 | Streak: 3 days" in out
    assert "Pipeline: claimable — relay ready" in out
    assert "ready to relay" in out


def test_cmd_stake_all_uses_nested_status_balance(monkeypatch, capsys):
    captured: dict[str, int | None] = {}

    class FakeAgent(WZRDAgent):
        def authenticate(self, keypair=None):
            self.token = "session-token"
            return None

        def status(self, *, token=None):
            return {"solana": {"ccm_balance": 995_000_000}}

        def stake(self, amount, lock_duration=0, channel_config=None, keypair=None, *, token=None):
            captured["amount"] = amount
            captured["lock_duration"] = lock_duration
            captured["channel_config"] = channel_config
            return {"tx_sig": "stake-tx"}

    monkeypatch.setattr("wzrd.agent.WZRDAgent", FakeAgent)

    cli.cmd_stake(argparse.Namespace(amount="all", lock=30, channel=None, keypair=None))

    assert captured == {
        "amount": 995_000_000,
        "lock_duration": 30 * SLOTS_PER_DAY,
        "channel_config": None,
    }
    out = capsys.readouterr().out
    assert "Staking full balance:" in out
    assert "tx: stake-tx" in out


def test_cmd_status_includes_staking_view(monkeypatch, capsys):
    class FakeAgent:
        def authenticate(self, keypair=None):
            return None

        def status(self, *, token=None):
            return {
                "pubkey": "agent",
                "solana": {
                    "ccm_balance": 99_500_000,
                    "positions": {"active": 0},
                },
            }

        def staking_status(self, *, channel_config=None, token=None):
            return {
                "staked": True,
                "amount": 895_500_000_000,
                "multiplier_bps": 15_000,
                "pending_rewards": 0,
            }

    monkeypatch.setattr("wzrd.agent.WZRDAgent", FakeAgent)

    cli.cmd_status(argparse.Namespace(keypair=None))

    payload = json.loads(capsys.readouterr().out)
    assert payload["solana"]["positions"]["active"] == 0
    assert payload["solana"]["staking"]["staked"] is True
    assert payload["solana"]["staking"]["amount"] == 895_500_000_000


def test_cmd_earned_prints_balances_without_loop_import_crash(monkeypatch, capsys):
    class FakeAgent:
        def authenticate(self, keypair=None):
            return None

        def earned(self, *, token=None):
            return {
                "agent_pubkey": "agent-123",
                "total_earned_ccm": 2_707_440_000_000,
                "pending_ccm": 1_707_440_000_000,
                "rank": 81,
                "contribution_streak_days": 9,
                "pipeline": {
                    "state": "claimable",
                    "relay_ready": True,
                    "hint": "CCM is ready to claim! Call agent.claim() for gasless relay.",
                },
            }

    monkeypatch.setattr("wzrd.agent.WZRDAgent", FakeAgent)

    cli.cmd_earned(argparse.Namespace(keypair=None))

    out = capsys.readouterr().out
    assert "Agent: agent-123" in out
    assert "Lifetime: 2,707" in out
    assert "Pending: 1,707" in out
    assert "Rank: #81 | Streak: 9 days" in out
    assert "Pipeline: claimable" in out
