"""
Request models shared across L1 and L2 servers.
"""

from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field

from ..constants import DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE


class PaginationParams(BaseModel):
    """Common pagination parameters."""
    page: int = Field(default=1, ge=1, description="Page number (1-indexed)")
    limit: int = Field(
        default=DEFAULT_PAGE_SIZE,
        ge=1,
        le=MAX_PAGE_SIZE,
        description="Items per page"
    )

    @property
    def offset(self) -> int:
        """Calculate offset for database queries."""
        return (self.page - 1) * self.limit


class PublishRequest(BaseModel):
    """Request to publish content to L2/storage."""
    name: str = Field(..., min_length=1, max_length=255)
    description: Optional[str] = Field(default=None, max_length=2000)
    tags: List[str] = Field(default_factory=list)
    storage_id: Optional[str] = Field(default=None, description="Target storage provider")


class MetadataUpdateRequest(BaseModel):
    """Request to update content metadata."""
    name: Optional[str] = Field(default=None, max_length=255)
    description: Optional[str] = Field(default=None, max_length=2000)
    tags: Optional[List[str]] = Field(default=None)
    metadata: Optional[Dict[str, Any]] = Field(default=None)


class StorageConfigRequest(BaseModel):
    """Request to configure a storage provider."""
    provider_type: str = Field(..., description="Provider type (pinata, web3storage, local, etc.)")
    name: str = Field(..., min_length=1, max_length=100)
    api_key: Optional[str] = Field(default=None)
    api_secret: Optional[str] = Field(default=None)
    endpoint: Optional[str] = Field(default=None)
    config: Optional[Dict[str, Any]] = Field(default_factory=dict)
    is_default: bool = Field(default=False)


class RecipeRunRequest(BaseModel):
    """Request to run a recipe."""
    recipe_id: str = Field(..., description="Recipe content hash or ID")
    inputs: Dict[str, str] = Field(..., description="Map of input name to content hash")
    features: List[str] = Field(
        default=["beats", "energy"],
        description="Analysis features to extract"
    )


class PlanRequest(BaseModel):
    """Request to generate an execution plan."""
    recipe_yaml: str = Field(..., description="Recipe YAML content")
    input_hashes: Dict[str, str] = Field(..., description="Map of input name to content hash")
    features: List[str] = Field(default=["beats", "energy"])


class ExecutePlanRequest(BaseModel):
    """Request to execute a generated plan."""
    plan_json: str = Field(..., description="JSON-serialized execution plan")
    run_id: Optional[str] = Field(default=None, description="Optional run ID for tracking")
