<?php

final class GeoService
{
    public static function geocode(PDO $db, string $query): ?array
    {
        $q = trim(preg_replace('~\s+~', ' ', $query));
        if ($q === '') {
            return null;
        }

        // Cache DB
        $st = $db->prepare('SELECT lat,lng FROM geocode_cache WHERE q=:q LIMIT 1');
        $st->execute([':q' => $q]);
        $row = $st->fetch(PDO::FETCH_ASSOC);
        if ($row && $row['lat'] !== null && $row['lng'] !== null) {
            return ['lat' => (float) $row['lat'], 'lng' => (float) $row['lng']];
        }

        // Nominatim (OpenStreetMap) — respecter l'usage: User-Agent + requêtes raisonnables
        $url = 'https://nominatim.openstreetmap.org/search?format=jsonv2&limit=1&q=' . rawurlencode($q);

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_TIMEOUT => 10,
            CURLOPT_CONNECTTIMEOUT => 5,
            CURLOPT_HTTPHEADER => ['Accept: application/json', 'User-Agent: Globinours/1.0 (contact: local-refuge)'],
        ]);

        $body = curl_exec($ch);
        if ($body === false) {
            curl_close($ch);
            return null;
        }
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($code < 200 || $code >= 300) {
            return null;
        }

        $json = json_decode($body, true);
        if (!is_array($json) || empty($json[0]['lat']) || empty($json[0]['lon'])) {
            // Stocker "vide" en cache évite de spammer
            $db->prepare(
                "INSERT OR REPLACE INTO geocode_cache(q,lat,lng,raw_json,fetched_at) VALUES(:q,NULL,NULL,:raw,datetime('now'))",
            )->execute([':q' => $q, ':raw' => $body]);
            return null;
        }

        $lat = (float) $json[0]['lat'];
        $lng = (float) $json[0]['lon'];

        $db->prepare(
            "INSERT OR REPLACE INTO geocode_cache(q,lat,lng,raw_json,fetched_at) VALUES(:q,:lat,:lng,:raw,datetime('now'))",
        )->execute([':q' => $q, ':lat' => $lat, ':lng' => $lng, ':raw' => $body]);

        return ['lat' => $lat, 'lng' => $lng];
    }
}
