"""
Data models for Data Manager Client requests and responses.
"""

from datetime import datetime
from decimal import Decimal
from typing import Any

from pydantic import BaseModel, Field


class QueryOptions(BaseModel):
    """Options for querying data."""

    filter: dict[str, Any] | None = Field(None, description="Query filter conditions")
    sort: dict[str, int] | None = Field(None, description="Sort specification")
    limit: int = Field(100, ge=1, le=1000, description="Maximum records to return")
    offset: int = Field(0, ge=0, description="Number of records to skip")
    fields: list[str] | None = Field(None, description="Fields to include in response")


class InsertOptions(BaseModel):
    """Options for inserting data."""

    data: dict[str, Any] | list[dict[str, Any]] = Field(
        ..., description="Data to insert"
    )
    schema: str | None = Field(None, description="Schema name for validation")
    validate: bool = Field(False, description="Enable schema validation")


class UpdateOptions(BaseModel):
    """Options for updating data."""

    filter: dict[str, Any] = Field(
        ..., description="Filter to identify records to update"
    )
    data: dict[str, Any] = Field(..., description="Data to update")
    upsert: bool = Field(False, description="Create record if not found")
    schema: str | None = Field(None, description="Schema name for validation")
    validate: bool = Field(False, description="Enable schema validation")


class DeleteOptions(BaseModel):
    """Options for deleting data."""

    filter: dict[str, Any] = Field(
        ..., description="Filter to identify records to delete"
    )


class CandleData(BaseModel):
    """OHLCV candle data model."""

    timestamp: datetime
    open: Decimal
    high: Decimal
    low: Decimal
    close: Decimal
    volume: Decimal
    quote_volume: Decimal | None = None
    trades_count: int | None = None

    class Config:
        json_encoders = {Decimal: str, datetime: lambda v: v.isoformat()}


class TradeData(BaseModel):
    """Trade execution data model."""

    timestamp: datetime
    trade_id: int
    price: Decimal
    quantity: Decimal
    side: str

    class Config:
        json_encoders = {Decimal: str, datetime: lambda v: v.isoformat()}


class DepthData(BaseModel):
    """Order book depth data model."""

    bids: list[list[str]]  # [[price, quantity], ...]
    asks: list[list[str]]  # [[price, quantity], ...]
    last_update_id: int


class FundingData(BaseModel):
    """Funding rate data model."""

    timestamp: datetime
    funding_rate: Decimal
    mark_price: Decimal | None = None

    class Config:
        json_encoders = {Decimal: str, datetime: lambda v: v.isoformat()}


class PaginationInfo(BaseModel):
    """Pagination metadata."""

    total: int
    limit: int
    offset: int
    page: int
    pages: int
    has_next: bool
    has_previous: bool


class APIResponse(BaseModel):
    """Generic API response wrapper."""

    data: Any
    pagination: PaginationInfo | None = None
    metadata: dict[str, Any] | None = None
    parameters: dict[str, Any] | None = None
