"""Component library DTOs — Phase 11.2."""
from __future__ import annotations

from datetime import datetime
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field

from app.models.types import ComponentKind, ComponentStatus, ComponentVersionStatus
from app.schemas.common import ORMBase

_FORBID = ConfigDict(extra="forbid")


class ExperienceComponentCreate(BaseModel):
    model_config = _FORBID

    workspace_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    kind: ComponentKind = ComponentKind.CONTENT
    status: ComponentStatus = ComponentStatus.DRAFT
    category: str | None = Field(default=None, max_length=100)
    tags: list[str] | None = None
    metadata_json: dict | None = None


class ExperienceComponentUpdate(BaseModel):
    model_config = _FORBID

    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    kind: ComponentKind | None = None
    status: ComponentStatus | None = None
    category: str | None = Field(default=None, max_length=100)
    tags: list[str] | None = None
    metadata_json: dict | None = None
    version: int = Field(ge=1)


class ExperienceComponentRead(ORMBase):
    id: UUID
    tenant_id: UUID
    workspace_id: UUID
    code: str
    name: str
    description: str | None
    kind: ComponentKind
    status: ComponentStatus
    category: str | None
    tags: list | None
    latest_version_number: int
    published_version_id: UUID | None
    is_system: bool
    metadata_json: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class ExperienceComponentVersionCreate(BaseModel):
    model_config = _FORBID

    workspace_id: UUID
    component_id: UUID
    definition_schema: dict | None = None
    props_defaults: dict | None = None
    render_hint: dict | None = None
    changelog: str | None = None
    metadata_json: dict | None = None


class ExperienceComponentVersionUpdate(BaseModel):
    model_config = _FORBID

    definition_schema: dict | None = None
    props_defaults: dict | None = None
    render_hint: dict | None = None
    changelog: str | None = None
    metadata_json: dict | None = None
    version: int = Field(ge=1)


class ExperienceComponentVersionRead(ORMBase):
    id: UUID
    tenant_id: UUID
    workspace_id: UUID
    component_id: UUID
    version_number: int
    status: ComponentVersionStatus
    definition_schema: dict | None
    props_defaults: dict | None
    render_hint: dict | None
    changelog: str | None
    is_immutable: bool
    published_at: datetime | None
    retired_at: datetime | None
    metadata_json: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class PageComponentPlacementCreate(BaseModel):
    model_config = _FORBID

    workspace_id: UUID
    site_id: UUID
    page_id: UUID
    component_id: UUID
    component_version_id: UUID
    slot_key: str = Field(max_length=100)
    sort_order: int = Field(default=0, ge=0)
    props_override: dict | None = None
    is_visible: bool = True
    metadata_json: dict | None = None


class PageComponentPlacementUpdate(BaseModel):
    model_config = _FORBID

    component_version_id: UUID | None = None
    slot_key: str | None = Field(default=None, max_length=100)
    sort_order: int | None = Field(default=None, ge=0)
    props_override: dict | None = None
    is_visible: bool | None = None
    metadata_json: dict | None = None
    version: int = Field(ge=1)


class PageComponentPlacementRead(ORMBase):
    id: UUID
    tenant_id: UUID
    workspace_id: UUID
    site_id: UUID
    page_id: UUID
    component_id: UUID
    component_version_id: UUID
    slot_key: str
    sort_order: int
    props_override: dict | None
    is_visible: bool
    metadata_json: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class ExperienceComponentListResponse(BaseModel):
    items: list[ExperienceComponentRead]
    total: int
    page: int
    page_size: int


class ExperienceComponentVersionListResponse(BaseModel):
    items: list[ExperienceComponentVersionRead]
    total: int
    page: int
    page_size: int


class PageComponentPlacementListResponse(BaseModel):
    items: list[PageComponentPlacementRead]
    total: int
    page: int
    page_size: int
