"""CRUD API для user_custom_pois (#254).

POST   /api/v1/custom-pois                 → 201 CustomPoiOut
GET    /api/v1/custom-pois                 → list[CustomPoiOut]
PATCH  /api/v1/custom-pois/{id}            → CustomPoiOut
DELETE /api/v1/custom-pois/{id}            → 204

Auth: anonymous user_id из header X-Session-Id (workaround до #67 NextAuth).
Если заголовок отсутствует — генерируем UUID и возвращаем в X-Session-Id response header.
Frontend сохраняет в localStorage.
"""

from __future__ import annotations

import logging
import uuid
from typing import Annotated, Any

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

from app.core.db import get_db
from app.schemas.custom_poi import CustomPoiCreate, CustomPoiOut, CustomPoiUpdate
from app.services.site_finder.custom_pois import (
    create_custom_poi,
    delete_custom_poi,
    list_custom_pois,
    update_custom_poi,
)

logger = logging.getLogger(__name__)

router = APIRouter()


def _resolve_session_id(
    x_session_id: str | None,
    response: Response,
) -> str:
    """Вернуть user_id из X-Session-Id header или сгенерировать UUID.

    При генерации устанавливаем X-Session-Id в response header чтобы
    frontend мог сохранить значение в localStorage.
    """
    if x_session_id and x_session_id.strip():
        return x_session_id.strip()
    generated = str(uuid.uuid4())
    response.headers["X-Session-Id"] = generated
    logger.debug("generated session_id=%s (no X-Session-Id header)", generated)
    return generated


@router.post("", response_model=CustomPoiOut, status_code=status.HTTP_201_CREATED)
def create_poi(
    payload: CustomPoiCreate,
    db: Annotated[Session, Depends(get_db)],
    response: Response,
    x_session_id: Annotated[str | None, Header()] = None,
) -> Any:
    """Создать кастомную POI точку.

    Возвращает 201 с созданным объектом. X-Session-Id response header содержит
    актуальный session_id (пригодится frontend для localStorage).
    """
    user_id = _resolve_session_id(x_session_id, response)
    poi = create_custom_poi(db, user_id, payload)
    # Echo back session_id чтобы frontend всегда имел его в response
    response.headers["X-Session-Id"] = user_id
    return poi


@router.get("", response_model=list[CustomPoiOut])
def list_pois(
    db: Annotated[Session, Depends(get_db)],
    response: Response,
    x_session_id: Annotated[str | None, Header()] = None,
    parcel_cad: Annotated[
        str | None,
        Query(description="Фильтр по кадастровому номеру участка (возвращает global + parcel POI)"),
    ] = None,
) -> Any:
    """Список кастомных POI пользователя.

    Если parcel_cad задан — возвращает global (parcel_cad IS NULL) + parcel-specific POI.
    """
    user_id = _resolve_session_id(x_session_id, response)
    response.headers["X-Session-Id"] = user_id
    return list_custom_pois(db, user_id, parcel_cad)


@router.patch("/{poi_id}", response_model=CustomPoiOut)
def patch_poi(
    poi_id: int,
    payload: CustomPoiUpdate,
    db: Annotated[Session, Depends(get_db)],
    response: Response,
    x_session_id: Annotated[str | None, Header()] = None,
) -> Any:
    """Обновить поля кастомной POI (PATCH-style). 404 если не найдена."""
    user_id = _resolve_session_id(x_session_id, response)
    response.headers["X-Session-Id"] = user_id
    poi = update_custom_poi(db, poi_id, user_id, payload)
    if poi is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Custom POI not found")
    return poi


@router.delete("/{poi_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_poi(
    poi_id: int,
    db: Annotated[Session, Depends(get_db)],
    response: Response,
    x_session_id: Annotated[str | None, Header()] = None,
) -> None:
    """Удалить кастомную POI. 404 если не найдена."""
    user_id = _resolve_session_id(x_session_id, response)
    deleted = delete_custom_poi(db, poi_id, user_id)
    if not deleted:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Custom POI not found")
