"""Template system DTOs — Phase 11.4."""
from __future__ import annotations

from datetime import datetime
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field

from app.models.types import (
    TemplateInstantiationStatus,
    TemplateStatus,
    TemplateVersionStatus,
)
from app.schemas.common import ORMBase

_FORBID = ConfigDict(extra="forbid")


class ExperienceTemplateCreate(BaseModel):
    model_config = _FORBID

    workspace_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    page_type: str = Field(max_length=50)
    status: TemplateStatus = TemplateStatus.DRAFT
    category: str | None = Field(default=None, max_length=100)
    tags: list[str] | None = None
    is_starter_pack: bool = False
    metadata_json: dict | None = None


class ExperienceTemplateUpdate(BaseModel):
    model_config = _FORBID

    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    page_type: str | None = Field(default=None, max_length=50)
    status: TemplateStatus | None = None
    category: str | None = Field(default=None, max_length=100)
    tags: list[str] | None = None
    is_starter_pack: bool | None = None
    metadata_json: dict | None = None
    version: int = Field(ge=1)


class ExperienceTemplateRead(ORMBase):
    id: UUID
    tenant_id: UUID
    workspace_id: UUID
    code: str
    name: str
    description: str | None
    page_type: str
    status: TemplateStatus
    category: str | None
    tags: list | None
    latest_version_number: int
    published_version_id: UUID | None
    is_starter_pack: bool
    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 ExperienceTemplateListResponse(BaseModel):
    items: list[ExperienceTemplateRead]
    total: int
    page: int
    page_size: int


class ExperienceTemplateVersionCreate(BaseModel):
    model_config = _FORBID

    workspace_id: UUID
    template_id: UUID
    blueprint_json: dict | None = None
    changelog: str | None = None
    metadata_json: dict | None = None


class ExperienceTemplateVersionUpdate(BaseModel):
    model_config = _FORBID

    blueprint_json: dict | None = None
    changelog: str | None = None
    metadata_json: dict | None = None
    version: int = Field(ge=1)


class ExperienceTemplateVersionRead(ORMBase):
    id: UUID
    tenant_id: UUID
    workspace_id: UUID
    template_id: UUID
    version_number: int
    status: TemplateVersionStatus
    blueprint_json: 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 ExperienceTemplateVersionListResponse(BaseModel):
    items: list[ExperienceTemplateVersionRead]
    total: int
    page: int
    page_size: int


class TemplateInstantiateRequest(BaseModel):
    model_config = _FORBID

    workspace_id: UUID
    site_id: UUID
    template_id: UUID
    template_version_id: UUID | None = None
    page_code: str = Field(max_length=50)
    page_slug: str = Field(max_length=200)
    page_title: str = Field(max_length=255)
    apply_theme: bool = True
    apply_layout: bool = True
    apply_placements: bool = True
    metadata_json: dict | None = None


class TemplateInstantiationRead(ORMBase):
    id: UUID
    tenant_id: UUID
    workspace_id: UUID
    template_id: UUID
    template_version_id: UUID
    site_id: UUID
    page_id: UUID | None
    status: TemplateInstantiationStatus
    result_json: dict | None
    error_message: str | None
    completed_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 TemplateInstantiationListResponse(BaseModel):
    items: list[TemplateInstantiationRead]
    total: int
    page: int
    page_size: int


class TemplateInstantiateResponse(BaseModel):
    instantiation: TemplateInstantiationRead
    page_id: UUID | None = None
