// Poi.js
/**
 * Poi-Klasse (Lightweight Version)
 * Verwaltet die Daten eines einzelnen Stolpersteins, validiert Typen 
 * und mappt Datenstrukturen für das Backend/Frontend.
 */

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

export class Poi {
    // Definition der erlaubten Felder und ihrer Datentypen für die Validierung
    static allowedFields = {
        first_name: "string",
        last_name: "string",
        year_of_birth: "number",
        street: "string",
        houseNr: "string",
        localdistrict: "string",
        city: "string",
        lat: "number",
        lng: "number",
        stone_position: "string",
        status: "string",
        comment: "string",
        caretaker: "string",
        url_wikipedia: "string",
        needs_cleaning: "boolean",
        Confirmed_by: "string",
        manual_address: "boolean",
        url_kodb: "string",
        last_cleaned: "string",
        instance_nr: "string",
        cleaned_by: "string",
        updated_at: "string",
        updated_by: "string"
    };

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

        // Mapping: house_no (aus DB/PHP) -> houseNr (internes JS Format)
        if (data.house_no !== undefined) {
            data.houseNr = data.house_no;
            delete data.house_no;
        }

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

        // Metadaten explizit setzen (Fallbacks nutzen, falls nicht vorhanden)
        this.updated_by = this.updated_by || data.updated_by || null;
        this.updated_at = this.updated_at || data.updated_at || null;
    }

    /**
     * Setzt einen Wert und führt eine Typprüfung/Konvertierung durch.
     */
    set(key, value) {
        if (Poi.allowedFields.hasOwnProperty(key)) {
            const expectedType = Poi.allowedFields[key];

            // Numerische Validierung & Konvertierung (verhindert NaN im State)
            if (expectedType === "number") {
                const numValue = parseFloat(value);
                if (isNaN(numValue)) {
                    console.warn(`Poi: Ungültige Zahl für ${key}:`, value);
                    this[key] = 0;
                    return;
                }
                this[key] = numValue;
                return;
            }

            // Boolean Validierung (interpretiert diverse Backend-Formate)
            if (expectedType === "boolean") {
                this[key] = (value === true || String(value).toLowerCase() === "true" || value === "t" || value === 1);
                return;
            }

            // Standard-Typprüfung für Strings
            if (typeof value !== expectedType && value !== null && value !== undefined) {
                console.warn(`Poi: Typ-Abweichung bei "${key}". Erwartet: ${expectedType}, Erhalten: ${typeof value}`, value);
            }

            this[key] = value;
        } else {
            // Unbekanntes Feld (wird mit Warnung übernommen)
            console.warn(`Poi: Feld "${key}" ist nicht in allowedFields definiert.`);
            this[key] = value;
        }
    }

    /**
     * Erzeugt ein JSON-Objekt für das API-Backend.
     * Mappt interne JS-Namen zurück auf DB-Spaltennamen (z.B. houseNr -> house_no).
     * @returns {object}
     */
    toApiJson() {
        return {
            gid: this.gid,
            first_name: this.first_name || "",
            last_name: this.last_name || "",
            year_of_birth: this.year_of_birth || 0,
            street: this.street || "",
            house_no: this.houseNr || "", // Zurück-Mapping für PHP-Backend
            localdistrict: this.localdistrict || "",
            city: this.city || "",
            lat: this.lat || 0,
            lng: this.lng || 0,
            updated_at: this.updated_at || getCurrentTimestamp(),
            stone_position: this.stone_position || null,
            status: this.status || null,
            comment: this.comment || null,
            caretaker: this.caretaker || null,
            URL_Wikipedia: this.url_wikipedia || null,
            Confirmed_by: this.Confirmed_by || null,
            manual_address: this.manual_address || false,
            URL_KoDb: this.url_kodb || null,
            last_cleaned: this.last_cleaned || null,
            instance_nr: this.instance_nr || null,
            cleaned_by: this.cleaned_by || null
        };
    }
}