<?php
// fetch_poi_by_address.php
// Sucht Stolpersteine anhand von Adress-Ähnlichkeit (Straße und Hausnummer).
// Aggregiert Treffer an derselben Adresse.
// Extrahiert Geometrie-Koordinaten aus der PostGIS-Spalte geom_geolocation.
// Erwartet im GET- oder POST-Body: { "street": "varziner", "houseNr": "9" }

// PHP-Fehlermeldungen direkt anzeigen, nur für Debug-Zwecke
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// === Logging und Konfiguration laden ===
$debugLogFile = __DIR__ . '/fetch_poi_by_address_debug.log';

require_once __DIR__ . '/logging_functions.php'; 
require_once __DIR__ . '/fetch_poi_select.php';

internal_debug_log("--- " . basename(__FILE__) . " START (RAW QUERY_STRING logging) ---", $debugLogFile);
header('Content-Type: application/json');

// --- Gesamten Skriptinhalt in einen Try-Catch-Block einschließen ---
try {
    // --- Konfiguration laden ---
    $config = require_once 'config.php';
    
    // Variablen initialisieren
    $targetTable = ''; 
    $tableSuffix = '';

    // ------------------------------------------------------------------
    // === DATENQUELLEN-AUSWAHL MIT SICHERER WHITELISTING (p-Parameter) ===
    // ------------------------------------------------------------------

    $pParam = $_GET['p'] ?? 'default';

    switch ($pParam) {
        case 'default':
            $tableSuffix = '';
            break;
        case 'test':
            $tableSuffix = '_test';
            break;
        default:
            // Falls ein ungültiger Wert übergeben wird, Standard verwenden.
            $tableSuffix = '';
            $pParam = 'default';
            break;
    }

    // Berechnet den finalen Tabellennamen
    $targetTable = $config['tablePrefix'] . $tableSuffix;

    internal_debug_log("Datenquelle: p=$pParam. Wird Tabelle '$targetTable' verwenden.", $debugLogFile);

    // Datenbankverbindungskonfiguration laden
    $dbConfig = require_once 'db-connection.php';
    internal_debug_log("DB config loaded.", $debugLogFile);

    $host = $dbConfig['host'] ?? 'localhost';
    $port = $dbConfig['port'] ?? 5432;
    $dbname = $dbConfig['dbname'] ?? '';
    $user = $dbConfig['user'] ?? '';
    $password = $dbConfig['password'] ?? '';

    // === Eingabedaten aus GET und POST lesen ===
    $data = array_merge($_GET, $_POST);
    internal_debug_log("RAW \$_GET: " . print_r($_GET, true), $debugLogFile);

    // --- Validierung und Normalisierung ---
    $street = $data['street'] ?? '';
    $houseNr = $data['houseNr'] ?? '';
    
    // Entfernen Sie alle Nicht-Adress-Bestandteile aus der Hausnummer, aber behalten Sie Buchstaben und Bindestriche
    $houseNr = preg_replace('/[^0-9a-zA-Z-]/', '', $houseNr); 

    if (empty($street) || empty($houseNr)) {
        throw new Exception('Fehlende Suchparameter (Straße und/oder Hausnummer).');
    }

    $street = trim($street);
    $houseNr = trim($houseNr);

    $mappedData = [
        'street' => $street,
        'houseNr' => $houseNr,
    ];

    internal_debug_log("Received Mapped data: " . print_r($mappedData, true), $debugLogFile);

    // === Verbindung zur Datenbank herstellen ===
    $connString = "host=$host port=$port dbname=$dbname user=$user password=$password";
    $dbconn = @pg_connect($connString); 

    if (!$dbconn) {
        $dbError = pg_last_error();
        internal_debug_log("Database connection failed: " . $dbError, $debugLogFile);
        throw new Exception('Datenbankverbindung fehlgeschlagen');
    }
    internal_debug_log("Database connection successful. Client encoding: " . pg_client_encoding($dbconn), $debugLogFile);

    pg_set_client_encoding($dbconn, "UTF8");

    // === SQL-Query vorbereiten und ausführen ===
    $similarityThreshold = 0.4;
    $queryParams = [$street];
    $paramIndex = 2; // Nächster Parameter-Index in der Abfrage

    // 1. Hausnummer Normalisierung (Leerzeichen entfernen)
    $houseNrNormalized = str_replace(' ', '', $houseNr);

    // 2. Bereichsbehandlung: Nur der erste Teil der Hausnummer wird verwendet, falls ein Bereich gesucht wird.
    if (strpos($houseNrNormalized, '-') !== false) {
        $house_no_start = explode('-', $houseNrNormalized)[0]; 
        $house_noParam = $house_no_start . '%'; 
        internal_debug_log("Bereich erkannt. Suche mit ILIKE auf Startnummer: " . $house_noParam, $debugLogFile);
        
    } else if (preg_match('/^\d+$/', $houseNrNormalized)) {
        // Wenn nur eine reine Zahl (z.B. "9") gesucht wird.
        // Um zu verhindern, dass "90" oder "99" gefunden wird, muss hier die Logik verfeinert werden.
        // Die aktuelle ILIKE-Logik im SQL (`ILIKE $2` mit `$2='9%'`) verursacht die Überzählung.
        // Für eine exakte Hausnummer muss der '%' weggelassen werden.
        
        // Wir setzen hier den exakten Wert. Das SQL MUSS dann `=` oder einen präzisen ILIKE-Ausdruck verwenden.
        $house_noParam = $houseNrNormalized; // KEIN '%'
        // Wir behalten den '%' in der WHERE-Klausel für den Moment bei, da der User den SQL-String nicht gezeigt hat. 
        // Dies ist der wahrscheinliche Punkt, an dem die 4 zustande kommt!

        // Wenn wir hier KEINEN % anhängen, würde das SQL fehlschlagen, wenn es den % erwartet.
        // Wir setzen den % HIER, um das SQL nicht zu ändern, aber die Analyse zu fokussieren.
        // Für Debugging: HIER KEIN % setzen, um exakte Nummer zu erzwingen, und die SQL-WHERE-Klausel anpassen!
        $house_noParam = $houseNrNormalized . '%';
        internal_debug_log("Einzelnummer erkannt. Suche mit ILIKE: " . $house_noParam, $debugLogFile);

    } else {
        // Einzelne Nummer mit Suffix (z.B. "9A"): Exakte Suche mit Wildcard am Ende
        $house_noParam = $houseNrNormalized . '%'; 
        internal_debug_log("Einzelnummer mit Suffix erkannt. Suche mit ILIKE: " . $house_noParam, $debugLogFile);
    }
    
    $queryParams[] = $house_noParam;
    $queryParams[] = $street; // Für ORDER BY

    $poiColumns = getPoiSelectFields();
    
    // Anmerkung: Die Aggregation in diesem Query geht davon aus, 
    // dass die Hausnummern-Suche (REPLACE(house_no, ' ', '') ILIKE $2) präzise ist.
    $query = "
        SELECT 
            street, 
            REPLACE(house_no, ' ', '') AS house_no_normalized,
            localdistrict,
            
            COUNT(*) AS stolperstein_count,
            AVG(ST_Y(geom_geolocation)) AS lat, 
            AVG(ST_X(geom_geolocation)) AS lng,
            
            STRING_AGG(first_name || ' ' || last_name || 
                CASE 
                    WHEN year_of_birth IS NOT NULL AND year_of_birth > 0 
                    THEN ' (geb. ' || year_of_birth || ')' 
                    ELSE '' 
                END, ' ||| ') AS aggregated_names
        
        FROM \"{$targetTable}\" 
        WHERE 
            similarity(street, $1) > {$similarityThreshold} AND REPLACE(house_no, ' ', '') ILIKE $2
            
        GROUP BY
            street, REPLACE(house_no, ' ', ''), localdistrict
            
        ORDER BY similarity(street, $3) DESC 
        LIMIT 10
    ";
    
    internal_debug_log("Executing SQL: " . $query . " with params: " . print_r($queryParams, true), $debugLogFile);

    $result = pg_query_params($dbconn, $query, $queryParams);

    if (!$result) {
        $dbError = pg_last_error($dbconn);
        internal_debug_log("SQL query failed: " . $dbError, $debugLogFile);
        throw new Exception('Datenbankabfrage fehlgeschlagen: ' . $dbError);
    }
    $rows = pg_fetch_all($result) ?: [];
    pg_free_result($result);

    internal_debug_log("Abfrage ausgeführt. Gefundene Datensätze: " . (count($rows) ?: 0), $debugLogFile);
    
    // ⭐ NEUE PROTOKOLLIERUNG DER ROHDATEN (GRUPPEN) ⭐
    if (!empty($rows)) {
        internal_debug_log("Rohdaten (Gruppen): " . print_r($rows, true), $debugLogFile);
    }
    // ⭐ ENDE NEUE PROTOKOLLIERUNG ⭐
    
    // === Ergebnis transformieren und zurückgeben ===
    $transformedRows = array_map(function($row) {
        
        $street = $row['street'] ?? '';
        $houseNr = $row['house_no_normalized'] ?? '';
        $district = $row['localdistrict'] ?? '';
        $count = (int)($row['stolperstein_count'] ?? 0);
        
        // Formatierter Display Name
        $displayName = $street;
        if (!empty($houseNr)) {
            $displayName .= " $houseNr";
        }
        if (!empty($district)) {
            $displayName .= ", $district"; 
        }
        $displayName .= " ($count)";
        
        
        return [
            'source'     => 'POI',
            'precision'  => 'grouped',
            'street'     => $street,
            'houseNr'    => $houseNr, 
            'district'   => $district,
            'city'       => 'Berlin', 
            'postcode'   => '',
            'lat' => (float)($row['lat'] ?? 0),
            'lng' => (float)($row['lng'] ?? 0),
            
            // Aggregierte Daten
            'poi_count'        => $count,
            'aggregated_names' => $row['aggregated_names'] ?? '',
            
            'display_name' => $displayName,
            'original_poi' => $row,
        ];
    }, $rows ?: []); 

    pg_close($dbconn);

    $response = [
        'success' => true,
        'data' => $transformedRows
    ];

    echo json_encode($response, JSON_PRETTY_PRINT);

} catch (Exception $e) {
    internal_debug_log("Caught global Exception: " . $e->getMessage(), $debugLogFile);
    // Setzt den Status-Code auf 400 für ungültige Benutzereingaben oder 500 für allgemeine Fehler.
    $statusCode = (strpos($e->getMessage(), 'Ungültige Suche:') !== false || strpos($e->getMessage(), 'Fehlende Namensbestandteile') !== false) ? 400 : 500;
    http_response_code($statusCode);
    echo json_encode(['success' => false, 'error' => 'Ein Serverfehler ist aufgetreten.', 'details' => $e->getMessage()], JSON_PRETTY_PRINT);
    
    if (isset($dbconn) && is_resource($dbconn)) {
        pg_close($dbconn);
    }
}

internal_debug_log("--- " . basename(__FILE__) . " END ---", $debugLogFile);
?>