"""Grid Bot for BLOT SDK."""

from dataclasses import dataclass, field
from typing import Optional, Literal

from blot.bots.base import BaseBot


@dataclass
class GridBot(BaseBot):
    """Grid Bot - Profit from sideways markets.
    
    The Grid Bot places a series of buy and sell orders at predetermined
    price intervals, creating a "grid" of orders that profits from
    price fluctuations.
    
    Example:
        ```python
        from blot import GridBot
        
        bot = GridBot(
            base_token="SOL",
            quote_token="USDC",
            lower_price=120,
            upper_price=180,
            grid_count=20,
            total_investment=100,  # USDC
        )
        ```
    
    Attributes:
        base_token: Token to trade (e.g., "SOL").
        quote_token: Quote currency (e.g., "USDC").
        lower_price: Bottom of the grid range.
        upper_price: Top of the grid range.
        grid_count: Number of grid lines.
        total_investment: Total investment in quote currency.
        mode: Grid type ('arithmetic' or 'geometric').
        ai_assisted: Let AI adjust grid range automatically.
    """
    
    # Trading pair
    base_token: str = "SOL"
    quote_token: str = "USDC"
    
    # Grid settings
    lower_price: float = 100.0
    upper_price: float = 200.0
    grid_count: int = 20
    
    # Investment
    total_investment: float = 100.0  # Quote currency
    
    # Grid type
    mode: Literal["arithmetic", "geometric"] = "arithmetic"
    
    # AI assistance
    ai_assisted: bool = False
    
    # Execution
    slippage: float = 0.5  # percent
    
    def validate(self) -> bool:
        """Validate bot configuration."""
        if self.lower_price >= self.upper_price:
            raise ValueError("lower_price must be less than upper_price")
        if self.grid_count < 2:
            raise ValueError("grid_count must be at least 2")
        if self.total_investment <= 0:
            raise ValueError("total_investment must be positive")
        if self.mode not in ["arithmetic", "geometric"]:
            raise ValueError("mode must be 'arithmetic' or 'geometric'")
        if self.slippage < 0 or self.slippage > 100:
            raise ValueError("slippage must be between 0 and 100")
        return True
    
    @property
    def grid_spacing(self) -> float:
        """Calculate grid spacing based on mode."""
        if self.mode == "arithmetic":
            return (self.upper_price - self.lower_price) / (self.grid_count - 1)
        else:
            # Geometric: equal percentage between levels
            return (self.upper_price / self.lower_price) ** (1 / (self.grid_count - 1))
    
    @property
    def grid_levels(self) -> list[float]:
        """Generate all grid price levels."""
        levels = []
        if self.mode == "arithmetic":
            spacing = self.grid_spacing
            for i in range(self.grid_count):
                levels.append(self.lower_price + i * spacing)
        else:
            ratio = self.grid_spacing
            price = self.lower_price
            for _ in range(self.grid_count):
                levels.append(price)
                price *= ratio
        return levels

