"""
Pydantic v2 schemas for the Marketing Home FAQ section CMS (INDL-52).

Write schemas explicitly whitelist the fields a client may set. `id`,
`sort_order`, `deleted_at`, and timestamps are never accepted from the
client — `sort_order` is only ever assigned server-side (create appends at
the end; `reorder` is the only endpoint that reassigns it).

Length/required checks use plain `Optional[str]` fields (no Pydantic
`Field(min_length=...)` constraints) so the router can raise the exact
copy from the PRD's Validation Rules tables (e.g. "Heading is required").
Pydantic v2 prefixes `field_validator` `ValueError`s with "Value error, "
and this codebase's `validation_error_handler` does not strip that prefix
(see `src/core/handlers/errors.py`), so business-rule messages are raised
via `src/core/exceptions.ValidationError` in the router instead — the same
pattern already used by `create_page`/`create_post` in this router.
"""
from __future__ import annotations

from datetime import datetime
from typing import List, Optional
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field


# ---------------------------------------------------------------------------
# Site-admin — responses
# ---------------------------------------------------------------------------

class FaqSettingsResponse(BaseModel):
    id: UUID
    heading: str
    subheading: Optional[str] = None
    intro: Optional[str] = None
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class FaqItemResponse(BaseModel):
    id: UUID
    question: str
    answer: str
    sort_order: int
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class FaqSectionResponse(BaseModel):
    settings: Optional[FaqSettingsResponse] = None
    items: List[FaqItemResponse] = Field(default_factory=list)


# ---------------------------------------------------------------------------
# Site-admin — requests (explicit field whitelisting — A08 / API3)
# ---------------------------------------------------------------------------

class UpdateFaqSettingsRequest(BaseModel):
    """Body for `PATCH /site-admin/faq/settings`. Only heading/subheading/intro
    are bindable — never id/created_at/updated_at."""

    model_config = ConfigDict(extra="forbid")

    heading: Optional[str] = None
    subheading: Optional[str] = None
    intro: Optional[str] = None


class FaqItemWriteRequest(BaseModel):
    """Body for both `POST /site-admin/faq/items` (create — both fields
    required) and `PATCH /site-admin/faq/items/{id}` (partial update — only
    fields present in the payload are validated/applied). Only
    question/answer are bindable — never id/sort_order/deleted_at/timestamps."""

    model_config = ConfigDict(extra="forbid")

    question: Optional[str] = None
    answer: Optional[str] = None


class ReorderFaqItemsRequest(BaseModel):
    """Body for `PATCH /site-admin/faq/items/reorder`. `sort_order` is
    assigned server-side as each id's index in this list."""

    model_config = ConfigDict(extra="forbid")

    order: List[UUID] = Field(min_length=1, max_length=500)


# ---------------------------------------------------------------------------
# Public — responses (deliberately narrower than the admin shape; no id/
# timestamps on settings, no sort_order/timestamps on items — data
# minimization for the anonymous endpoint)
# ---------------------------------------------------------------------------

class PublicFaqSettingsResponse(BaseModel):
    heading: str
    subheading: Optional[str] = None
    intro: Optional[str] = None

    model_config = ConfigDict(from_attributes=True)


class PublicFaqItemResponse(BaseModel):
    id: UUID
    question: str
    answer: str

    model_config = ConfigDict(from_attributes=True)


class PublicFaqSectionResponse(BaseModel):
    settings: Optional[PublicFaqSettingsResponse] = None
    items: List[PublicFaqItemResponse] = Field(default_factory=list)
