"""
Tests for paper trading functionality.
"""
import pytest
from paper_strategy_instance import PaperStrategyInstance
from brokers import OrderSide, OrderType, OrderStatus


class TestPaperStrategyInstance:
    """Tests for PaperStrategyInstance."""

    def test_create_instance(self):
        """Test creating a paper strategy instance."""
        instance = PaperStrategyInstance(
            strategy_instance_id='test-instance-1',
            strategy_id='test-strategy-1',
            strategy_name='Test Strategy',
            user_id=1,
            generated_code='def next(self): pass',
            data_cache=None,
            indicators=None,
            trades=None,
            initial_balance=10000.0,
        )

        assert instance.strategy_instance_id == 'test-instance-1'
        assert instance.starting_balance == 10000.0
        assert instance.get_current_balance() == 10000.0
        assert instance.get_available_balance() == 10000.0

    def test_update_prices(self):
        """Test updating prices in paper broker."""
        instance = PaperStrategyInstance(
            strategy_instance_id='test-1',
            strategy_id='strat-1',
            strategy_name='Test',
            user_id=1,
            generated_code='def next(self): pass',
            data_cache=None,
            indicators=None,
            trades=None,
        )

        instance.update_prices({'BTC/USDT': 50000.0, 'ETH/USDT': 3000.0})

        assert instance.get_current_price(symbol='BTC/USDT') == 50000.0
        assert instance.get_current_price(symbol='ETH/USDT') == 3000.0

    def test_trade_order_market_buy(self):
        """Test placing a market buy order."""
        instance = PaperStrategyInstance(
            strategy_instance_id='test-1',
            strategy_id='strat-1',
            strategy_name='Test',
            user_id=1,
            generated_code='def next(self): pass',
            data_cache=None,
            indicators=None,
            trades=None,
            initial_balance=10000.0,
            commission=0.001,
        )

        # Set price
        instance.update_prices({'BTC/USDT': 50000.0})

        # Place order
        result = instance.trade_order(
            trade_type='buy',
            size=0.1,
            order_type='MARKET',
            source={'symbol': 'BTC/USDT'}
        )

        assert result.success
        assert result.status == OrderStatus.FILLED

        # Check position exists
        pos = instance.get_position('BTC/USDT')
        assert pos is not None
        assert pos.size == 0.1

        # Check balance reduced
        assert instance.get_available_balance() < 10000.0

    def test_trade_order_sell(self):
        """Test selling a position."""
        instance = PaperStrategyInstance(
            strategy_instance_id='test-1',
            strategy_id='strat-1',
            strategy_name='Test',
            user_id=1,
            generated_code='def next(self): pass',
            data_cache=None,
            indicators=None,
            trades=None,
            initial_balance=10000.0,
            commission=0,
            slippage=0,
        )

        # Buy first
        instance.update_prices({'BTC/USDT': 50000.0})
        instance.trade_order(
            trade_type='buy',
            size=0.1,
            order_type='MARKET',
            source={'symbol': 'BTC/USDT'}
        )

        # Now sell at higher price
        instance.update_prices({'BTC/USDT': 51000.0})
        result = instance.trade_order(
            trade_type='sell',
            size=0.1,
            order_type='MARKET',
            source={'symbol': 'BTC/USDT'}
        )

        assert result.success

        # Position should be closed
        pos = instance.get_position('BTC/USDT')
        assert pos is None

    def test_close_position(self):
        """Test closing a position via close_position method."""
        instance = PaperStrategyInstance(
            strategy_instance_id='test-1',
            strategy_id='strat-1',
            strategy_name='Test',
            user_id=1,
            generated_code='def next(self): pass',
            data_cache=None,
            indicators=None,
            trades=None,
        )

        instance.update_prices({'BTC/USDT': 50000.0})
        instance.trade_order(
            trade_type='buy',
            size=0.1,
            order_type='MARKET',
            source={'symbol': 'BTC/USDT'}
        )

        result = instance.close_position('BTC/USDT')
        assert result.success

    def test_close_all_positions(self):
        """Test closing all positions."""
        instance = PaperStrategyInstance(
            strategy_instance_id='test-1',
            strategy_id='strat-1',
            strategy_name='Test',
            user_id=1,
            generated_code='def next(self): pass',
            data_cache=None,
            indicators=None,
            trades=None,
        )

        instance.update_prices({'BTC/USDT': 50000.0, 'ETH/USDT': 3000.0})

        instance.trade_order(
            trade_type='buy',
            size=0.1,
            order_type='MARKET',
            source={'symbol': 'BTC/USDT'}
        )
        instance.trade_order(
            trade_type='buy',
            size=1.0,
            order_type='MARKET',
            source={'symbol': 'ETH/USDT'}
        )

        assert instance.get_active_trades() == 2

        results = instance.close_all_positions()
        assert len(results) == 2
        assert all(r.success for r in results)
        assert instance.get_active_trades() == 0

    def test_reset(self):
        """Test resetting paper trading state."""
        instance = PaperStrategyInstance(
            strategy_instance_id='test-1',
            strategy_id='strat-1',
            strategy_name='Test',
            user_id=1,
            generated_code='def next(self): pass',
            data_cache=None,
            indicators=None,
            trades=None,
            initial_balance=10000.0,
        )

        instance.update_prices({'BTC/USDT': 50000.0})
        instance.trade_order(
            trade_type='buy',
            size=0.1,
            order_type='MARKET',
            source={'symbol': 'BTC/USDT'}
        )

        assert instance.get_available_balance() < 10000.0

        instance.reset()

        assert instance.get_available_balance() == 10000.0
        assert instance.get_active_trades() == 0

    def test_get_trade_history(self):
        """Test getting trade history."""
        instance = PaperStrategyInstance(
            strategy_instance_id='test-1',
            strategy_id='strat-1',
            strategy_name='Test',
            user_id=1,
            generated_code='def next(self): pass',
            data_cache=None,
            indicators=None,
            trades=None,
        )

        instance.update_prices({'BTC/USDT': 50000.0})
        instance.trade_order(
            trade_type='buy',
            size=0.1,
            order_type='MARKET',
            source={'symbol': 'BTC/USDT'}
        )

        history = instance.get_trade_history()
        assert len(history) == 1
        assert history[0]['symbol'] == 'BTC/USDT'
        assert history[0]['side'] == 'buy'


class TestStrategiesModeSeletion:
    """Tests for strategy mode selection."""

    def test_mode_selection_imports(self):
        """Test that mode selection imports work."""
        from Strategies import Strategies
        from brokers import TradingMode

        assert TradingMode.PAPER == 'paper'
        assert TradingMode.BACKTEST == 'backtest'
        assert TradingMode.LIVE == 'live'
