"""Tests for Pydantic schemas."""

import pytest
from decimal import Decimal
from datetime import datetime
from pydantic import ValidationError

from backend.core.schemas import (
    OrderCreate, OrderResponse, OrderSide, OrderType, OrderStatus,
    PositionResponse, PortfolioResponse, PortfolioHistoryResponse
)


class TestOrderCreate:
    """Tests for OrderCreate schema."""
    
    def test_order_create_valid(self):
        """Test valid order creation."""
        order = OrderCreate(
            exchange_id=1,
            symbol="BTC/USD",
            side=OrderSide.BUY,
            order_type=OrderType.MARKET,
            quantity=Decimal("0.1"),
            paper_trading=True
        )
        assert order.exchange_id == 1
        assert order.symbol == "BTC/USD"
        assert order.side == OrderSide.BUY
    
    def test_order_create_with_price(self):
        """Test order creation with price."""
        order = OrderCreate(
            exchange_id=1,
            symbol="BTC/USD",
            side=OrderSide.BUY,
            order_type=OrderType.LIMIT,
            quantity=Decimal("0.1"),
            price=Decimal("50000"),
            paper_trading=True
        )
        assert order.price == Decimal("50000")
    
    def test_order_create_invalid_side(self):
        """Test order creation with invalid side."""
        with pytest.raises(ValidationError):
            OrderCreate(
                exchange_id=1,
                symbol="BTC/USD",
                side="invalid",
                order_type=OrderType.MARKET,
                quantity=Decimal("0.1")
            )


class TestOrderResponse:
    """Tests for OrderResponse schema."""
    
    def test_order_response_from_dict(self):
        """Test creating OrderResponse from dictionary."""
        order_data = {
            "id": 1,
            "exchange_id": 1,
            "strategy_id": None,
            "symbol": "BTC/USD",
            "order_type": OrderType.MARKET,
            "side": OrderSide.BUY,
            "status": OrderStatus.FILLED,
            "quantity": Decimal("0.1"),
            "price": Decimal("50000"),
            "filled_quantity": Decimal("0.1"),
            "average_fill_price": Decimal("50000"),
            "fee": Decimal("5"),
            "paper_trading": True,
            "created_at": datetime.now(),
            "updated_at": datetime.now(),
            "filled_at": datetime.now()
        }
        
        order = OrderResponse(**order_data)
        assert order.id == 1
        assert order.symbol == "BTC/USD"


class TestPositionResponse:
    """Tests for PositionResponse schema."""
    
    def test_position_response_valid(self):
        """Test valid position response."""
        position = PositionResponse(
            symbol="BTC/USD",
            quantity=Decimal("0.1"),
            entry_price=Decimal("50000"),
            current_price=Decimal("51000"),
            unrealized_pnl=Decimal("100"),
            realized_pnl=Decimal("0")
        )
        assert position.symbol == "BTC/USD"
        assert position.unrealized_pnl == Decimal("100")


class TestPortfolioResponse:
    """Tests for PortfolioResponse schema."""
    
    def test_portfolio_response_valid(self):
        """Test valid portfolio response."""
        portfolio = PortfolioResponse(
            positions=[],
            performance={"total_return": 0.1},
            timestamp="2025-01-01T00:00:00"
        )
        assert portfolio.positions == []
        assert portfolio.performance["total_return"] == 0.1


class TestPortfolioHistoryResponse:
    """Tests for PortfolioHistoryResponse schema."""
    
    def test_portfolio_history_response_valid(self):
        """Test valid portfolio history response."""
        history = PortfolioHistoryResponse(
            dates=["2025-01-01", "2025-01-02"],
            values=[1000.0, 1100.0],
            pnl=[0.0, 100.0]
        )
        assert len(history.dates) == 2
        assert len(history.values) == 2

