"""Búsqueda de músicos disponibles cerca de un punto.

Usa PostGIS:
  - ST_DWithin(geography, geography, metros)  → filtra por radio real sobre la esfera.
  - ST_Distance(geography, geography)         → distancia en metros para ordenar por cercanía.

Así el cliente ve primero lo más cercano y puede ampliar el radio para abarcar otras ciudades
o incluso todo el país.
"""
from fastapi import APIRouter, Depends, Query
from geoalchemy2.functions import ST_Distance, ST_DWithin
from sqlalchemy import select
from sqlalchemy.orm import Session

from app import models
from app.core.database import get_db
from app.schemas.musician import MusicianSearchResult
from app.services.geo import point, to_out

router = APIRouter(tags=["search"])


@router.get("/search", response_model=list[MusicianSearchResult])
def search_musicians(
    lat: float = Query(..., ge=-90, le=90),
    lng: float = Query(..., ge=-180, le=180),
    radius_km: float = Query(25, gt=0, le=5000, description="Radio de búsqueda en km"),
    service_type: str | None = Query(None, description="Slug del catálogo, p.ej. 'mariachi'"),
    country: str | None = Query(None, description="ISO-2, p.ej. 'VE'"),
    available_only: bool = Query(True, description="Solo músicos disponibles ahora"),
    limit: int = Query(50, ge=1, le=200),
    db: Session = Depends(get_db),
):
    origin = point(lat, lng)
    radius_m = radius_km * 1000
    distance = ST_Distance(models.MusicianProfile.location, origin).label("distance_m")

    stmt = (
        select(models.MusicianProfile, distance)
        .where(models.MusicianProfile.location.isnot(None))
        .where(ST_DWithin(models.MusicianProfile.location, origin, radius_m))
        .order_by(distance)
        .limit(limit)
    )

    if available_only:
        stmt = stmt.where(models.MusicianProfile.is_available.is_(True))
    if service_type:
        # el array service_types del músico contiene el slug buscado
        stmt = stmt.where(models.MusicianProfile.service_types.contains([service_type]))
    if country:
        stmt = stmt.where(models.MusicianProfile.country == country.upper())

    rows = db.execute(stmt).all()
    return [to_out(profile, round(dist_m / 1000, 2)) for profile, dist_m in rows]
