<?php
// addLocationToAdresses.php
// Alle Fehler anzeigen
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Zeitlimit erhöhen
ini_set('max_execution_time', 300); // 5 Minuten

// Speicherlimit erhöhen
ini_set('memory_limit', '256M');

// Funktion zum Loggen mit Zeitstempel
function log_message($message) {
    echo date('[Y-m-d H:i:s] ') . $message . "<br>";
    // Flush output buffer
    if (ob_get_level() > 0) {
        ob_flush();
        flush();
    }
}

try {
    // Verbindungsaufbau zur Datenbank
    $config = include('db-connection.php');
    $host = $config['host'];
    $port = $config['port'];
    $dbname = $config['dbname'];
    $user = $config['user'];
    $password = $config['password'];

    log_message("Stelle Verbindung zur Datenbank her...");
    
    // Verbindungsaufbau zur Datenbank
    $conn = pg_connect("host=$host port=$port dbname=$dbname user=$user password=$password")
    or die('Verbindungsaufbau fehlgeschlagen: ' . pg_last_error());

    // SQL-Abfrage, um die Adressen aus der Tabelle wikidata zu holen
    $query = "
        SELECT id, street, hnr, district, city
        FROM wikidata 
        WHERE new_in_koorddb = 'true'
    ";
    
    log_message("Führe Abfrage aus...");
    $result = pg_query($conn, $query);

    if (!$result) {
        throw new Exception("Datenbankabfrage fehlgeschlagen: " . pg_last_error($conn));
    }

    // Anzahl der gefundenen Adressen ausgeben
    $total_count = pg_num_rows($result);
    log_message("Anzahl der gefundenen Adressen: $total_count");

    if ($total_count > 0) {
        $success_count = 0;
        $error_count = 0;
        $skipped_count = 0;
        
        $count = 0;
        // Durchlaufe alle Adressen
        while ($row = pg_fetch_assoc($result)) {
            $count++;
            $id = $row['id'];
            
            try {
                // Adresse zusammenstellen
                $city = isset($row['city']) && !empty($row['city']) ? $row['city'] : 'Berlin';
                $address = $row['street'] . ' ' . $row['hnr'] . ', ' . $row['district'] . ', ' . $city;
                log_message("[$count/$total_count] Verarbeite Adresse (ID: $id): $address");

                // Geocoding-API aufrufen
                $search_query = urlencode($address);
                $url = "https://geocode.search.hereapi.com/v1/geocode?q={$search_query}&apiKey=okEOI_7ww-l-Eop_6L8XY8YpWT2G-3bBNcO7ZoVT_P8";
                
                $ch = curl_init($url);  
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 30 Sekunden Timeout
                $response = curl_exec($ch);

                if (curl_errno($ch)) {
                    throw new Exception("cURL-Anfrage fehlgeschlagen: " . curl_error($ch));
                }
                
                $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                if ($http_code != 200) {
                    throw new Exception("API-Anfrage fehlgeschlagen mit HTTP-Code: $http_code, Antwort: $response");
                }
                
                curl_close($ch);

                // Antwort der API überprüfen
                $data = json_decode($response, true);
                if (json_last_error() !== JSON_ERROR_NONE) {
                    throw new Exception("JSON-Decodierung fehlgeschlagen: " . json_last_error_msg());
                }

                if (!isset($data['items']) || count($data['items']) == 0) {
                    throw new Exception("Keine Ergebnisse von der Geocoding-API erhalten");
                }

                if (!isset($data['items'][0]['position']['lat']) || !isset($data['items'][0]['position']['lng'])) {
                    throw new Exception("Keine Koordinaten in API-Antwort gefunden");
                }

                $lat = $data['items'][0]['position']['lat'];
                $lon = $data['items'][0]['position']['lng'];
                $point = "POINT($lon $lat)";

                log_message("Koordinaten gefunden: LAT=$lat, LON=$lon");

                // SQL-Abfrage zum Aktualisieren der Koordinaten - nur über ID
                $update_query = "
                    UPDATE wikidata 
                    SET lat = $1, lon = $2, geom = ST_SetSRID(ST_GeomFromText($3), 4326)
                    WHERE id = $4
                ";

                // Führe das Update direkt aus (ohne erneute Vorbereitung)
                $update_result = pg_query_params($conn, $update_query, array($lat, $lon, $point, $id));

                if (!$update_result) {
                    throw new Exception("Update fehlgeschlagen: " . pg_last_error($conn));
                }

                $affected_rows = pg_affected_rows($update_result);
                if ($affected_rows > 0) {
                    log_message("ERFOLG: Daten für ID $id aktualisiert ($affected_rows Zeilen betroffen)");
                    $success_count++;
                } else {
                    log_message("WARNUNG: Keine Zeilen aktualisiert für ID $id");
                    $skipped_count++;
                }
            } catch (Exception $e) {
                log_message("FEHLER bei ID $id: " . $e->getMessage());
                $error_count++;
            }
            
            // Kurze Pause zwischen API-Anfragen
            usleep(500000); // 500ms Pause
        }
        
        // Zusammenfassung ausgeben
        log_message("------ ZUSAMMENFASSUNG ------");
        log_message("Gesamt: $total_count Adressen gefunden");
        log_message("Erfolgreich aktualisiert: $success_count");
        log_message("Fehler: $error_count");
        log_message("Übersprungen: $skipped_count");
    } else {
        log_message("Keine Adressen gefunden, die aktualisiert werden müssen!");
    }

    // Datenbankverbindung schließen
    pg_close($conn);
    log_message("Datenbankverbindung geschlossen");
    
} catch (Exception $e) {
    log_message("KRITISCHER FEHLER: " . $e->getMessage());
    if (isset($conn) && $conn) {
        pg_close($conn);
        log_message("Datenbankverbindung geschlossen nach Fehler");
    }
}

log_message("Skript beendet");
?>