from decimal import Decimal
from typing import Literal, Optional

from pydantic import BaseModel, ConfigDict, Field


class MapConfigRequest(BaseModel):
    """PATCH /accounts/me/map-config body. Explicit allowlist + extra='forbid'
    prevents mass-assignment of protected account fields (security API3/S-06)."""

    model_config = ConfigDict(extra="forbid")

    map_mode: Optional[Literal["geo", "image"]] = None
    boundary: Optional[dict] = None  # GeoJSON Polygon; explicit null clears it
    # Optional last-searched-location cache (AC-19).
    search_lat: Optional[float] = Field(default=None, ge=-90, le=90)
    search_lng: Optional[float] = Field(default=None, ge=-180, le=180)
    search_address: Optional[str] = Field(default=None, max_length=500)


class CentroidOut(BaseModel):
    lat: float
    lng: float


class CemeteryMapConfigResponse(BaseModel):
    map_mode: str
    boundary: Optional[dict] = None
    centroid: Optional[CentroidOut] = None
    total_area_m2: Optional[Decimal] = None
    map_image_url: Optional[str] = None
    geocoding_enabled: bool = False
    # Last-searched-location cache (AC-19)
    map_search_lat: Optional[Decimal] = None
    map_search_lng: Optional[Decimal] = None
    map_search_address: Optional[str] = None


class GeocodeResponse(BaseModel):
    lat: float
    lng: float
    formatted_address: str
