"""Pydantic schemas для location (#948 Part B, ТЗ §8.2).

LocationOut  — ответ API: район + 4 district-level индекса (0..1 или None).
LocationList — ответ list-эндпоинта (total + rows).

Read-only: индексы ВЫЧИСЛЯЮТСЯ воркером (tasks/location_refresh.py), не вводятся
пользователем → Create/Update-схем нет (CRUD отсутствует, только GET-API).

Все индексы Optional[float] ∈ [0,1]: None = нет данных (graceful-on-thin-data —
никогда не фабрикуем 0). centroid не отдаём бинарём — lon/lat достаточно для карты
(NULL если centroid не вычислен).
"""

from __future__ import annotations

from datetime import datetime

from pydantic import BaseModel, Field


class LocationOut(BaseModel):
    """Локация (район) с district-level индексами (#948 Part B, §8.2)."""

    id: int
    district_name: str = Field(..., description="Логический ключ района (8 админ-районов ЕКБ)")
    region: str | None = Field(None, description="Регион (NULL = ЕКБ/Свердл.)")
    lon: float | None = Field(None, description="Долгота центроида района (WGS-84), None если нет")
    lat: float | None = Field(None, description="Широта центроида района (WGS-84), None если нет")
    infra_index: float | None = Field(
        None,
        ge=0.0,
        le=1.0,
        description="Инфра-индекс 0..1 (POI района / POI города); None=нет данных",
    )
    competition_index: float | None = Field(
        None,
        ge=0.0,
        le=1.0,
        description=(
            "Индекс конкуренции 0..1 (доступное/затоваренное конкурирующее предложение "
            "= overstock; выше = больше конкур. давления; ортогонален demand); "
            "None=нет данных"
        ),
    )
    demand_index: float | None = Field(
        None,
        ge=0.0,
        le=1.0,
        description="Индекс спроса 0..1 (saturated velocity); None=нет данных",
    )
    future_supply_index: float | None = Field(
        None,
        ge=0.0,
        le=1.0,
        description="Индекс будущего предложения 0..1; None=нет данных",
    )
    indices_computed_at: datetime | None = Field(
        None, description="Когда индексы последний раз пересчитаны (None до первого refresh)"
    )
    created_at: datetime
    updated_at: datetime


class LocationList(BaseModel):
    """Ответ list-эндпоинта: total + страница строк (зеркало InsightList)."""

    total: int
    rows: list[LocationOut]
