import {Hono} from 'hono'
import {z} from 'zod'

import {type GuardedVars} from '../auth/middleware'
import {geocoder} from '../lib/geocoder'
import {placesLimiter} from '../lib/rate-limit'
import {validate} from '../lib/validate'

const querySchema = z.object({
  lat: z.coerce.number().min(-90).max(90),
  lng: z.coerce.number().min(-180).max(180),
  radius: z.coerce.number().int().positive().max(5000).optional(),
  limit: z.coerce.number().int().positive().max(50).optional(),
})

const reverseSchema = z.object({
  lat: z.coerce.number().min(-90).max(90),
  lng: z.coerce.number().min(-180).max(180),
})

const places = new Hono<{Variables: GuardedVars}>()
  .use('*', placesLimiter)
  .get('/nearby', validate('query', querySchema), async (c) => {
    const {lat, lng, radius, limit} = c.req.valid('query')
    const hits = await geocoder.searchNearby(
      {latitude: lat, longitude: lng},
      {radiusMeters: radius, limit},
    )
    return c.json({places: hits.map((h) => h.ref)})
  })
  .get('/reverse', validate('query', reverseSchema), async (c) => {
    const {lat, lng} = c.req.valid('query')
    const hit = await geocoder.reverse({
      latitude: lat,
      longitude: lng,
    })
    return c.json({place: hit?.ref ?? null})
  })

export default places
