"""
Public cemetery map schemas (INDL-56).

These are strict, allowlist-only response models for the unauthenticated
`/api/public/map` surface. Every model uses ``extra="forbid"`` so a field that
is not explicitly declared here can never be serialized to a public visitor —
the last line of defence against leaking staff-only data (notes, reserved_by,
record_id, full DOB/DOD, etc.). The service constructs these models explicitly
(an allowlist by construction); ``extra="forbid"`` makes any accidental extra
key fail closed rather than leak.
"""
from typing import Optional

from pydantic import BaseModel, ConfigDict


class PublicMapStatus(BaseModel):
    """A single entry from the tenant status catalog (drives the legend)."""

    model_config = ConfigDict(extra="forbid")

    id: str
    name: str
    color_hex: str
    status_key: Optional[str] = None
    sort_order: int = 0


class PublicMapSectionProperties(BaseModel):
    model_config = ConfigDict(extra="forbid")

    id: str
    code: Optional[str] = None
    name: Optional[str] = None
    display_color: Optional[str] = None
    total: int = 0
    available: int = 0
    occupancy_pct: float = 0.0


class PublicMapPlotProperties(BaseModel):
    """Public, data-minimized plot marker properties.

    Deliberately omits ``notes``, ``reserved_by``, ``reserved_at``,
    ``record_id`` and full dates. Burial identity fields
    (``occupant_name``/``year_of_birth``/``year_of_death``) are populated ONLY
    when the linked record is public; ``memorial_slug`` only when the memorial
    is published.
    """

    model_config = ConfigDict(extra="forbid")

    id: str
    plot_ref: str
    label: str
    status: str
    color: str
    section_code: Optional[str] = None
    plot_type_name: Optional[str] = None
    price: Optional[float] = None
    public_description: Optional[str] = None
    latitude: Optional[float] = None
    longitude: Optional[float] = None
    has_memorial: bool = False
    memorial_slug: Optional[str] = None
    occupant_name: Optional[str] = None
    year_of_birth: Optional[int] = None
    year_of_death: Optional[int] = None


class PublicPlotDetailResponse(BaseModel):
    """Single-plot public detail (lazy-loaded on marker selection)."""

    model_config = ConfigDict(extra="forbid")

    plot_ref: str
    label: str
    status: str
    color: str
    section_code: Optional[str] = None
    section_name: Optional[str] = None
    plot_type_name: Optional[str] = None
    price: Optional[float] = None
    public_description: Optional[str] = None
    latitude: Optional[float] = None
    longitude: Optional[float] = None
    has_memorial: bool = False
    memorial_slug: Optional[str] = None
    occupant_name: Optional[str] = None
    year_of_birth: Optional[int] = None
    year_of_death: Optional[int] = None
    memorial_excerpt: Optional[str] = None
    memorial_photo_url: Optional[str] = None
    walking_minutes: Optional[int] = None
    distance_m: Optional[float] = None
