/*
Verantwortlichkeiten der ScStone-Klasse
Die ScStone-Klasse ist jetzt ein echtes Datenmodell. Ihre Methoden haben die richtige Rolle:

Daten-Validierung und -Verwaltung: Methoden wie set(), convertToNumber() und das allowedFields-Objekt stellen sicher, 
dass die Daten intern korrekt sind. Dies ist die Kernaufgabe eines Datenmodells.

Vorbereitung der Geschäftsdaten: Die Methoden updateCleaningStatus() und updateCaretakerStatus() bereiten das 
korrekte Datenobjekt (data) vor, das für die jeweilige Geschäftslogik notwendig ist. Sie kennen die Struktur des 
Stolpersteins und wissen, welche Daten für das Backend benötigt werden.

Delegation an den BackendService: Anstatt selbst fetch()-Aufrufe durchzuführen, delegieren diese Methoden die 
Netzwerkanfrage korrekt an die this.backendService-Instanz. 

Die Logik, die jetzt in ScStone verbleibt, ist die Domänenlogik oder Geschäftslogik – also alles, was mit der 
Repräsentation und dem Zustand eines Stolpersteins zu tun hat. Die Netzwerklogik wurde erfolgreich ausgelagert.
*/
import { BackendService } from './backend-poi.js';
import { getCurrentUser,getCurrentTimestamp } from './sc-utilities.js'; 

export class ScStone {
  static allowedFields = {
    first_name: "string",
    last_name: "string",
    year_of_birth: "number",
    street: "string",
    house_no: "string",
    localdistrict: "string",
    city: "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", // ISO-Datumsstring
    instance_nr: "string",
    cleaned_by: "string",
  };

  constructor(data = {}, backendServiceInstance) {

    // Sonderbehandlung für gid (primary key)
    if (data.hasOwnProperty("gid")) {
      this.gid = data.gid;
    }

    // Setze nur erlaubte Felder über die set-Methode
    Object.keys(data).forEach((key) => {
      if (ScStone.allowedFields.hasOwnProperty(key)) {
        this.set(key, data[key]);
      } else if (key !== "gid") {
        throw new Error(`Unbekanntes Feld: ${key}`);
      }
    });


    // Initialisiere die Metadaten auf null oder "unbekannt", wenn das Objekt noch nicht gespeichert ist
    this.updated_by = null;  // Wird erst beim Speichern gesetzt
    this.updated_at = null;  // Wird erst beim Speichern gesetzt

    if (backendServiceInstance instanceof BackendService) { // Stelle sicher, dass BackendService importiert ist
      this.backendService = backendServiceInstance;  // Eigenschaft dynamisch hinzufügen, cool ;-)
    } else {
      console.error("ScStone: Eine gültige BackendService-Instanz muss übergeben werden.");
      // OPTIONAL: Wirf einen Fehler, wenn keine Instanz übergeben wird, um Probleme frühzeitig zu erkennen.
      throw new Error("Missing BackendService instance for ScStone.");
    }
  } // Ende Konstruktor

  // 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
  set(key, value) {
    if (ScStone.allowedFields.hasOwnProperty(key)) {
      const expectedType = ScStone.allowedFields[key];

      // Überprüfe, ob die Werte für Lat, Lon und year_of_birth numerisch sind
      if (key === "Lat" || key === "Lon" || key === "year_of_birth") {
        if (typeof value !== "number" || isNaN(value)) {
          throw new Error(
            `Ungültiger Wert für ${key}: Erwartet eine Zahl, aber erhalten: ${value}`
          );
        }
      }

      // Validierung nach der Typüberprüfung
      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}`);
    }
  }



  /**
   * Methode zum Aktualisieren des Reinigungsstatus
   * @param {boolean} isDirty - true für schmutzig, false für sauber
   * @returns {Promise<Object>} Das Ergebnis des Updates vom Server
   */
  async updateCleaningStatus(isDirty) {
    const username = getCurrentUser();
    if (!username) {
      throw new Error("Kein Benutzername vorhanden");
    }

    if (typeof isDirty !== "boolean") {
      throw new Error("Ungültiger Parameter: isDirty muss true oder false sein");
    }

    // Das 'data'-Objekt wird hier in ScStone.js zusammengestellt,
    // da ScStone die Domänenklasse ist und die relevanten Daten kennt.
    const data = {
      gid: this.gid, // Die GID des aktuellen ScStone-Objekts
      username: username,
      deviceInfo: {
        os: "Web", // Beispielwerte, die Sie anpassen müssten
        version: "1.0",
        model: "Browser",
      },
    };

    try {
      // **HIER IST DER AUFRUF DES BACKENDSERVICE**
      // Wir rufen die Methode 'updateStoneCleaningStatus' auf der Instanz 'this.backendService' auf.
      // Wir übergeben das gesamte 'data'-Objekt und den Boolean 'isDirty'.
      const result = await this.backendService.updateStoneCleaningStatus(data, isDirty);

      // Die Prüfung auf Erfolg des *Geschäftsvorgangs* findet weiterhin hier statt,
      // da der BackendService nur die rohe Serverantwort liefert.
      if (!result.success) {
        throw new Error(result.error || "Unbekannter Fehler beim Aktualisieren des Reinigungsstatus.");
      }
      return result;
    } catch (error) {
      console.error("ScStone.updateCleaningStatus: Fehler beim Senden der Anfrage:", error);
      throw error; // Fehler weiterreichen zur weiteren Handhabung in der UI oder darüber
    }
  }


    async updateCaretakerStatus(isChecked) {
        const username = getCurrentUser(); 
        if (!username) {
            throw new Error("Benutzername nicht vorhanden. Keine Aktualisierung möglich.");
        }

        const data = {
            gid: this.gid,
            caretaker: isChecked ? "anonym" : "",
            username: username, // Hinzugefügt: Benutzername für die Anfrage
            deviceInfo: {      // Hinzugefügt: Geräteinformationen
                os: "Web",
                version: "1.0",
                model: "Browser",
            },
        };

        console.log("DEBUG: ScStone.js - Daten die an den Server gesendet werden:", data);

        try {
            // Der Aufruf bleibt gleich, da die Methode im BackendService das korrekte Datenobjekt erwartet
            const result = await this.backendService.updateStoneCaretakerStatus(data);
            if (!result.success) {
                // Hier wird die Geschäftslogik-Antwort vom BackendService geprüft
                throw new Error(result.error || "Unbekannter Fehler beim Aktualisieren des Paten-Status.");
            }
            return result;
        } catch (error) {
            console.error("Fehler in ScStone.updateCaretakerStatus:", error);
            throw error; // Fehler weiterreichen
        }
    }

}
