"""
Pydantic schemas for API request/response models.
"""
from datetime import datetime
from typing import Any

from pydantic import BaseModel, Field


# --- Strategy Schemas ---

class StrategyParam(BaseModel):
    """Single strategy parameter definition."""
    name: str
    value: Any
    param_type: str = Field(description="Type: int, float, bool, list")
    min_value: float | None = None
    max_value: float | None = None
    description: str | None = None


class StrategyInfo(BaseModel):
    """Strategy information with parameters."""
    name: str
    display_name: str
    market_type: str
    default_leverage: int
    default_params: dict[str, Any]
    grid_params: dict[str, Any]


class StrategiesResponse(BaseModel):
    """Response for GET /api/strategies."""
    strategies: list[StrategyInfo]


# --- Symbol/Data Schemas ---

class SymbolInfo(BaseModel):
    """Available symbol information."""
    symbol: str
    exchange: str
    market_type: str
    timeframes: list[str]
    start_date: str | None = None
    end_date: str | None = None
    row_count: int = 0


class DataStatusResponse(BaseModel):
    """Response for GET /api/data/status."""
    symbols: list[SymbolInfo]


# --- Backtest Schemas ---

class BacktestRequest(BaseModel):
    """Request body for POST /api/backtest."""
    strategy: str
    symbol: str
    exchange: str = "okx"
    timeframe: str = "1h"
    market_type: str = "perpetual"
    start_date: str | None = None
    end_date: str | None = None
    init_cash: float = 10000.0
    leverage: int | None = None
    fees: float | None = None
    slippage: float = 0.001
    sl_stop: float | None = None
    tp_stop: float | None = None
    sl_trail: bool = False
    params: dict[str, Any] = Field(default_factory=dict)


class TradeRecord(BaseModel):
    """Single trade record."""
    entry_time: str
    exit_time: str | None = None
    entry_price: float
    exit_price: float | None = None
    size: float
    direction: str
    pnl: float | None = None
    return_pct: float | None = None
    status: str = "closed"


class EquityPoint(BaseModel):
    """Single point on equity curve."""
    timestamp: str
    value: float
    drawdown: float = 0.0


class BacktestMetrics(BaseModel):
    """Backtest performance metrics."""
    total_return: float
    benchmark_return: float = 0.0
    alpha: float = 0.0
    sharpe_ratio: float
    max_drawdown: float
    win_rate: float
    total_trades: int
    profit_factor: float | None = None
    avg_trade_return: float | None = None
    total_fees: float = 0.0
    total_funding: float = 0.0
    liquidation_count: int = 0
    liquidation_loss: float = 0.0
    adjusted_return: float | None = None


class BacktestResult(BaseModel):
    """Complete backtest result."""
    run_id: str
    strategy: str
    symbol: str
    market_type: str
    timeframe: str
    start_date: str
    end_date: str
    leverage: int
    params: dict[str, Any]
    metrics: BacktestMetrics
    equity_curve: list[EquityPoint]
    trades: list[TradeRecord]
    created_at: str


class BacktestSummary(BaseModel):
    """Summary for backtest list view."""
    run_id: str
    strategy: str
    symbol: str
    market_type: str
    timeframe: str
    total_return: float
    sharpe_ratio: float
    max_drawdown: float
    total_trades: int
    created_at: str
    params: dict[str, Any]


class BacktestListResponse(BaseModel):
    """Response for GET /api/backtests."""
    runs: list[BacktestSummary]
    total: int


# --- Comparison Schemas ---

class CompareRequest(BaseModel):
    """Request body for POST /api/compare."""
    run_ids: list[str] = Field(min_length=2, max_length=5)


class CompareResult(BaseModel):
    """Comparison of multiple backtest runs."""
    runs: list[BacktestResult]
    param_diff: dict[str, list[Any]]
