from decimal import Decimal

from binance_quant.futures_models import (
    FuturesAction,
    FuturesPosition,
    FuturesPositionSide,
    FuturesPrediction,
    FuturesSymbolMetadata,
)


def test_futures_position_derives_side_from_signed_quantity():
    long_position = FuturesPosition(
        symbol="btcusdt",
        quantity=Decimal("0.01"),
        entry_price=Decimal("60000"),
        mark_price=Decimal("60100"),
        liquidation_price=Decimal("55000"),
        isolated_margin=Decimal("10"),
        unrealized_pnl=Decimal("1"),
        leverage=3,
        margin_type="isolated",
    )
    short_position = FuturesPosition(
        symbol="ethusdt",
        quantity=Decimal("-0.5"),
        entry_price=Decimal("3000"),
        mark_price=Decimal("2990"),
        liquidation_price=Decimal("3300"),
        isolated_margin=Decimal("20"),
        unrealized_pnl=Decimal("5"),
        leverage=2,
        margin_type="isolated",
    )
    flat_position = FuturesPosition(
        symbol="bnbusdt",
        quantity=Decimal("0"),
        entry_price=Decimal("0"),
        mark_price=Decimal("600"),
        liquidation_price=Decimal("0"),
        isolated_margin=Decimal("0"),
        unrealized_pnl=Decimal("0"),
        leverage=1,
        margin_type="CROSSED",
    )

    assert long_position.symbol == "BTCUSDT"
    assert long_position.side is FuturesPositionSide.LONG
    assert short_position.symbol == "ETHUSDT"
    assert short_position.side is FuturesPositionSide.SHORT
    assert short_position.absolute_quantity == Decimal("0.5")
    assert flat_position.symbol == "BNBUSDT"
    assert flat_position.side is FuturesPositionSide.FLAT
    assert flat_position.margin_type == "crossed"


def test_futures_prediction_normalizes_symbol_and_action():
    prediction = FuturesPrediction(
        symbol="btcusdt",
        action=FuturesAction.OPEN_LONG,
        confidence=Decimal("0.82"),
        reason="trend",
        leverage=3,
        stop_loss_price=Decimal("62000"),
        take_profit_price=Decimal("66000"),
    )

    assert prediction.symbol == "BTCUSDT"
    assert prediction.action is FuturesAction.OPEN_LONG
    assert prediction.close_percent is None


def test_futures_symbol_metadata_normalizes_assets():
    metadata = FuturesSymbolMetadata(
        symbol="btcusdt",
        base_asset="btc",
        quote_asset="usdt",
        min_qty=Decimal("0.001"),
        step_size=Decimal("0.001"),
        tick_size=Decimal("0.1"),
        min_notional=Decimal("100"),
    )

    assert metadata.symbol == "BTCUSDT"
    assert metadata.base_asset == "BTC"
    assert metadata.quote_asset == "USDT"
