/**
 * ScStone-Klasse
 * Verwaltet die Daten eines einzelnen Stolpersteins.
 * * FIX: 'throw' durch 'console.warn' ersetzt, um Abstürze bei 
 * unerwarteten Datenbank-Feldern oder Datentypen zu verhindern.
 */

import { BackendService } from './backend-poi.js';
import { getCurrentUser, getCurrentTimestamp } from './sc-utilities.js';

export class ScStone {
    // Definition der erlaubten Felder und ihrer Datentypen
    static allowedFields = {
        first_name: "string",
        last_name: "string",
        year_of_birth: "number",
        street: "string",
        house_no: "string",
        localdistrict: "string",
        city: "string",
        lat: "number",
        lng: "number",
        stone_position: "string",
        status: "string",
        comment: "string",
        caretaker: "string",
        url_wikipedia: "string",
        needs_cleaning: "boolean", // Hier als boolean definieren -> errechnetet wert aus dem backend
        Confirmed_by: "string",
        manual_address: "boolean",
        url_kodb: "string", // Kleingeschrieben für Kompatibilität
        last_cleaned: "string",
        instance_nr: "string",
        cleaned_by: "string",
    };

    constructor(data = {}, backendServiceInstance) {
        // GID (Primary Key) sicherstellen
        if (data.hasOwnProperty("gid")) {
            this.gid = data.gid;
        }

        // Alle Felder aus den Rohdaten verarbeiten
        Object.keys(data).forEach((key) => {
            if (key !== "gid") {
                this.set(key, data[key]);
            }
        });

        // Metadaten übernehmen
        this.updated_by = data.updated_by || null;
        this.updated_at = data.updated_at || null;

        if (backendServiceInstance instanceof BackendService) {
            this.backendService = backendServiceInstance;
        } else {
            // Dies ist ein kritischer Fehler in der App-Logik, daher bleibt das throw hier
            throw new Error("Missing or invalid BackendService instance for ScStone.");
        }
    }

    /**
     * Setzt einen Wert und prüft den Typ, ohne das Programm bei Fehlern zu stoppen.
     */
    set(key, value) {
        // 1. Prüfen, ob das Feld bekannt ist
        if (ScStone.allowedFields.hasOwnProperty(key)) {
            const expectedType = ScStone.allowedFields[key];

            // Sonderfall: Numerische Validierung (Wichtig für die Karte)
            if (key === "lat" || key === "lng" || key === "year_of_birth") {
                const numValue = parseFloat(value);
                if (isNaN(numValue)) {
                    console.warn(`ScStone: Ungültige Zahl für ${key}:`, value);
                    this[key] = 0; // Fallback
                    return;
                }
                this[key] = numValue;
                return;
            }

            // Sonderfall: Boolean
            if (expectedType === "boolean") {
                this[key] = (value === true || String(value).toLowerCase() === "true" || value === "t");
                return;
            }

            // Standard-Typprüfung (Warnen statt Absturz)
            if (typeof value !== expectedType && value !== null && value !== undefined) {
                console.warn(`ScStone: Typ-Abweichung bei "${key}". Erwartet: ${expectedType}, Erhalten: ${typeof value}`, value);
            }
            
            this[key] = value;
        } else {
            // Unbekanntes Feld (wie url_kodb früher)
            console.warn(`ScStone: Feld "${key}" ist nicht in allowedFields definiert.`);
            this[key] = value; // Trotzdem speichern, damit die Daten nicht verloren gehen
        }
    }

    /**
     * Update-Methoden für das Backend
     */
    async updateCleaningStatus(isDirty) {
        const username = getCurrentUser();
        if (!username) throw new Error("Kein Benutzername vorhanden");

        const data = {
            gid: this.gid,
            username: username,
            deviceInfo: { os: "Web", version: "1.0", model: "Browser" },
        };

        try {
            const result = await this.backendService.updateStoneCleaningStatus(data, isDirty);
            return result;
        } catch (error) {
            console.error("ScStone.updateCleaningStatus Error:", error);
            throw error;
        }
    }

    async updateCaretakerStatus(isChecked) {
        const username = getCurrentUser();
        if (!username) throw new Error("Benutzername nicht vorhanden.");

        const data = {
            gid: this.gid,
            caretaker: isChecked ? "anonym" : "",
            username: username,
            deviceInfo: { os: "Web", version: "1.0", model: "Browser" },
        };

        try {
            const result = await this.backendService.updateStoneCaretakerStatus(data);
            return result;
        } catch (error) {
            console.error("ScStone.updateCaretakerStatus Error:", error);
            throw error;
        }
    }
}