"""
Pydantic schemas for platform.site.page.

These schemas validate JSONFields in Django Page model and provide
typed API responses for django-ninja endpoints.

Schema hierarchy:
- PageMetadataSchema: Validates Page.metadata JSONField (SEO, OG tags)
- PageDataSchema: Validates Page.data JSONField (blueprint-specific content)
- PageBodySchema: Validates Page.body JSONField (rich text blocks)
- PublicPageResponseSchema: Full page response for public API (CMS rendering)
- PageListResponseSchema: Lightweight page list item for admin/listing
"""

from __future__ import annotations

from datetime import datetime
from typing import Any, Literal
from uuid import UUID

from pydantic import Field, field_validator

from lightwave.schema.pydantic.core.base import (
    APIResponseSchema,
    JSONFieldSchema,
)
from lightwave.schema.pydantic.core.validators.field_options import (
    FieldOptions,
    get_field_values,
)

from .section import SectionConfig

# =============================================================================
# SST-Derived Literals
# =============================================================================

# Load valid values from SST YAML
PAGE_STATUSES = get_field_values("page_statuses")
LAYOUT_NAMES = ["web", "auth", "app", "app_admin", "error"]  # Fixed 5 layouts

# Type aliases for type hints
PageStatusLiteral = Literal["draft", "published", "archived"]
LayoutNameLiteral = Literal["web", "auth", "app", "app_admin", "error"]


# =============================================================================
# JSONField Schemas (for model validation)
# =============================================================================


class PageMetadataSchema(JSONFieldSchema):
    """
    Schema for Page.metadata JSONField.

    Contains SEO and OpenGraph metadata for the page.
    """

    title: str | None = Field(
        default=None,
        description="Page title for browser tab and SEO",
        max_length=100,
    )
    description: str | None = Field(
        default=None,
        description="Meta description for SEO",
        max_length=300,
    )
    og_image: str | None = Field(
        default=None,
        description="OpenGraph image URL",
    )
    og_title: str | None = Field(
        default=None,
        description="OpenGraph title (defaults to title if not set)",
    )
    og_description: str | None = Field(
        default=None,
        description="OpenGraph description (defaults to description if not set)",
    )
    robots: str | None = Field(
        default=None,
        description="Robots meta tag value (e.g., 'noindex, nofollow')",
    )
    canonical_url: str | None = Field(
        default=None,
        description="Canonical URL for SEO",
    )


class PageDataSchema(JSONFieldSchema):
    """
    Schema for Page.data JSONField.

    This is the extensible content storage validated per blueprint.
    The base schema allows any content; blueprints can define stricter schemas.
    """

    # Base schema allows any extra fields (validated by blueprint)
    pass


class PageBodySchema(JSONFieldSchema):
    """
    Schema for Page.body JSONField.

    Contains rich text content blocks (Tiptap/ProseMirror format).
    """

    # Rich text blocks - structure depends on editor
    pass


class LayoutSchema(JSONFieldSchema):
    """
    Schema for Layout model.

    5 fixed layouts determine authorization level and UI chrome.
    """

    name: LayoutNameLiteral = Field(
        ...,
        description="Layout identifier (web, auth, app, app_admin, error)",
    )
    display_name: str = Field(
        ...,
        description="Human-readable name",
    )
    template_path: str | None = Field(
        default=None,
        description="Path to layout template (if applicable)",
    )
    requires_auth: bool = Field(
        default=False,
        description="Whether layout requires authentication",
    )


class PageSchema(JSONFieldSchema):
    """
    Full schema for Page model.

    Used for internal validation, not API responses.
    """

    id: UUID
    slug: str
    path: str
    title: str
    status: PageStatusLiteral
    layout_id: UUID
    blueprint_id: UUID | None = None
    data: dict[str, Any] = Field(default_factory=dict)
    metadata: PageMetadataSchema = Field(default_factory=PageMetadataSchema)
    body: list[Any] = Field(default_factory=list)
    sections: list[SectionConfig] = Field(default_factory=list)

    @field_validator("status")
    @classmethod
    def validate_status(cls, v: str) -> str:
        """Validate status against SST field options."""
        return FieldOptions.validate("page_statuses", v)


