import { NextResponse } from "next/server"; import { getWeatherRegionForCountryCode } from "@/types/weather-region"; const REVERSE_GEOCODING_URL = "https://nominatim.openstreetmap.org/reverse"; const USER_AGENT = "wtr./1.0 (https://git.zvcloud.net/zv/wtr)"; interface RawReverseLocation { name?: string; display_name?: string; address?: { city?: string; town?: string; village?: string; municipality?: string; county?: string; state?: string; country?: string; country_code?: string; }; } function parseCoordinate(value: string | null, min: number, max: number) { if (!value?.trim()) return null; const coordinate = Number(value); return Number.isFinite(coordinate) && coordinate >= min && coordinate <= max ? Number(coordinate.toFixed(3)) : null; } export async function GET(request: Request) { const { searchParams } = new URL(request.url); const latitude = parseCoordinate(searchParams.get("latitude"), -90, 90); const longitude = parseCoordinate(searchParams.get("longitude"), -180, 180); const language = searchParams.get("language") === "en" ? "en" : "pl"; if (latitude === null || longitude === null) { return NextResponse.json({ error: "Invalid coordinates." }, { status: 400 }); } const params = new URLSearchParams({ format: "jsonv2", lat: String(latitude), lon: String(longitude), zoom: "10", addressdetails: "1", "accept-language": language, }); try { const response = await fetch(`${REVERSE_GEOCODING_URL}?${params}`, { next: { revalidate: 86400 }, headers: { Accept: "application/json", "User-Agent": USER_AGENT }, }); if (!response.ok) return NextResponse.json({ error: "Reverse geocoding is unavailable." }, { status: 502 }); const data = (await response.json()) as RawReverseLocation; const name = data.address?.city ?? data.address?.town ?? data.address?.village ?? data.address?.municipality ?? data.name ?? data.display_name?.split(",")[0]?.trim(); if (!name) return NextResponse.json({ error: "Place name is unavailable." }, { status: 404 }); const countryCode = data.address?.country_code?.toUpperCase() ?? null; return NextResponse.json( { name, province: data.address?.state ?? null, district: data.address?.county ?? null, country: data.address?.country ?? null, countryCode, admin1: data.address?.state ?? null, admin2: data.address?.county ?? null, timezone: null, region: getWeatherRegionForCountryCode(countryCode), }, { headers: { "Cache-Control": "public, s-maxage=86400, stale-while-revalidate=604800" }, }, ); } catch { return NextResponse.json({ error: "Reverse geocoding is unavailable." }, { status: 502 }); } }