"""Read-only API для location (#948 Part B, ТЗ §8.2).

GET /api/v1/locations                  → LocationList   (все локации с индексами)
GET /api/v1/locations/{district_name}  → LocationOut    (одна; 404 если нет)

Read-only: индексы инфра/конкуренция/спрос/будущее-предложение ВЫЧИСЛЯЮТСЯ воркером
(tasks/location_refresh.py через services/site_finder/locations.py), НЕ вводятся
пользователем — поэтому CRUD нет (никаких POST/PUT/DELETE).

Access control: backend rbac_guard (app/main.py) хард-блокирует ТОЛЬКО /api/v1/admin/*
(admin-only). На /api/v1/locations pilot отсекается FRONTEND-овым RouteGuard
(allowed_paths из /me) + Caddy, НЕ бэкендом (is_path_allowed() из backend-кода тут НЕ
вызывается). До эндпоинта доходят analyst+admin (та же модель, что insights/
custom-pois — НЕ backend pilot-gating).

Хэндлеры sync `def` (зеркало insights.py/custom_pois.py): сервис ходит в БД через
sync SQLAlchemy Session → FastAPI исполняет их в threadpool, event loop не блокируется
(async def + sync db.execute было бы хуже — заблокировало бы loop).

district_name в path: FastAPI принимает Cyrillic через URL-encoding прозрачно (имена
8 админ-районов ЕКБ: «Кировский», «Ленинский», …).
"""

from __future__ import annotations

import logging
from typing import Annotated, Any

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session

from app.core.db import get_db
from app.schemas.location import LocationList, LocationOut
from app.services.site_finder.locations import get_location, list_locations

logger = logging.getLogger(__name__)

router = APIRouter()


@router.get("", response_model=LocationList)
def list_locations_endpoint(
    db: Annotated[Session, Depends(get_db)],
) -> Any:
    """Все локации (районы) с district-level индексами."""
    return list_locations(db)


@router.get("/{district_name}", response_model=LocationOut)
def get_location_endpoint(
    district_name: str,
    db: Annotated[Session, Depends(get_db)],
) -> Any:
    """Вернуть одну локацию по district_name. 404 если не найдена."""
    location = get_location(db, district_name)
    if location is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Location not found")
    return location