# =============================================================================
# API Response Schemas (for django-ninja)
# =============================================================================


class PublicPageResponseSchema(APIResponseSchema):
    """
    Full page response for public CMS rendering.

    This is the primary schema returned by GET /v1/pages/by-path
    and consumed by TanStack Start for SSR.

    Fields are designed for frontend consumption with TypeScript codegen.
    """

    # Identity
    id: UUID = Field(..., description="Page UUID")
    slug: str = Field(..., description="URL-friendly slug")
    path: str = Field(..., description="Full URL path (e.g., '/pricing')")
    title: str = Field(..., description="Page title")
    page_type: str = Field(default="page", description="Page type identifier")

    # Status
    status: PageStatusLiteral = Field(
        ...,
        description="Publication status (draft, published, archived)",
    )
    requires_auth: bool = Field(
        default=False,
        description="Whether page requires authentication to view",
    )

    # Layout (determines UI chrome and auth level)
    layout_id: UUID | None = Field(
        default=None,
        description="DEPRECATED — Layout model removed. Will be removed next release.",
    )
    layout_name: LayoutNameLiteral = Field(
        ...,
        description="Layout identifier (web, auth, app, app_admin, error)",
    )

    # Blueprint (optional JSON schema validation)
    blueprint_id: UUID | None = Field(
        default=None,
        description="Blueprint UUID (if content is validated)",
    )
    blueprint_name: str | None = Field(
        default=None,
        description="Blueprint name (e.g., 'marketing', 'blog-post')",
    )

    # Content
    data: dict[str, Any] = Field(
        default_factory=dict,
        description="Blueprint-specific page data",
    )
    metadata: PageMetadataSchema = Field(
        default_factory=PageMetadataSchema,
        description="SEO and OpenGraph metadata",
    )
    body: list[Any] = Field(
        default_factory=list,
        description="Rich text body content blocks",
    )
    sections: list[SectionConfig] = Field(
        default_factory=list,
        description="React section configurations for rendering",
    )

    # Timestamps
    created_at: datetime = Field(..., description="Creation timestamp")
    updated_at: datetime = Field(..., description="Last update timestamp")


class PageListResponseSchema(APIResponseSchema):
    """
    Lightweight page response for listing/admin views.

    Excludes heavy content fields (data, body, sections) for performance.
    """

    id: UUID
    slug: str
    path: str
    title: str
    page_type: str = "page"
    status: PageStatusLiteral
    layout_name: LayoutNameLiteral
    created_at: datetime
    updated_at: datetime


class PageCreateRequestSchema(JSONFieldSchema):
    """
    Request schema for creating a new page.
    """

    path: str = Field(..., description="URL path (must be unique per site)")
    title: str = Field(..., description="Page title")
    layout_id: UUID = Field(..., description="Layout to use")
    blueprint_id: UUID | None = Field(default=None, description="Optional blueprint")
    status: PageStatusLiteral = Field(default="draft", description="Initial status")
    data: dict[str, Any] = Field(default_factory=dict)
    metadata: PageMetadataSchema = Field(default_factory=PageMetadataSchema)
    sections: list[SectionConfig] = Field(default_factory=list)


class PageUpdateRequestSchema(JSONFieldSchema):
    """
    Request schema for updating a page.

    All fields are optional for PATCH operations.
    """

    title: str | None = None
    status: PageStatusLiteral | None = None
    layout_id: UUID | None = None
    blueprint_id: UUID | None = None
    data: dict[str, Any] | None = None
    metadata: PageMetadataSchema | None = None
    sections: list[SectionConfig] | None = None


# =============================================================================
# Exports
# =============================================================================

__all__ = [
    # Literals
    "PAGE_STATUSES",
    "LAYOUT_NAMES",
    "PageStatusLiteral",
    "LayoutNameLiteral",
    # JSONField schemas
    "PageMetadataSchema",
    "PageDataSchema",
    "PageBodySchema",
    "LayoutSchema",
    "PageSchema",
    # API schemas
    "PublicPageResponseSchema",
    "PageListResponseSchema",
    "PageCreateRequestSchema",
    "PageUpdateRequestSchema",
    # Re-export section schema
    "SectionConfig",
]
