"""Data models for SILICO SDK."""
from typing import Optional, Dict, Any


class TradeRequest:
    """Represents a trade execution request."""

    def __init__(
        self,
        symbol: str,
        side: str,
        amount_usdc: float,
        strategy_tag: Optional[str] = None,
        max_slippage_bps: int = 50,
        natural_language_intent: Optional[str] = None
    ):
        """
        Args:
            symbol: Trading pair (e.g., "SOL/USDC")
            side: "BUY" or "SELL"
            amount_usdc: Amount in USDC
            strategy_tag: Optional strategy identifier
            max_slippage_bps: Maximum slippage in basis points (default: 50)
            natural_language_intent: Optional human-readable intent

        Raises:
            ValueError: If validation fails
        """
        if side not in ("BUY", "SELL"):
            raise ValueError("side must be BUY or SELL")

        if amount_usdc <= 0:
            raise ValueError("amount_usdc must be positive")

        self.symbol = symbol
        self.side = side
        self.amount_usdc = amount_usdc
        self.strategy_tag = strategy_tag
        self.max_slippage_bps = max_slippage_bps
        self.natural_language_intent = natural_language_intent

    def to_dict(self) -> Dict[str, Any]:
        """Convert to API request format."""
        data = {
            "symbol": self.symbol,
            "side": self.side,
            "amount_usdc": self.amount_usdc,
            "max_slippage_bps": self.max_slippage_bps,
        }

        if self.strategy_tag:
            data["strategy_tag"] = self.strategy_tag

        if self.natural_language_intent:
            data["natural_language_intent"] = self.natural_language_intent

        return data


class TradeResponse:
    """Represents a trade execution response."""

    def __init__(
        self,
        success: bool,
        trade_id: Optional[str] = None,
        executed_price: Optional[float] = None,
        error_message: Optional[str] = None,
        raw_response: Optional[Dict] = None
    ):
        """
        Args:
            success: Whether trade succeeded
            trade_id: Trade identifier (if successful)
            executed_price: Execution price (if successful)
            error_message: Error description (if failed)
            raw_response: Full API response
        """
        self.success = success
        self.trade_id = trade_id
        self.executed_price = executed_price
        self.error_message = error_message
        self.raw_response = raw_response or {}

    @classmethod
    def from_api_response(cls, response: Dict[str, Any]) -> "TradeResponse":
        """
        Parse API response into TradeResponse.

        Args:
            response: Raw API response dict

        Returns:
            TradeResponse instance
        """
        success = response.get("success", False)

        if success:
            data = response.get("data", {})
            return cls(
                success=True,
                trade_id=data.get("trade_id"),
                executed_price=data.get("executed_price"),
                raw_response=response
            )
        else:
            return cls(
                success=False,
                error_message=response.get("detail", "Unknown error"),
                raw_response=response
            )


class MarketData:
    """Stores market data for strategy decisions."""

    def __init__(self):
        """Initialize empty market data store."""
        self._prices: Dict[str, float] = {}

    def update_price(self, symbol: str, price: float) -> None:
        """
        Update price for a symbol.

        Args:
            symbol: Trading pair
            price: Current price
        """
        self._prices[symbol] = price

    def get_price(self, symbol: str) -> Optional[float]:
        """
        Get current price for a symbol.

        Args:
            symbol: Trading pair

        Returns:
            Current price or None if not available
        """
        return self._prices.get(symbol)
