"""
Common API schemas used across all endpoints.

These schemas provide standard request/response structures for:
- Pagination parameters and metadata
- Webhook acknowledgments
- Bulk operations
- Health checks

All endpoints should use these standard schemas rather than
defining their own variations.

Usage:
    from lightwave.schema.pydantic.contracts.api.common import (
        PaginationParams,
        WebhookResponse,
        BulkOperationResponse,
    )

    @router.get("/items/")
    def list_items(request, pagination: PaginationParams = Query(...)):
        items = Item.objects.all()
        return paginate(items, pagination)

    @router.post("/webhooks/stripe/")
    def handle_stripe_webhook(request) -> WebhookResponse:
        return WebhookResponse(status="success", processed_count=1)
"""

from datetime import datetime
from typing import Any, Literal

from pydantic import Field

from lightwave.schema.pydantic.core.base import (
    APIRequestSchema,
    APIResponseSchema,
)


class PaginationParams(APIRequestSchema):
    """
    Standard pagination parameters for list endpoints.

    All list endpoints should accept these query parameters
    for consistent pagination behavior.

    Example:
        GET /api/pages/?page=1&page_size=20&ordering=-created_at

    Fields:
        page: 1-indexed page number (default: 1)
        page_size: Number of items per page (default: 20, max: 100)
        ordering: Field to order by (prefix with - for descending)
    """

    page: int = Field(1, ge=1, description="Page number (1-indexed)")
    page_size: int = Field(20, ge=1, le=100, description="Items per page")
    ordering: str | None = Field(
        None,
        description="Field to order by (prefix with - for descending)",
        examples=["-created_at", "title", "-updated_at"],
    )

    @property
    def offset(self) -> int:
        """Calculate offset from page and page_size."""
        return (self.page - 1) * self.page_size


class WebhookResponse(APIResponseSchema):
    """
    Standard webhook acknowledgment response.

    All webhook handlers should return this schema to provide
    consistent feedback to webhook senders.

    Example response:
        {
            "status": "success",
            "message": "Processed 5 events",
            "processed_count": 5,
            "received_at": "2024-01-15T10:30:00Z"
        }
    """

    id: int | None = None  # Override - webhooks don't have IDs
    created_at: datetime | None = None  # Override
    updated_at: datetime | None = None  # Override

    status: Literal["success", "error", "queued", "partial"] = Field(..., description="Processing status")
    message: str | None = Field(None, description="Optional status message")
    processed_count: int = Field(0, ge=0, description="Number of items processed")
    failed_count: int = Field(0, ge=0, description="Number of items that failed")
    received_at: datetime = Field(default_factory=datetime.utcnow, description="When webhook was received")
    request_id: str | None = Field(None, description="Request ID for tracing")


class BulkOperationResponse(APIResponseSchema):
    """
    Response for bulk create/update/delete operations.

    Provides detailed feedback on batch operations including
    success/failure counts and individual error details.

    Example response:
        {
            "total": 10,
            "succeeded": 8,
            "failed": 2,
            "errors": [
                {"index": 3, "error": "Duplicate key", "item_id": "abc123"},
                {"index": 7, "error": "Validation failed", "item_id": "def456"}
            ]
        }
    """

    id: int | None = None  # Override - bulk ops don't have IDs
    created_at: datetime | None = None  # Override
    updated_at: datetime | None = None  # Override

    total: int = Field(..., ge=0, description="Total items in request")
    succeeded: int = Field(..., ge=0, description="Successfully processed items")
    failed: int = Field(..., ge=0, description="Failed items")
    errors: list[dict[str, Any]] = Field(
        default_factory=list,
        description="Details about failed items",
    )
    created_ids: list[int | str] = Field(
        default_factory=list,
        description="IDs of created items (for bulk create)",
    )


class HealthCheckResponse(APIResponseSchema):
    """
    Standard health check response.

    Used by /health/ and /ready/ endpoints for monitoring.

    Example response:
        {
            "status": "healthy",
            "version": "1.2.3",
            "checks": {
                "database": "ok",
                "cache": "ok",
                "external_api": "degraded"
            }
        }
    """

    id: int | None = None  # Override
    created_at: datetime | None = None  # Override
    updated_at: datetime | None = None  # Override

    status: Literal["healthy", "degraded", "unhealthy"] = Field(..., description="Overall health status")
    version: str = Field(..., description="Application version")
    environment: str = Field(..., description="Environment name")
    timestamp: datetime = Field(default_factory=datetime.utcnow, description="Check timestamp")
    checks: dict[str, Literal["ok", "degraded", "error"]] = Field(
        default_factory=dict,
        description="Individual service check results",
    )
    details: dict[str, Any] = Field(
        default_factory=dict,
        description="Additional details (only in non-production)",
    )


class ActionResponse(APIResponseSchema):
    """
    Response for action endpoints (non-CRUD operations).

    Used for endpoints like /trigger-sync/, /send-email/, etc.
    that perform an action rather than returning a resource.

    Example response:
        {
            "success": true,
            "message": "Email sent successfully",
            "action": "send_email",
            "resource_id": "msg_abc123"
        }
    """

    id: int | None = None  # Override
    created_at: datetime | None = None  # Override
    updated_at: datetime | None = None  # Override

    success: bool = Field(..., description="Whether action succeeded")
    message: str = Field(..., description="Human-readable result message")
    action: str = Field(..., description="Action that was performed")
    resource_id: str | int | None = Field(None, description="ID of affected/created resource")
    metadata: dict[str, Any] = Field(
        default_factory=dict,
        description="Additional action-specific data",
    )
