from __future__ import annotations

from decimal import Decimal

from src.strategies.portfolio_holding_advisor import HoldingCandidate, build_portfolio_holding_advice


def test_portfolio_holding_advisor_allocates_only_to_trend_confirmed_assets() -> None:
    candidates = [
        HoldingCandidate("BTC", Decimal("112"), Decimal("110"), Decimal("95"), Decimal("8.0"), Decimal("120000000"), Decimal("1.0"), Decimal("0.30")),
        HoldingCandidate("SOL", Decimal("100"), Decimal("102"), Decimal("97"), Decimal("12.0"), Decimal("90000000"), Decimal("1.5"), Decimal("0.45")),
        HoldingCandidate("WLD", Decimal("100"), Decimal("130"), Decimal("90"), Decimal("44.0"), Decimal("50000000"), Decimal("4.5"), Decimal("0.80")),
    ]

    advice = build_portfolio_holding_advice(candidates, equity_usdc=Decimal("1000"), max_assets=2)

    assert advice.live_order_allowed is False
    assert advice.mainnet_signed_action is False
    assert [item.coin for item in advice.allocations] == ["BTC"]
    assert advice.allocations[0].target_weight_pct == Decimal("20.00")
    assert advice.allocations[0].action == "advisor_accumulate_watch"
    assert "trend_not_confirmed" in advice.rejected["SOL"]
    assert "volatility_too_high" in advice.rejected["WLD"]


def test_portfolio_holding_advisor_goes_cash_when_regime_is_weak() -> None:
    candidates = [
        HoldingCandidate("ETH", Decimal("100"), Decimal("99"), Decimal("98"), Decimal("-2.0"), Decimal("150000000"), Decimal("1.2"), Decimal("0.20")),
        HoldingCandidate("LINK", Decimal("100"), Decimal("101"), Decimal("103"), Decimal("0.5"), Decimal("70000000"), Decimal("1.0"), Decimal("0.20")),
    ]

    advice = build_portfolio_holding_advice(candidates, equity_usdc=Decimal("1000"), max_assets=3)

    assert advice.allocations == []
    assert advice.cash_weight_pct == Decimal("100.00")
    assert advice.status == "cash_or_wait"
