// validate_address.js (Korrigierte Version mit strenger Adressvalidierung)

import { mylog, showToast } from './sc-utilities.js';

/**
 * ruft die url ( service mit parametern) und gibt die antwort als json zurück.
 * Implementiert Exponential Backoff und Retry-Logik.
 * @param {string} url 
 * @param {number} retries  max anz wiederholungen
 * @param {number} delay
 * @returns {Promise<any>}
 */
function fetchWithRetry(url, retries = 3, delay = 500) {
  return new Promise((resolve, reject) => {
    function attemptFetch(attempt) {
      const currentDelay = delay * Math.pow(2, attempt);

      fetch(url)
        .then((response) => {
          if (!response.ok) {
            if (response.status === 404) {
                 throw new Error("404: Adresse nicht gefunden.");
            }
            throw new Error(`HTTP Fehler: ${response.status}`);
          }
          return response.json();
        })
        .then((json) => {
          resolve(json);
        })
        .catch((error) => {
          if (error.message.includes("404") || attempt >= retries) {
            reject(new Error(`Maximale Anzahl von Versuchen erreicht oder Fehler: ${error.message}`));
          } else {
            mylog(`[fetchWithRetry] Versuch ${attempt + 1}/${retries} fehlgeschlagen. Versuche in ${currentDelay}ms erneut. Fehler: ${error.message}`);
            showToast(`Laden der Koordinaten fehlgeschlagen. Versuch ${attempt + 1}.`);
            setTimeout(() => attemptFetch(attempt + 1), currentDelay);
          }
        });
    }
    attemptFetch(0);
  });
}

/**
 * Ruft die Koordinaten für eine Adresse über den Geocoding-Service ab.
 * Baut die URL auf, indem Adress-Objektkomponenten als separate Query-Parameter übergeben werden.
 * Führt eine Plausibilitätsprüfung durch, um nur Treffer mit expliziter Hausnummer zurückzugeben.
 *
 * @param {{street: string, house_no: string, localdistrict: string}} fullAddressObject -
 * Das Adress-Objekt mit den einzelnen Komponenten.
 * @returns {Promise<{lat: number, lon: number}|null>} Koordinaten-Objekt oder null bei Misserfolg.
 */
export async function fetchCoordForAddress(fullAddressObject) {
  
  // 1. URL mit allen, URL-kodierten Parametern erstellen
  const streetEncoded = encodeURIComponent(fullAddressObject.street || '');
  const houseNoEncoded = encodeURIComponent(fullAddressObject.house_no || '');
  const localDistrictEncoded = encodeURIComponent(fullAddressObject.localdistrict || '');
  const cityEncoded = encodeURIComponent('Berlin');
  const countryEncoded = encodeURIComponent('Deutschland');
  
  const queryString = 
    `street=${streetEncoded}` +
    `&house_no=${houseNoEncoded}` +
    `&local_district=${localDistrictEncoded}` +
    `&city=${cityEncoded}` + 
    `&country=${countryEncoded}`+ 
    `&source=${'HERE'}`;

  
  const url = `https://www.app.stolperclean.de/webapp/DEVELOPMENT/validate_address_details.php?${queryString}`;
  
  const debugAddressString = `${fullAddressObject.street} ${fullAddressObject.house_no}, ${fullAddressObject.localdistrict}`;

  mylog(`[fetchCoordForAddress] Versuche Abruf für: "${debugAddressString}"`);
  
  
    try {
        // fetchWithRetry(url) wird verwendet, um den HTTP GET Request an das PHP-Skript zu senden
        const response = await fetchWithRetry(url);

        // 2. Prüfung auf 'status: success' im Rückgabeobjekt des PHP-Skripts
        if (response.status === 'success' && response.data) {
            
            const lat = response.data.latitude;
            const lon = response.data.longitude;
            const precision = response.precision_level;
            
            if (typeof lat === 'number' && typeof lon === 'number') {
                mylog(`[fetchCoordForAddress] ERGEBNIS gefunden (${response.source}, Präzision: ${precision}).`);
                return { lat: lat, lon: lon };
            }
        } 
        
        // 3. Fehlerfall (status: 'error' oder andere Mismatches vom PHP-Skript)
        
        if (response.status === 'error') {
             // Zeige die Fehlermeldung, die vom PHP-Backend gesendet wurde (z.B. "Distrikt-Mismatch")
             showToast(`Geocoding Fehler (${response.source}): ${response.message}`);
             mylog(`[fetchCoordForAddress] PHP Backend Fehler: ${response.message}`);
        } else {
             // Unbekanntes Format oder kein Erfolg
             mylog(`[fetchCoordForAddress] Backend meldet keinen Erfolg oder unerwartetes Format.`);
        }

        return null;

    } catch (error) {
        // Fängt Netzwerkfehler oder HTTP-Fehler ab (z.B. 400 vom PHP-Skript)
        mylog("[fetchCoordForAddress] Fehler im Catch-Block:", error);
        
        // Da das PHP-Skript bei Fehlern 400 zurückgibt, kann die Fehlermeldung hier spezifischer sein
        const errorMessage = error.message || 'Die Anfrage an das Geocoding-Backend schlug fehl (Netzwerk oder CORS).';
        showToast(`Verbindungsfehler zur Verifizierung: ${errorMessage}`);
        return null;
    }
}