class ScStone {
  static allowedFields = {
    first_name: "string",
    last_name: "string",
    year_of_birth: "number",
    street: "string",
    house_no: "string",
    localdistrict: "string",
    city: "string",
    geom: "string", // Annahme: Geometrie als WKT-String
    Lat: "number",
    Lon: "number",
    stone_position: "string",
    status: "string",
    comment: "string",
    caretaker: "string",
    URL_Wikipedia: "string",
    Confirmed_by: "string",
    manual_address: "boolean",
    URL_KoDb: "string",
    last_cleaned: "string", // Annahme: ISO-Datumsstring
    instance_nr: "string",
    cleaned_by: "string",
  };

  constructor(data = {}) {
    Object.keys(data).forEach((key) => {
      if (ScStone.allowedFields.hasOwnProperty(key)) {
        // Statt direkt zuzuweisen, verwenden wir die set() Methode
        this.set(key, data[key]);
      } else {
        throw new Error(`Unbekanntes Feld: ${key}`);
      }
    });
  }

  // Hilfsmethode zum Konvertieren in Zahl
  convertToNumber(value, key) {
    const numberValue = parseFloat(value);
    if (isNaN(numberValue)) {
      throw new Error(
        `Ungültiger Wert für ${key}: Konnte nicht in Zahl konvertiert werden.`
      );
    }
    return numberValue;
  }

  // Die set-Methode sorgt für Validierung und Konvertierung
  set(key, value) {
    if (ScStone.allowedFields.hasOwnProperty(key)) {
      const expectedType = ScStone.allowedFields[key];

      // Konvertiere numerische Werte, falls der Wert ein String ist
      if (expectedType === "number") {
        value = this.convertToNumber(value, key);
      }

      // Validierung nach der Konvertierung
      if (
        typeof value === expectedType ||
        (expectedType === "boolean" &&
          typeof value === "string" &&
          value.toLowerCase() === "true")
      ) {
        this[key] = value;
      } else {
        throw new Error(
          `Ungültiger Wert für ${key}: Erwartet ${expectedType}, aber erhalten: ${typeof value}`
        );
      }
    } else {
      throw new Error(`Unbekanntes Feld: ${key}`);
    }
  }

  toJSON() {
    return { ...this };
  }

  // Neue Methode zum Speichern der ScStone-Instanz mit maximal 3 Versuchen
  save(retryCount = 0) {
    return fetch("test_insert.php", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(this), // Sendet die Instanz als JSON
    })
      .then((response) => {
        if (!response.ok) {
          throw new Error("Netzwerkantwort war nicht ok.");
        }
        return response.json(); // Verarbeite die Antwort als JSON
      })
      .then((data) => {
        if (data.success) {
          // Erfolgreiches Einfügen, gib die GID zurück
          return data.gid;
        } else {
          throw new Error("Fehler: " + data.message);
        }
      })
      .catch((error) => {
        console.error("Fetch-Fehler:", error);
        if (retryCount < 3) {
          console.log(`Wiederhole Anfrage... Versuch ${retryCount + 1}`);
          return this.save(retryCount + 1); // Versuche erneut
        } else {
          throw new Error(
            "Maximale Anzahl von Versuchen erreicht: " + error.message
          );
        }
      });
  }
}
