<?php
/**
 * PocketBooking Pro — Vermietung / Ferienwohnungsmodus
 *
 * Zentrale Klasse für den Vermietungsmodus: Lizenz, DB-Tabellen, AJAX-Handler.
 *
 * @package PocketBookingPro
 * @since   2.0.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Simpbook_Vermietung {

    /** @var self|null */
    private static $instance = null;

    /**
     * Singleton-Zugriff.
     */
    public static function instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Constructor — registriert Hooks.
     */
    private function __construct() {
        // DB-Tabellen bei Plugin-Aktivierung anlegen
        register_activation_hook( SIMPBOOK_PLUGIN_DIR . 'simple-appointment-booking.php', [ $this, 'tabellen_erstellen' ] );

        // Tabellen bei Bedarf erstellen (falls Aktivierungs-Hook nicht lief)
        add_action( 'admin_init', [ $this, 'tabellen_pruefen_und_erstellen' ] );

        // AJAX-Handler für Vermietung
        add_action( 'wp_ajax_simpbook_vermietung_unterkunft_speichern', [ $this, 'ajax_unterkunft_speichern' ] );
        add_action( 'wp_ajax_simpbook_vermietung_unterkunft_loeschen', [ $this, 'ajax_unterkunft_loeschen' ] );
        add_action( 'wp_ajax_simpbook_vermietung_zimmer_speichern', [ $this, 'ajax_zimmer_speichern' ] );
        add_action( 'wp_ajax_simpbook_vermietung_zimmer_loeschen', [ $this, 'ajax_zimmer_loeschen' ] );
        add_action( 'wp_ajax_simpbook_vermietung_tag_speichern', [ $this, 'ajax_tag_speichern' ] );
        add_action( 'wp_ajax_simpbook_vermietung_tag_loeschen', [ $this, 'ajax_tag_loeschen' ] );
        add_action( 'wp_ajax_simpbook_vermietung_verfuegbarkeit', [ $this, 'ajax_verfuegbarkeit_pruefen' ] );
        add_action( 'wp_ajax_nopriv_simpbook_vermietung_verfuegbarkeit', [ $this, 'ajax_verfuegbarkeit_pruefen' ] );
        add_action( 'wp_ajax_simpbook_vermietung_buchen', [ $this, 'ajax_aufenthalt_buchen' ] );
        add_action( 'wp_ajax_nopriv_simpbook_vermietung_buchen', [ $this, 'ajax_aufenthalt_buchen' ] );
        add_action( 'wp_ajax_simpbook_vermietung_preis_berechnen', [ $this, 'ajax_preis_berechnen' ] );
        add_action( 'wp_ajax_nopriv_simpbook_vermietung_preis_berechnen', [ $this, 'ajax_preis_berechnen' ] );
        add_action( 'wp_ajax_nopriv_simpbook_verfuegbarkeit_kalender', [ $this, 'ajax_verfuegbarkeit_kalender' ] );
        add_action( 'wp_ajax_simpbook_verfuegbarkeit_kalender', [ $this, 'ajax_verfuegbarkeit_kalender' ] );
        add_action( 'wp_ajax_simpbook_vermietung_buchung_status', [ $this, 'ajax_buchung_status_aendern' ] );
        add_action( 'wp_ajax_simpbook_vermietung_verfuegbarkeit_block', [ $this, 'ajax_verfuegbarkeit_blockieren' ] );

        // Frontend-Shortcodes
        add_shortcode( 'simpbook_unterkuenfte', [ $this, 'shortcode_unterkuenfte_grid' ] );
        add_shortcode( 'simpbook_unterkunft', [ $this, 'shortcode_unterkunft_detail' ] );

        // Admin-Assets laden
        add_action( 'admin_enqueue_scripts', [ $this, 'admin_assets_laden' ] );
        add_action( 'wp_enqueue_scripts', [ $this, 'frontend_assets_laden' ] );
    }

    // =========================================================================
    // LIZENZ-SYSTEM
    // =========================================================================

    /**
     * Prüft ob eine gültige Vermietungs-Lizenz vorliegt.
     */
    public static function lizenz_aktiv() {
        return get_option( 'simpbook_vermietung_lizenz_status', '' ) === 'gueltig';
    }

    /**
     * Prüft ob die Vermietungs-Trial-Phase aktiv ist.
     */
    public static function trial_aktiv() {
        $trial_start = (int) get_option( 'simpbook_vermietung_trial_start_time', 0 );
        if ( $trial_start <= 0 ) {
            return false;
        }
        $trial_dauer = 14 * DAY_IN_SECONDS; // 14 Tage
        return ( time() - $trial_start ) < $trial_dauer;
    }

    /**
     * Hat der Nutzer Zugang zum Vermietungsmodus? (Lizenz ODER Trial)
     */
    public static function hat_zugang() {
        return self::lizenz_aktiv() || self::trial_aktiv();
    }

    /**
     * Startet den Trial automatisch beim ersten Admin-Zugriff.
     */
    public static function trial_init() {
        if ( get_option( 'simpbook_vermietung_trial_ever_started', false ) ) {
            return; // Trial war schon mal aktiv
        }
        update_option( 'simpbook_vermietung_trial_start_time', time() );
        update_option( 'simpbook_vermietung_trial_ever_started', true );
    }

    /**
     * Validiert einen Vermietungs-Lizenzschlüssel gegen den Lizenzserver.
     *
     * @param string $lizenz_key Der eingegebene Lizenzschlüssel.
     * @return bool True wenn gültig, false sonst.
     */
    public static function lizenz_validieren( $lizenz_key ) {
        $lizenz_server_url = 'https://mobile-refuel.de/wp-content/plugins/mobile-refuel-lizenzserver/lizenzen/check_license.php';
        $token             = 'aP39F3kLc9x!mZ82';
        $domain            = home_url();

        $response = wp_remote_get( add_query_arg(
            [
                'key'         => urlencode( $lizenz_key ),
                'token'       => $token,
                'domain'      => urlencode( $domain ),
                'plugin_slug' => 'simple-appointment-booking-vermietung',
                'action'      => 'check_license',
            ],
            $lizenz_server_url
        ), [ 'timeout' => 15 ] );

        if ( is_wp_error( $response ) ) {
            update_option( 'simpbook_vermietung_lizenz_status', 'error' );
            return false;
        }

        $body = wp_remote_retrieve_body( $response );
        $data = json_decode( $body, true );

        if ( ! $data ) {
            update_option( 'simpbook_vermietung_lizenz_status', 'error' );
            return false;
        }

        if ( isset( $data['status'] ) ) {
            if ( $data['status'] === 'valid' ) {
                update_option( 'simpbook_vermietung_lizenz_status', 'gueltig' );
                delete_option( 'simpbook_vermietung_trial_start_time' );
                delete_option( 'simpbook_vermietung_trial_ever_started' );
                return true;
            } elseif ( in_array( $data['status'], [ 'invalid', 'limit_reached', 'error' ], true ) ) {
                update_option( 'simpbook_vermietung_lizenz_status', $data['status'] );
                return false;
            }
        }

        update_option( 'simpbook_vermietung_lizenz_status', 'error' );
        return false;
    }

    // =========================================================================
    // DATENBANK
    // =========================================================================

    /**
     * Erstellt alle Vermietungs-Tabellen.
     */
    public function tabellen_erstellen() {
        global $wpdb;
        $charset_collate = $wpdb->get_charset_collate();
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';

        // 1. Unterkünfte
        $sql_unterkuenfte = "CREATE TABLE {$wpdb->prefix}simpbook_unterkuenfte (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            titel varchar(255) NOT NULL,
            untertitel varchar(255) DEFAULT NULL,
            objektbeschreibung longtext DEFAULT NULL,
            status varchar(20) DEFAULT 'entwurf',
            unterkunft_typ varchar(50) DEFAULT 'ferienwohnung',
            vermietungsart varchar(20) DEFAULT 'gesamt',
            preis_pro_nacht decimal(10,2) DEFAULT NULL,
            preis_pro_woche decimal(10,2) DEFAULT NULL,
            rabatt_preis_nacht decimal(10,2) DEFAULT NULL,
            preis_anzeigen tinyint(1) DEFAULT 1,
            preis_auf_anfrage tinyint(1) DEFAULT 0,
            reinigungsgebuehr decimal(10,2) DEFAULT NULL,
            kaution decimal(10,2) DEFAULT NULL,
            max_gaeste int DEFAULT NULL,
            max_zimmer_gesamt int DEFAULT NULL,
            schlafplaetze int DEFAULT NULL,
            wohnflaeche decimal(10,2) DEFAULT NULL,
            grundstuecksflaeche decimal(10,2) DEFAULT NULL,
            baujahr int DEFAULT NULL,
            letzte_renovierung int DEFAULT NULL,
            strasse varchar(255) DEFAULT NULL,
            hausnummer varchar(20) DEFAULT NULL,
            plz varchar(10) DEFAULT NULL,
            ort varchar(100) DEFAULT NULL,
            bundesland varchar(100) DEFAULT NULL,
            land varchar(100) DEFAULT 'Deutschland',
            latitude decimal(10,7) DEFAULT NULL,
            longitude decimal(10,7) DEFAULT NULL,
            lage_beschreibung longtext DEFAULT NULL,
            ausstattung_json longtext DEFAULT NULL,
            bilder_json longtext DEFAULT NULL,
            titelbild_id bigint(20) DEFAULT NULL,
            mitarbeiter_id mediumint(9) DEFAULT NULL,
            min_naechte int DEFAULT NULL,
            max_naechte int DEFAULT NULL,
            checkin_uhrzeit time DEFAULT NULL,
            checkout_uhrzeit time DEFAULT NULL,
            buchbar_von date DEFAULT NULL,
            buchbar_bis date DEFAULT NULL,
            rabatt_codes text DEFAULT NULL,
            google_maps_anzeigen tinyint(1) DEFAULT 1,
            adresse_anzeigen tinyint(1) DEFAULT 1,
            sortierung int DEFAULT 0,
            erstellt_am datetime DEFAULT CURRENT_TIMESTAMP,
            aktualisiert_am datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY idx_status (status),
            KEY idx_typ (unterkunft_typ),
            KEY idx_ort (ort),
            KEY idx_mitarbeiter (mitarbeiter_id)
        ) $charset_collate;";

        // 2. Zimmer
        $sql_zimmer = "CREATE TABLE {$wpdb->prefix}simpbook_unterkunft_zimmer (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            unterkunft_id mediumint(9) NOT NULL,
            name varchar(255) NOT NULL,
            beschreibung text DEFAULT NULL,
            zimmer_typ varchar(50) DEFAULT 'doppelzimmer',
            preis_pro_nacht decimal(10,2) DEFAULT NULL,
            preis_pro_woche decimal(10,2) DEFAULT NULL,
            rabatt_preis_nacht decimal(10,2) DEFAULT NULL,
            max_gaeste int DEFAULT 2,
            schlafplaetze int DEFAULT 2,
            betten_beschreibung varchar(255) DEFAULT NULL,
            zimmergroesse decimal(8,2) DEFAULT NULL,
            ausstattung_json longtext DEFAULT NULL,
            bilder_json longtext DEFAULT NULL,
            titelbild_id bigint(20) DEFAULT NULL,
            anzahl_verfuegbar int DEFAULT 1,
            aktiv tinyint(1) DEFAULT 1,
            buchbar_von date DEFAULT NULL,
            buchbar_bis date DEFAULT NULL,
            sortierung int DEFAULT 0,
            PRIMARY KEY (id),
            KEY idx_unterkunft (unterkunft_id),
            KEY idx_aktiv (aktiv)
        ) $charset_collate;";

        // 3. Tags
        $sql_tags = "CREATE TABLE {$wpdb->prefix}simpbook_unterkunft_tags (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            name varchar(100) NOT NULL,
            slug varchar(100) NOT NULL,
            farbe varchar(7) DEFAULT '#2271b1',
            icon varchar(50) DEFAULT 'home',
            sortierung int DEFAULT 0,
            PRIMARY KEY (id),
            UNIQUE KEY slug (slug)
        ) $charset_collate;";

        // 4. Tag-Zuordnungen
        $sql_tag_zuordnungen = "CREATE TABLE {$wpdb->prefix}simpbook_unterkunft_tag_zuordnungen (
            id bigint(20) NOT NULL AUTO_INCREMENT,
            unterkunft_id mediumint(9) NOT NULL,
            tag_id mediumint(9) NOT NULL,
            PRIMARY KEY (id),
            UNIQUE KEY unterkunft_tag (unterkunft_id, tag_id),
            KEY idx_tag (tag_id)
        ) $charset_collate;";

        // 5. Aufenthalte (Buchungen)
        $sql_aufenthalte = "CREATE TABLE {$wpdb->prefix}simpbook_aufenthalte (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            unterkunft_id mediumint(9) NOT NULL,
            zimmer_id mediumint(9) DEFAULT NULL,
            gast_name varchar(255) NOT NULL,
            gast_email varchar(255) NOT NULL,
            gast_telefon varchar(50) DEFAULT NULL,
            gast_typ varchar(20) DEFAULT 'einzelperson',
            firmen_name varchar(255) DEFAULT NULL,
            firmen_adresse text DEFAULT NULL,
            anzahl_gaeste int DEFAULT 1,
            nachricht text DEFAULT NULL,
            checkin_datum date NOT NULL,
            checkout_datum date NOT NULL,
            checkin_uhrzeit time DEFAULT NULL,
            checkout_uhrzeit time DEFAULT NULL,
            anzahl_naechte int NOT NULL,
            preis_pro_nacht decimal(10,2) DEFAULT NULL,
            reinigungsgebuehr decimal(10,2) DEFAULT NULL,
            kaution decimal(10,2) DEFAULT NULL,
            rabatt_code_angewendet varchar(100) DEFAULT NULL,
            rabatt_betrag decimal(10,2) DEFAULT NULL,
            gesamtpreis decimal(12,2) DEFAULT NULL,
            preis_gebucht decimal(12,2) DEFAULT NULL,
            zahlungs_methode varchar(50) DEFAULT NULL,
            zahlungs_status varchar(50) DEFAULT NULL,
            rechnungs_email varchar(255) DEFAULT NULL,
            rechnungsnummer varchar(50) DEFAULT NULL,
            zahlungs_stripe_pi_id varchar(100) DEFAULT NULL,
            stripe_payment_type varchar(50) DEFAULT NULL,
            status varchar(20) DEFAULT 'AUSSTEHEND',
            storniert tinyint(1) DEFAULT 0,
            stornierungs_datum datetime DEFAULT NULL,
            stornierungs_token varchar(100) DEFAULT NULL,
            status_geaendert_datum datetime DEFAULT NULL,
            custom_fields text DEFAULT NULL,
            marketing_einwilligung tinyint(1) DEFAULT 0,
            erinnerung_gesendet tinyint(1) DEFAULT 0,
            erstellt_am datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY idx_unterkunft (unterkunft_id),
            KEY idx_zimmer (zimmer_id),
            KEY idx_checkin (checkin_datum),
            KEY idx_checkout (checkout_datum),
            KEY idx_status (status),
            KEY idx_zahlungs_status (zahlungs_status)
        ) $charset_collate;";

        // 6. Verfügbarkeit (blockierte Zeiten / Saisonpreise)
        $sql_verfuegbarkeit = "CREATE TABLE {$wpdb->prefix}simpbook_verfuegbarkeit (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            unterkunft_id mediumint(9) NOT NULL,
            zimmer_id mediumint(9) DEFAULT NULL,
            typ varchar(20) NOT NULL,
            datum_von date NOT NULL,
            datum_bis date NOT NULL,
            preis_pro_nacht decimal(10,2) DEFAULT NULL,
            bezeichnung varchar(100) DEFAULT NULL,
            PRIMARY KEY (id),
            KEY idx_unterkunft (unterkunft_id),
            KEY idx_zimmer (zimmer_id),
            KEY idx_datum (datum_von, datum_bis)
        ) $charset_collate;";

        dbDelta( $sql_unterkuenfte );
        dbDelta( $sql_zimmer );
        dbDelta( $sql_tags );
        dbDelta( $sql_tag_zuordnungen );
        dbDelta( $sql_aufenthalte );
        dbDelta( $sql_verfuegbarkeit );
    }

    /**
     * Prüft ob Vermietungstabellen existieren, erstellt sie bei Bedarf.
     */
    public function tabellen_pruefen_und_erstellen() {
        global $wpdb;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $tabelle_existiert = $wpdb->get_var(
            $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->prefix . 'simpbook_unterkuenfte' )
        );
        if ( ! $tabelle_existiert ) {
            $this->tabellen_erstellen();
        }
    }

    // =========================================================================
    // HELPER-FUNKTIONEN
    // =========================================================================

    /**
     * Holt eine einzelne Unterkunft.
     */
    public static function get_unterkunft( $id ) {
        global $wpdb;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        return $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}simpbook_unterkuenfte WHERE id = %d", $id
        ) );
    }

    /**
     * Holt alle Unterkünfte (optional gefiltert).
     */
    public static function get_unterkuenfte( $args = [] ) {
        global $wpdb;
        $defaults = [
            'status'   => 'aktiv',
            'limit'    => 50,
            'offset'   => 0,
            'order_by' => 'sortierung',
            'order'    => 'ASC',
        ];
        $args = wp_parse_args( $args, $defaults );

        $where = '1=1';
        $params = [];

        if ( ! empty( $args['status'] ) && $args['status'] !== 'alle' ) {
            $where .= ' AND status = %s';
            $params[] = $args['status'];
        }

        $order_by = in_array( $args['order_by'], [ 'id', 'titel', 'sortierung', 'erstellt_am', 'preis_pro_nacht', 'ort' ], true )
            ? $args['order_by'] : 'sortierung';
        $order = strtoupper( $args['order'] ) === 'DESC' ? 'DESC' : 'ASC';

        $sql = "SELECT * FROM {$wpdb->prefix}simpbook_unterkuenfte WHERE {$where} ORDER BY {$order_by} {$order} LIMIT %d OFFSET %d";
        $params[] = (int) $args['limit'];
        $params[] = (int) $args['offset'];

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
        return $wpdb->get_results( $wpdb->prepare( $sql, ...$params ) );
    }

    /**
     * Holt alle Zimmer einer Unterkunft.
     */
    public static function get_zimmer( $unterkunft_id ) {
        global $wpdb;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        return $wpdb->get_results( $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}simpbook_unterkunft_zimmer WHERE unterkunft_id = %d ORDER BY sortierung ASC",
            $unterkunft_id
        ) );
    }

    /**
     * Holt alle Tags.
     */
    public static function get_tags() {
        global $wpdb;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        return $wpdb->get_results(
            "SELECT * FROM {$wpdb->prefix}simpbook_unterkunft_tags ORDER BY sortierung ASC, name ASC"
        );
    }

    /**
     * Holt alle Tags einer Unterkunft.
     */
    public static function get_unterkunft_tags( $unterkunft_id ) {
        global $wpdb;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        return $wpdb->get_results( $wpdb->prepare(
            "SELECT t.* FROM {$wpdb->prefix}simpbook_unterkunft_tags t
             INNER JOIN {$wpdb->prefix}simpbook_unterkunft_tag_zuordnungen tz ON t.id = tz.tag_id
             WHERE tz.unterkunft_id = %d
             ORDER BY t.sortierung ASC",
            $unterkunft_id
        ) );
    }

    /**
     * Holt alle Aufenthalte (Buchungen) — optional gefiltert.
     */
    public static function get_aufenthalte( $args = [] ) {
        global $wpdb;
        $defaults = [
            'unterkunft_id' => 0,
            'status'        => '',
            'limit'         => 50,
            'offset'        => 0,
            'order_by'      => 'checkin_datum',
            'order'         => 'ASC',
            'von'           => '',
            'bis'           => '',
        ];
        $args = wp_parse_args( $args, $defaults );

        $where = 'storniert = 0';
        $params = [];

        if ( $args['unterkunft_id'] > 0 ) {
            $where .= ' AND unterkunft_id = %d';
            $params[] = (int) $args['unterkunft_id'];
        }

        if ( ! empty( $args['status'] ) ) {
            $where .= ' AND status = %s';
            $params[] = $args['status'];
        }

        if ( ! empty( $args['von'] ) ) {
            $where .= ' AND checkin_datum >= %s';
            $params[] = $args['von'];
        }

        if ( ! empty( $args['bis'] ) ) {
            $where .= ' AND checkout_datum <= %s';
            $params[] = $args['bis'];
        }

        $order_by = in_array( $args['order_by'], [ 'id', 'checkin_datum', 'checkout_datum', 'erstellt_am', 'gast_name', 'status', 'gesamtpreis' ], true )
            ? $args['order_by'] : 'checkin_datum';
        $order = strtoupper( $args['order'] ) === 'DESC' ? 'DESC' : 'ASC';

        $sql = "SELECT * FROM {$wpdb->prefix}simpbook_aufenthalte WHERE {$where} ORDER BY {$order_by} {$order} LIMIT %d OFFSET %d";
        $params[] = (int) $args['limit'];
        $params[] = (int) $args['offset'];

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
        return $wpdb->get_results( $wpdb->prepare( $sql, ...$params ) );
    }

    /**
     * Zählt Aufenthalte mit Filter.
     */
    public static function zaehle_aufenthalte( $where = '1=1' ) {
        global $wpdb;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
        return (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}simpbook_aufenthalte WHERE {$where}" );
    }

    /**
     * Berechnet den Preis für einen Aufenthalt.
     */
    public static function preis_berechnen( $unterkunft_id, $zimmer_id, $checkin, $checkout, $rabatt_code = '' ) {
        global $wpdb;
        $unterkunft = self::get_unterkunft( $unterkunft_id );
        if ( ! $unterkunft ) {
            return null;
        }

        $checkin_date  = new DateTime( $checkin );
        $checkout_date = new DateTime( $checkout );
        $naechte       = (int) $checkin_date->diff( $checkout_date )->days;

        if ( $naechte <= 0 ) {
            return null;
        }

        // Basis-Preis ermitteln (Unterkunft oder Zimmer)
        $basis_preis = (float) $unterkunft->preis_pro_nacht;

        if ( $zimmer_id > 0 ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $zimmer = $wpdb->get_row( $wpdb->prepare(
                "SELECT * FROM {$wpdb->prefix}simpbook_unterkunft_zimmer WHERE id = %d AND unterkunft_id = %d",
                $zimmer_id, $unterkunft_id
            ) );
            if ( $zimmer && $zimmer->preis_pro_nacht > 0 ) {
                $basis_preis = (float) $zimmer->preis_pro_nacht;
            }
        }

        // Saisonpreise pro Tag berechnen
        $gesamt_nachtpreis = 0;
        $aktuelle_nacht    = clone $checkin_date;
        for ( $i = 0; $i < $naechte; $i++ ) {
            $tages_preis = $basis_preis;

            // Prüfe Saisonpreise
            $datum_str = $aktuelle_nacht->format( 'Y-m-d' );
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $saison = $wpdb->get_row( $wpdb->prepare(
                "SELECT preis_pro_nacht FROM {$wpdb->prefix}simpbook_verfuegbarkeit
                 WHERE unterkunft_id = %d AND typ = 'saisonpreis'
                 AND (zimmer_id IS NULL OR zimmer_id = %d)
                 AND datum_von <= %s AND datum_bis >= %s
                 ORDER BY zimmer_id DESC LIMIT 1",
                $unterkunft_id, $zimmer_id, $datum_str, $datum_str
            ) );
            if ( $saison && $saison->preis_pro_nacht > 0 ) {
                $tages_preis = (float) $saison->preis_pro_nacht;
            }

            $gesamt_nachtpreis += $tages_preis;
            $aktuelle_nacht->modify( '+1 day' );
        }

        // Aufschläge
        $reinigung = (float) ( $unterkunft->reinigungsgebuehr ?? 0 );
        $kaution   = (float) ( $unterkunft->kaution ?? 0 );

        // Rabattcode prüfen
        $rabatt_betrag = 0;
        if ( ! empty( $rabatt_code ) && ! empty( $unterkunft->rabatt_codes ) ) {
            $codes = json_decode( $unterkunft->rabatt_codes, true );
            if ( is_array( $codes ) ) {
                foreach ( $codes as $code ) {
                    if (
                        isset( $code['code'] ) &&
                        strtoupper( trim( $code['code'] ) ) === strtoupper( trim( $rabatt_code ) )
                    ) {
                        // Gültigkeit prüfen
                        if ( ! empty( $code['gueltig_bis'] ) && strtotime( $code['gueltig_bis'] ) < time() ) {
                            break; // Abgelaufen
                        }
                        if ( isset( $code['typ'] ) && $code['typ'] === 'prozent' ) {
                            $rabatt_betrag = round( $gesamt_nachtpreis * ( (float) $code['betrag'] / 100 ), 2 );
                        } else {
                            $rabatt_betrag = (float) $code['betrag'];
                        }
                        break;
                    }
                }
            }
        }

        $gesamtpreis = $gesamt_nachtpreis - $rabatt_betrag + $reinigung;

        // Filter: Payment-Addon kann Preis modifizieren
        $gesamtpreis = apply_filters( 'simpbook_buchung_preis_berechnen', $gesamtpreis, [
            'modus'         => 'ferienhaeuser',
            'unterkunft_id' => $unterkunft_id,
            'zimmer_id'     => $zimmer_id,
            'naechte'       => $naechte,
            'basis_preis'   => $gesamt_nachtpreis,
        ] );

        return [
            'naechte'            => $naechte,
            'preis_pro_nacht'    => $basis_preis,
            'gesamt_nachtpreis'  => $gesamt_nachtpreis,
            'reinigungsgebuehr'  => $reinigung,
            'kaution'            => $kaution,
            'rabatt_betrag'      => $rabatt_betrag,
            'gesamtpreis'        => max( 0, $gesamtpreis ),
        ];
    }

    /**
     * Prüft Verfügbarkeit für einen Zeitraum.
     */
    public static function ist_verfuegbar( $unterkunft_id, $zimmer_id, $checkin, $checkout ) {
        global $wpdb;

        // 1. Blockierte Zeiträume prüfen
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $blockiert = $wpdb->get_var( $wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}simpbook_verfuegbarkeit
             WHERE unterkunft_id = %d AND typ = 'blockiert'
             AND (zimmer_id IS NULL OR zimmer_id = %d)
             AND datum_von < %s AND datum_bis > %s",
            $unterkunft_id, $zimmer_id, $checkout, $checkin
        ) );
        if ( $blockiert > 0 ) {
            return false;
        }

        // 2. Bestätigte oder ausstehende Buchungen prüfen
        $zimmer_where = $zimmer_id > 0 ? $wpdb->prepare( ' AND zimmer_id = %d', $zimmer_id ) : ' AND zimmer_id IS NULL';

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
        $belegt = $wpdb->get_var( $wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}simpbook_aufenthalte
             WHERE unterkunft_id = %d {$zimmer_where}
             AND storniert = 0 AND status IN ('AUSSTEHEND', 'BESTÄTIGT', 'BESTAETIGT', 'EINGECHECKT')
             AND checkin_datum < %s AND checkout_datum > %s",
            $unterkunft_id, $checkout, $checkin
        ) );

        // Bei Zimmern mit anzahl_verfuegbar > 1: Prüfe ob noch Kapazität frei
        if ( $zimmer_id > 0 ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $zimmer = $wpdb->get_row( $wpdb->prepare(
                "SELECT anzahl_verfuegbar FROM {$wpdb->prefix}simpbook_unterkunft_zimmer WHERE id = %d",
                $zimmer_id
            ) );
            $verfuegbar = $zimmer ? (int) $zimmer->anzahl_verfuegbar : 1;
            return $belegt < $verfuegbar;
        }

        return $belegt < 1;
    }

    // =========================================================================
    // AJAX-HANDLER
    // =========================================================================

    /**
     * AJAX: Unterkunft speichern (neu oder bearbeiten).
     */
    public function ajax_unterkunft_speichern() {
        if ( ! isset( $_POST['simpbook_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simpbook_nonce'] ) ), 'simpbook_unterkunft_speichern' ) ) {
            wp_send_json_error( 'Security check failed' );
            exit;
        }
        if ( ! current_user_can( 'read' ) ) {
            wp_send_json_error( 'Keine Berechtigung' );
            exit;
        }

        global $wpdb;
        $id = isset( $_POST['simpbook_unterkunft_id'] ) ? intval( $_POST['simpbook_unterkunft_id'] ) : 0;

        $daten = [
            'titel'               => isset( $_POST['titel'] ) ? sanitize_text_field( wp_unslash( $_POST['titel'] ) ) : '',
            'untertitel'          => isset( $_POST['untertitel'] ) ? sanitize_text_field( wp_unslash( $_POST['untertitel'] ) ) : '',
            'objektbeschreibung'  => isset( $_POST['objektbeschreibung'] ) ? wp_kses_post( wp_unslash( $_POST['objektbeschreibung'] ) ) : '',
            'status'              => isset( $_POST['status'] ) ? sanitize_text_field( wp_unslash( $_POST['status'] ) ) : 'entwurf',
            'unterkunft_typ'      => isset( $_POST['unterkunft_typ'] ) ? sanitize_text_field( wp_unslash( $_POST['unterkunft_typ'] ) ) : 'ferienwohnung',
            'vermietungsart'      => isset( $_POST['vermietungsart'] ) ? sanitize_text_field( wp_unslash( $_POST['vermietungsart'] ) ) : 'gesamt',
            'preis_pro_nacht'     => isset( $_POST['preis_pro_nacht'] ) ? floatval( $_POST['preis_pro_nacht'] ) : null,
            'preis_pro_woche'     => isset( $_POST['preis_pro_woche'] ) ? floatval( $_POST['preis_pro_woche'] ) : null,
            'rabatt_preis_nacht'  => isset( $_POST['rabatt_preis_nacht'] ) ? floatval( $_POST['rabatt_preis_nacht'] ) : null,
            'preis_anzeigen'      => isset( $_POST['preis_anzeigen'] ) ? 1 : 0,
            'preis_auf_anfrage'   => isset( $_POST['preis_auf_anfrage'] ) ? 1 : 0,
            'reinigungsgebuehr'   => isset( $_POST['reinigungsgebuehr'] ) ? floatval( $_POST['reinigungsgebuehr'] ) : null,
            'kaution'             => isset( $_POST['kaution'] ) ? floatval( $_POST['kaution'] ) : null,
            'max_gaeste'          => isset( $_POST['max_gaeste'] ) ? intval( $_POST['max_gaeste'] ) : null,
            'schlafplaetze'       => isset( $_POST['schlafplaetze'] ) ? intval( $_POST['schlafplaetze'] ) : null,
            'wohnflaeche'         => isset( $_POST['wohnflaeche'] ) ? floatval( $_POST['wohnflaeche'] ) : null,
            'strasse'             => isset( $_POST['strasse'] ) ? sanitize_text_field( wp_unslash( $_POST['strasse'] ) ) : '',
            'hausnummer'          => isset( $_POST['hausnummer'] ) ? sanitize_text_field( wp_unslash( $_POST['hausnummer'] ) ) : '',
            'plz'                 => isset( $_POST['plz'] ) ? sanitize_text_field( wp_unslash( $_POST['plz'] ) ) : '',
            'ort'                 => isset( $_POST['ort'] ) ? sanitize_text_field( wp_unslash( $_POST['ort'] ) ) : '',
            'land'                => isset( $_POST['land'] ) ? sanitize_text_field( wp_unslash( $_POST['land'] ) ) : 'Deutschland',
            'mitarbeiter_id'      => isset( $_POST['mitarbeiter_id'] ) ? intval( $_POST['mitarbeiter_id'] ) : null,
            'min_naechte'         => isset( $_POST['min_naechte'] ) ? intval( $_POST['min_naechte'] ) : null,
            'max_naechte'         => isset( $_POST['max_naechte'] ) ? intval( $_POST['max_naechte'] ) : null,
            'checkin_uhrzeit'     => isset( $_POST['checkin_uhrzeit'] ) ? sanitize_text_field( wp_unslash( $_POST['checkin_uhrzeit'] ) ) : null,
            'checkout_uhrzeit'    => isset( $_POST['checkout_uhrzeit'] ) ? sanitize_text_field( wp_unslash( $_POST['checkout_uhrzeit'] ) ) : null,
            'titelbild_id'        => isset( $_POST['titelbild_id'] ) ? intval( $_POST['titelbild_id'] ) : null,
        ];

        if ( $id > 0 ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->update( $wpdb->prefix . 'simpbook_unterkuenfte', $daten, [ 'id' => $id ], null, [ '%d' ] );
        } else {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
            $wpdb->insert( $wpdb->prefix . 'simpbook_unterkuenfte', $daten );
            $id = $wpdb->insert_id;
        }

        // Tags zuordnen
        if ( isset( $_POST['tags'] ) && is_array( $_POST['tags'] ) ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->delete( $wpdb->prefix . 'simpbook_unterkunft_tag_zuordnungen', [ 'unterkunft_id' => $id ], [ '%d' ] );
            foreach ( array_map( 'intval', $_POST['tags'] ) as $tag_id ) {
                if ( $tag_id > 0 ) {
                    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
                    $wpdb->insert(
                        $wpdb->prefix . 'simpbook_unterkunft_tag_zuordnungen',
                        [ 'unterkunft_id' => $id, 'tag_id' => $tag_id ],
                        [ '%d', '%d' ]
                    );
                }
            }
        }

        wp_send_json_success( [ 'id' => $id, 'message' => __( 'Unterkunft gespeichert.', 'simple-appointment-booking' ) ] );
        exit;
    }

    /**
     * AJAX: Unterkunft löschen.
     */
    public function ajax_unterkunft_loeschen() {
        if ( ! isset( $_POST['simpbook_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simpbook_nonce'] ) ), 'simpbook_unterkunft_loeschen' ) ) {
            wp_send_json_error( 'Security check failed' );
            exit;
        }

        global $wpdb;
        $id = isset( $_POST['unterkunft_id'] ) ? intval( $_POST['unterkunft_id'] ) : 0;
        if ( $id <= 0 ) {
            wp_send_json_error( 'Invalid ID' );
            exit;
        }

        // Zugehörige Daten löschen
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->delete( $wpdb->prefix . 'simpbook_unterkunft_zimmer', [ 'unterkunft_id' => $id ], [ '%d' ] );
        $wpdb->delete( $wpdb->prefix . 'simpbook_unterkunft_tag_zuordnungen', [ 'unterkunft_id' => $id ], [ '%d' ] );
        $wpdb->delete( $wpdb->prefix . 'simpbook_verfuegbarkeit', [ 'unterkunft_id' => $id ], [ '%d' ] );
        $wpdb->delete( $wpdb->prefix . 'simpbook_unterkuenfte', [ 'id' => $id ], [ '%d' ] );

        wp_send_json_success();
        exit;
    }

    /**
     * AJAX: Tag speichern.
     */
    public function ajax_tag_speichern() {
        if ( ! isset( $_POST['simpbook_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simpbook_nonce'] ) ), 'simpbook_tag_speichern' ) ) {
            wp_send_json_error( 'Security check failed' );
            exit;
        }

        global $wpdb;
        $id   = isset( $_POST['tag_id'] ) ? intval( $_POST['tag_id'] ) : 0;
        $name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '';
        $slug = sanitize_title( $name );
        $farbe = isset( $_POST['farbe'] ) ? sanitize_hex_color( wp_unslash( $_POST['farbe'] ) ) : '#2271b1';
        $icon  = isset( $_POST['icon'] ) ? sanitize_text_field( wp_unslash( $_POST['icon'] ) ) : 'home';

        if ( empty( $name ) ) {
            wp_send_json_error( __( 'Name ist erforderlich.', 'simple-appointment-booking' ) );
            exit;
        }

        $daten = [ 'name' => $name, 'slug' => $slug, 'farbe' => $farbe, 'icon' => $icon ];

        if ( $id > 0 ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->update( $wpdb->prefix . 'simpbook_unterkunft_tags', $daten, [ 'id' => $id ], null, [ '%d' ] );
        } else {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
            $wpdb->insert( $wpdb->prefix . 'simpbook_unterkunft_tags', $daten );
            $id = $wpdb->insert_id;
        }

        wp_send_json_success( [ 'id' => $id ] );
        exit;
    }

    /**
     * AJAX: Tag löschen.
     */
    public function ajax_tag_loeschen() {
        if ( ! isset( $_POST['simpbook_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simpbook_nonce'] ) ), 'simpbook_tag_loeschen' ) ) {
            wp_send_json_error( 'Security check failed' );
            exit;
        }

        global $wpdb;
        $id = isset( $_POST['tag_id'] ) ? intval( $_POST['tag_id'] ) : 0;
        if ( $id <= 0 ) {
            wp_send_json_error( 'Invalid ID' );
            exit;
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->delete( $wpdb->prefix . 'simpbook_unterkunft_tag_zuordnungen', [ 'tag_id' => $id ], [ '%d' ] );
        $wpdb->delete( $wpdb->prefix . 'simpbook_unterkunft_tags', [ 'id' => $id ], [ '%d' ] );

        wp_send_json_success();
        exit;
    }

    /**
     * AJAX: Zimmer speichern (anlegen oder bearbeiten).
     */
    public function ajax_zimmer_speichern() {
        if ( ! isset( $_POST['simpbook_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simpbook_nonce'] ) ), 'simpbook_zimmer_speichern' ) ) {
            wp_send_json_error( __( 'Sicherheitsprüfung fehlgeschlagen.', 'simple-appointment-booking' ) );
            exit;
        }
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( __( 'Keine Berechtigung.', 'simple-appointment-booking' ) );
            exit;
        }

        global $wpdb;
        $zimmer_id     = isset( $_POST['zimmer_id'] ) ? intval( $_POST['zimmer_id'] ) : 0;
        $unterkunft_id = isset( $_POST['unterkunft_id'] ) ? intval( $_POST['unterkunft_id'] ) : 0;

        if ( $unterkunft_id <= 0 ) {
            wp_send_json_error( __( 'Keine gültige Unterkunft angegeben.', 'simple-appointment-booking' ) );
            exit;
        }

        $name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '';
        if ( empty( $name ) ) {
            wp_send_json_error( __( 'Bitte einen Zimmer-Namen eingeben.', 'simple-appointment-booking' ) );
            exit;
        }

        $daten = [
            'unterkunft_id'      => $unterkunft_id,
            'name'               => $name,
            'beschreibung'       => isset( $_POST['beschreibung'] ) ? sanitize_textarea_field( wp_unslash( $_POST['beschreibung'] ) ) : '',
            'zimmer_typ'         => isset( $_POST['zimmer_typ'] ) ? sanitize_text_field( wp_unslash( $_POST['zimmer_typ'] ) ) : 'doppelzimmer',
            'preis_pro_nacht'    => isset( $_POST['preis_pro_nacht'] ) && '' !== $_POST['preis_pro_nacht'] ? floatval( $_POST['preis_pro_nacht'] ) : null,
            'preis_pro_woche'    => isset( $_POST['preis_pro_woche'] ) && '' !== $_POST['preis_pro_woche'] ? floatval( $_POST['preis_pro_woche'] ) : null,
            'rabatt_preis_nacht' => isset( $_POST['rabatt_preis_nacht'] ) && '' !== $_POST['rabatt_preis_nacht'] ? floatval( $_POST['rabatt_preis_nacht'] ) : null,
            'max_gaeste'         => isset( $_POST['max_gaeste'] ) && '' !== $_POST['max_gaeste'] ? intval( $_POST['max_gaeste'] ) : 2,
            'schlafplaetze'      => isset( $_POST['schlafplaetze'] ) && '' !== $_POST['schlafplaetze'] ? intval( $_POST['schlafplaetze'] ) : 2,
            'betten_beschreibung' => isset( $_POST['betten_beschreibung'] ) ? sanitize_text_field( wp_unslash( $_POST['betten_beschreibung'] ) ) : '',
            'zimmergroesse'      => isset( $_POST['zimmergroesse'] ) && '' !== $_POST['zimmergroesse'] ? floatval( $_POST['zimmergroesse'] ) : null,
            'anzahl_verfuegbar'  => isset( $_POST['anzahl_verfuegbar'] ) && '' !== $_POST['anzahl_verfuegbar'] ? intval( $_POST['anzahl_verfuegbar'] ) : 1,
            'aktiv'              => isset( $_POST['aktiv'] ) ? intval( $_POST['aktiv'] ) : 1,
            'sortierung'         => isset( $_POST['sortierung'] ) ? intval( $_POST['sortierung'] ) : 0,
        ];

        // Ausstattung als JSON
        if ( isset( $_POST['ausstattung'] ) && is_array( $_POST['ausstattung'] ) ) {
            $daten['ausstattung_json'] = wp_json_encode( array_map( 'sanitize_text_field', wp_unslash( $_POST['ausstattung'] ) ) );
        }

        // Bilder als JSON
        if ( isset( $_POST['bilder_ids'] ) ) {
            $bilder = array_filter( array_map( 'intval', explode( ',', sanitize_text_field( wp_unslash( $_POST['bilder_ids'] ) ) ) ) );
            $daten['bilder_json'] = wp_json_encode( $bilder );
        }

        // Titelbild
        if ( isset( $_POST['titelbild_id'] ) && '' !== $_POST['titelbild_id'] ) {
            $daten['titelbild_id'] = intval( $_POST['titelbild_id'] );
        }

        if ( $zimmer_id > 0 ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $result = $wpdb->update( $wpdb->prefix . 'simpbook_unterkunft_zimmer', $daten, [ 'id' => $zimmer_id, 'unterkunft_id' => $unterkunft_id ], null, [ '%d', '%d' ] );
        } else {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
            $result = $wpdb->insert( $wpdb->prefix . 'simpbook_unterkunft_zimmer', $daten );
            $zimmer_id = $wpdb->insert_id;
        }

        if ( false === $result ) {
            wp_send_json_error( __( 'Fehler beim Speichern: ', 'simple-appointment-booking' ) . $wpdb->last_error );
            exit;
        }

        // Zimmer-Daten zurückgeben für Live-Update
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $zimmer = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}simpbook_unterkunft_zimmer WHERE id = %d",
            $zimmer_id
        ) );

        wp_send_json_success( [
            'id'      => $zimmer_id,
            'zimmer'  => $zimmer,
            'message' => __( 'Zimmer gespeichert.', 'simple-appointment-booking' ),
        ] );
        exit;
    }

    /**
     * AJAX: Zimmer löschen.
     */
    public function ajax_zimmer_loeschen() {
        if ( ! isset( $_POST['simpbook_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simpbook_nonce'] ) ), 'simpbook_zimmer_loeschen' ) ) {
            wp_send_json_error( __( 'Sicherheitsprüfung fehlgeschlagen.', 'simple-appointment-booking' ) );
            exit;
        }
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( __( 'Keine Berechtigung.', 'simple-appointment-booking' ) );
            exit;
        }

        global $wpdb;
        $zimmer_id     = isset( $_POST['zimmer_id'] ) ? intval( $_POST['zimmer_id'] ) : 0;
        $unterkunft_id = isset( $_POST['unterkunft_id'] ) ? intval( $_POST['unterkunft_id'] ) : 0;

        if ( $zimmer_id <= 0 ) {
            wp_send_json_error( __( 'Ungültige Zimmer-ID.', 'simple-appointment-booking' ) );
            exit;
        }

        // Prüfe ob Buchungen für dieses Zimmer existieren
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $buchungen = $wpdb->get_var( $wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}simpbook_aufenthalte WHERE zimmer_id = %d AND storniert = 0",
            $zimmer_id
        ) );
        if ( $buchungen > 0 ) {
            wp_send_json_error( __( 'Dieses Zimmer kann nicht gelöscht werden, da bereits Buchungen existieren. Deaktivieren Sie es stattdessen.', 'simple-appointment-booking' ) );
            exit;
        }

        // Verfügbarkeiten für dieses Zimmer löschen
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->delete( $wpdb->prefix . 'simpbook_verfuegbarkeit', [ 'zimmer_id' => $zimmer_id ], [ '%d' ] );
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->delete( $wpdb->prefix . 'simpbook_unterkunft_zimmer', [ 'id' => $zimmer_id, 'unterkunft_id' => $unterkunft_id ], [ '%d', '%d' ] );

        wp_send_json_success( [ 'message' => __( 'Zimmer gelöscht.', 'simple-appointment-booking' ) ] );
        exit;
    }

    /**
     * AJAX: Verfügbarkeit prüfen (Frontend).
     */
    public function ajax_verfuegbarkeit_pruefen() {
        check_ajax_referer( 'simpbook_vermietung_nonce', 'simpbook_nonce' );

        $unterkunft_id = isset( $_POST['unterkunft_id'] ) ? intval( $_POST['unterkunft_id'] ) : 0;
        $zimmer_id     = isset( $_POST['zimmer_id'] ) ? intval( $_POST['zimmer_id'] ) : 0;
        $checkin       = isset( $_POST['checkin'] ) ? sanitize_text_field( wp_unslash( $_POST['checkin'] ) ) : '';
        $checkout      = isset( $_POST['checkout'] ) ? sanitize_text_field( wp_unslash( $_POST['checkout'] ) ) : '';

        if ( $unterkunft_id <= 0 || empty( $checkin ) || empty( $checkout ) ) {
            wp_send_json_error( __( 'Bitte alle Felder ausfüllen.', 'simple-appointment-booking' ) );
            exit;
        }

        $verfuegbar = self::ist_verfuegbar( $unterkunft_id, $zimmer_id, $checkin, $checkout );
        wp_send_json_success( [ 'verfuegbar' => $verfuegbar ] );
        exit;
    }

    /**
     * AJAX: Preis berechnen (Frontend).
     */
    public function ajax_preis_berechnen() {
        check_ajax_referer( 'simpbook_vermietung_nonce', 'simpbook_nonce' );

        $unterkunft_id = isset( $_POST['unterkunft_id'] ) ? intval( $_POST['unterkunft_id'] ) : 0;
        $zimmer_id     = isset( $_POST['zimmer_id'] ) ? intval( $_POST['zimmer_id'] ) : 0;
        $checkin       = isset( $_POST['checkin'] ) ? sanitize_text_field( wp_unslash( $_POST['checkin'] ) ) : '';
        $checkout      = isset( $_POST['checkout'] ) ? sanitize_text_field( wp_unslash( $_POST['checkout'] ) ) : '';
        $rabatt_code   = isset( $_POST['rabatt_code'] ) ? sanitize_text_field( wp_unslash( $_POST['rabatt_code'] ) ) : '';

        $preis = self::preis_berechnen( $unterkunft_id, $zimmer_id, $checkin, $checkout, $rabatt_code );
        if ( $preis === null ) {
            wp_send_json_error( __( 'Preisberechnung nicht möglich.', 'simple-appointment-booking' ) );
            exit;
        }

        wp_send_json_success( $preis );
        exit;
    }

    /**
     * AJAX: Aufenthalt buchen (Frontend).
     */
    public function ajax_aufenthalt_buchen() {
        check_ajax_referer( 'simpbook_vermietung_nonce', 'simpbook_nonce' );

        global $wpdb;

        $unterkunft_id = isset( $_POST['unterkunft_id'] ) ? intval( $_POST['unterkunft_id'] ) : 0;
        $zimmer_id     = isset( $_POST['zimmer_id'] ) ? intval( $_POST['zimmer_id'] ) : 0;
        $checkin       = isset( $_POST['checkin'] ) ? sanitize_text_field( wp_unslash( $_POST['checkin'] ) ) : '';
        $checkout      = isset( $_POST['checkout'] ) ? sanitize_text_field( wp_unslash( $_POST['checkout'] ) ) : '';
        $gast_name     = isset( $_POST['gast_name'] ) ? sanitize_text_field( wp_unslash( $_POST['gast_name'] ) ) : '';
        $gast_email    = isset( $_POST['gast_email'] ) ? sanitize_email( wp_unslash( $_POST['gast_email'] ) ) : '';
        $gast_telefon  = isset( $_POST['gast_telefon'] ) ? sanitize_text_field( wp_unslash( $_POST['gast_telefon'] ) ) : '';
        $anzahl_gaeste = isset( $_POST['anzahl_gaeste'] ) ? intval( $_POST['anzahl_gaeste'] ) : 1;
        $nachricht     = isset( $_POST['nachricht'] ) ? sanitize_textarea_field( wp_unslash( $_POST['nachricht'] ) ) : '';
        $rabatt_code   = isset( $_POST['rabatt_code'] ) ? sanitize_text_field( wp_unslash( $_POST['rabatt_code'] ) ) : '';

        // Validierung
        if ( $unterkunft_id <= 0 || empty( $checkin ) || empty( $checkout ) || empty( $gast_name ) || empty( $gast_email ) ) {
            wp_send_json_error( __( 'Bitte alle Pflichtfelder ausfüllen.', 'simple-appointment-booking' ) );
            exit;
        }

        // Verfügbarkeit nochmal prüfen
        if ( ! self::ist_verfuegbar( $unterkunft_id, $zimmer_id, $checkin, $checkout ) ) {
            wp_send_json_error( __( 'Der gewählte Zeitraum ist leider nicht mehr verfügbar.', 'simple-appointment-booking' ) );
            exit;
        }

        // Min/Max Nächte prüfen
        $unterkunft = self::get_unterkunft( $unterkunft_id );
        $checkin_date  = new DateTime( $checkin );
        $checkout_date = new DateTime( $checkout );
        $naechte       = (int) $checkin_date->diff( $checkout_date )->days;

        $min_naechte = $unterkunft->min_naechte ?? (int) get_option( 'simpbook_vermietung_standard_min_naechte', 1 );
        $max_naechte = $unterkunft->max_naechte ?? (int) get_option( 'simpbook_vermietung_standard_max_naechte', 365 );

        if ( $naechte < $min_naechte ) {
            wp_send_json_error( sprintf( __( 'Mindestaufenthalt: %d Nächte.', 'simple-appointment-booking' ), $min_naechte ) );
            exit;
        }
        if ( $naechte > $max_naechte ) {
            wp_send_json_error( sprintf( __( 'Maximaler Aufenthalt: %d Nächte.', 'simple-appointment-booking' ), $max_naechte ) );
            exit;
        }

        // Preis berechnen
        $preis = self::preis_berechnen( $unterkunft_id, $zimmer_id, $checkin, $checkout, $rabatt_code );

        // Auto-Bestätigung
        $auto_bestaetigung = get_option( 'simpbook_vermietung_auto_bestaetigung', '0' ) === '1';
        $initial_status    = $auto_bestaetigung ? 'BESTÄTIGT' : 'AUSSTEHEND';

        // Stornierungs-Token generieren
        $stornierungs_token = wp_generate_password( 32, false );

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
        $erfolg = $wpdb->insert( $wpdb->prefix . 'simpbook_aufenthalte', [
            'unterkunft_id'           => $unterkunft_id,
            'zimmer_id'               => $zimmer_id > 0 ? $zimmer_id : null,
            'gast_name'               => $gast_name,
            'gast_email'              => $gast_email,
            'gast_telefon'            => $gast_telefon,
            'anzahl_gaeste'           => $anzahl_gaeste,
            'nachricht'               => $nachricht,
            'checkin_datum'           => $checkin,
            'checkout_datum'          => $checkout,
            'anzahl_naechte'          => $naechte,
            'preis_pro_nacht'         => $preis ? $preis['preis_pro_nacht'] : null,
            'reinigungsgebuehr'       => $preis ? $preis['reinigungsgebuehr'] : null,
            'kaution'                 => $preis ? $preis['kaution'] : null,
            'rabatt_code_angewendet'  => ! empty( $rabatt_code ) ? $rabatt_code : null,
            'rabatt_betrag'           => $preis ? $preis['rabatt_betrag'] : null,
            'gesamtpreis'             => $preis ? $preis['gesamtpreis'] : null,
            'status'                  => $initial_status,
            'storniert'               => 0,
            'stornierungs_token'      => $stornierungs_token,
            'erinnerung_gesendet'     => 0,
        ] );

        if ( $erfolg ) {
            $aufenthalt_id = $wpdb->insert_id;

            // Hook: Buchung (Aufenthalt) erstellt
            do_action( 'simpbook_buchung_erstellt', $aufenthalt_id, [
                'modus'         => 'ferienhaeuser',
                'tabelle'       => 'simpbook_aufenthalte',
                'unterkunft_id' => $unterkunft_id,
                'zimmer_id'     => $zimmer_id,
                'kunde_name'    => $gast_name,
                'kunde_email'   => $gast_email,
                'status'        => $initial_status,
                'betrag'        => $preis ? $preis['gesamtpreis'] : 0,
            ] );

            wp_send_json_success( [
                'aufenthalt_id' => $aufenthalt_id,
                'status'        => $initial_status,
                'message'       => $auto_bestaetigung
                    ? __( 'Ihre Buchung wurde bestätigt!', 'simple-appointment-booking' )
                    : __( 'Ihre Buchungsanfrage wurde erhalten. Sie erhalten eine Bestätigung per E-Mail.', 'simple-appointment-booking' ),
            ] );
        } else {
            wp_send_json_error( __( 'Fehler beim Speichern der Buchung.', 'simple-appointment-booking' ) );
        }
        exit;
    }

    /**
     * AJAX: Buchungsstatus ändern (Backend).
     */
    public function ajax_buchung_status_aendern() {
        if ( ! isset( $_POST['simpbook_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simpbook_nonce'] ) ), 'simpbook_vermietung_status' ) ) {
            wp_send_json_error( 'Security check failed' );
            exit;
        }

        global $wpdb;
        $id     = isset( $_POST['aufenthalt_id'] ) ? intval( $_POST['aufenthalt_id'] ) : 0;
        $status = isset( $_POST['status'] ) ? sanitize_text_field( wp_unslash( $_POST['status'] ) ) : '';

        $erlaubte_status = [ 'AUSSTEHEND', 'BESTÄTIGT', 'BESTAETIGT', 'ABGELEHNT', 'STORNIERT', 'EINGECHECKT', 'AUSGECHECKT' ];
        if ( $id <= 0 || ! in_array( $status, $erlaubte_status, true ) ) {
            wp_send_json_error( 'Ungültiger Status' );
            exit;
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->update(
            $wpdb->prefix . 'simpbook_aufenthalte',
            [ 'status' => $status, 'status_geaendert_datum' => current_time( 'mysql' ) ],
            [ 'id' => $id ],
            [ '%s', '%s' ],
            [ '%d' ]
        );

        // Hook
        if ( $status === 'BESTÄTIGT' || $status === 'BESTAETIGT' ) {
            do_action( 'simpbook_buchung_bestaetigt', $id, [
                'modus'  => 'ferienhaeuser',
                'tabelle' => 'simpbook_aufenthalte',
            ] );
        }

        wp_send_json_success( [ 'message' => __( 'Status aktualisiert.', 'simple-appointment-booking' ) ] );
        exit;
    }

    /**
     * AJAX: Verfügbarkeit blockieren (Backend).
     */
    public function ajax_verfuegbarkeit_blockieren() {
        if ( ! isset( $_POST['simpbook_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simpbook_nonce'] ) ), 'simpbook_vermietung_block' ) ) {
            wp_send_json_error( 'Security check failed' );
            exit;
        }

        global $wpdb;
        $unterkunft_id = isset( $_POST['unterkunft_id'] ) ? intval( $_POST['unterkunft_id'] ) : 0;
        $zimmer_id     = isset( $_POST['zimmer_id'] ) ? intval( $_POST['zimmer_id'] ) : 0;
        $typ           = isset( $_POST['typ'] ) ? sanitize_text_field( wp_unslash( $_POST['typ'] ) ) : 'blockiert';
        $datum_von     = isset( $_POST['datum_von'] ) ? sanitize_text_field( wp_unslash( $_POST['datum_von'] ) ) : '';
        $datum_bis     = isset( $_POST['datum_bis'] ) ? sanitize_text_field( wp_unslash( $_POST['datum_bis'] ) ) : '';

        if ( $unterkunft_id <= 0 || empty( $datum_von ) || empty( $datum_bis ) ) {
            wp_send_json_error( __( 'Bitte alle Felder ausfüllen.', 'simple-appointment-booking' ) );
            exit;
        }

        $daten = [
            'unterkunft_id'  => $unterkunft_id,
            'zimmer_id'      => $zimmer_id > 0 ? $zimmer_id : null,
            'typ'            => in_array( $typ, [ 'blockiert', 'saisonpreis' ], true ) ? $typ : 'blockiert',
            'datum_von'      => $datum_von,
            'datum_bis'      => $datum_bis,
        ];

        if ( $typ === 'saisonpreis' ) {
            $daten['preis_pro_nacht'] = isset( $_POST['preis_pro_nacht'] ) ? floatval( $_POST['preis_pro_nacht'] ) : null;
            $daten['bezeichnung']     = isset( $_POST['bezeichnung'] ) ? sanitize_text_field( wp_unslash( $_POST['bezeichnung'] ) ) : '';
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
        $wpdb->insert( $wpdb->prefix . 'simpbook_verfuegbarkeit', $daten );

        wp_send_json_success( [ 'id' => $wpdb->insert_id ] );
        exit;
    }

    /**
     * AJAX: Verfügbarkeitskalender-Daten für Frontend.
     */
    public function ajax_verfuegbarkeit_kalender() {
        $unterkunft_id = isset( $_POST['unterkunft_id'] ) ? intval( $_POST['unterkunft_id'] ) : 0;
        $zimmer_id     = isset( $_POST['zimmer_id'] ) ? intval( $_POST['zimmer_id'] ) : 0;
        $monat         = isset( $_POST['monat'] ) ? intval( $_POST['monat'] ) : (int) wp_date( 'm' );
        $jahr          = isset( $_POST['jahr'] ) ? intval( $_POST['jahr'] ) : (int) wp_date( 'Y' );

        if ( $unterkunft_id <= 0 ) {
            wp_send_json_error( 'Invalid ID' );
            exit;
        }

        global $wpdb;
        $unterkunft = self::get_unterkunft( $unterkunft_id );
        $erster_tag = sprintf( '%04d-%02d-01', $jahr, $monat );
        $letzter_tag = wp_date( 'Y-m-t', strtotime( $erster_tag ) );

        $tage = [];
        $current = new DateTime( $erster_tag );
        $end     = new DateTime( $letzter_tag );
        $end->modify( '+1 day' );

        while ( $current < $end ) {
            $datum_str = $current->format( 'Y-m-d' );

            // Prüfe Buchungszeitraum
            if ( $unterkunft->buchbar_von && $datum_str < $unterkunft->buchbar_von ) {
                $tage[ $datum_str ] = 'nicht_buchbar';
                $current->modify( '+1 day' );
                continue;
            }
            if ( $unterkunft->buchbar_bis && $datum_str > $unterkunft->buchbar_bis ) {
                $tage[ $datum_str ] = 'nicht_buchbar';
                $current->modify( '+1 day' );
                continue;
            }

            // Prüfe blockiert
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $block = $wpdb->get_var( $wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->prefix}simpbook_verfuegbarkeit
                 WHERE unterkunft_id = %d AND typ = 'blockiert'
                 AND (zimmer_id IS NULL OR zimmer_id = %d)
                 AND datum_von <= %s AND datum_bis >= %s",
                $unterkunft_id, $zimmer_id, $datum_str, $datum_str
            ) );
            if ( $block > 0 ) {
                $tage[ $datum_str ] = 'blockiert';
                $current->modify( '+1 day' );
                continue;
            }

            // Prüfe Buchungen
            $zimmer_where = $zimmer_id > 0 ? $wpdb->prepare( ' AND zimmer_id = %d', $zimmer_id ) : '';
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
            $bestaetigt = $wpdb->get_var( $wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->prefix}simpbook_aufenthalte
                 WHERE unterkunft_id = %d {$zimmer_where}
                 AND storniert = 0 AND status IN ('BESTÄTIGT','BESTAETIGT','EINGECHECKT')
                 AND checkin_datum <= %s AND checkout_datum > %s",
                $unterkunft_id, $datum_str, $datum_str
            ) );
            if ( $bestaetigt > 0 ) {
                $tage[ $datum_str ] = 'belegt';
                $current->modify( '+1 day' );
                continue;
            }

            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
            $ausstehend = $wpdb->get_var( $wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->prefix}simpbook_aufenthalte
                 WHERE unterkunft_id = %d {$zimmer_where}
                 AND storniert = 0 AND status = 'AUSSTEHEND'
                 AND checkin_datum <= %s AND checkout_datum > %s",
                $unterkunft_id, $datum_str, $datum_str
            ) );
            if ( $ausstehend > 0 ) {
                $tage[ $datum_str ] = 'anfrage';
                $current->modify( '+1 day' );
                continue;
            }

            $tage[ $datum_str ] = 'verfuegbar';
            $current->modify( '+1 day' );
        }

        wp_send_json_success( [
            'buchbar_von' => $unterkunft->buchbar_von,
            'buchbar_bis' => $unterkunft->buchbar_bis,
            'tage'        => $tage,
        ] );
        exit;
    }

    // =========================================================================
    // SHORTCODES
    // =========================================================================

    /**
     * Shortcode: [simpbook_unterkuenfte] — Übersichts-Grid.
     */
    public function shortcode_unterkuenfte_grid( $atts ) {
        $atts = shortcode_atts( [
            'limit'      => 9,
            'typ'        => '',
            'ort'        => '',
            'tag'        => '',
            'sortierung' => 'neueste',
            'spalten'    => 3,
            'filter'     => 'nein',
        ], $atts, 'simpbook_unterkuenfte' );

        $args = [
            'status'   => 'aktiv',
            'limit'    => (int) $atts['limit'],
            'order_by' => $atts['sortierung'] === 'neueste' ? 'erstellt_am' : 'sortierung',
            'order'    => $atts['sortierung'] === 'neueste' ? 'DESC' : 'ASC',
        ];

        $unterkuenfte = self::get_unterkuenfte( $args );

        ob_start();
        $template = plugin_dir_path( dirname( __FILE__ ) ) . 'templates/vermietung-grid.php';
        if ( file_exists( $template ) ) {
            include $template;
        } else {
            echo '<p>' . esc_html__( 'Template nicht gefunden.', 'simple-appointment-booking' ) . '</p>';
        }
        return ob_get_clean();
    }

    /**
     * Shortcode: [simpbook_unterkunft id="X"] — Einzelansicht.
     */
    public function shortcode_unterkunft_detail( $atts ) {
        $atts = shortcode_atts( [
            'id' => 0,
        ], $atts, 'simpbook_unterkunft' );

        // ID aus Shortcode oder Query-Parameter
        $id = (int) $atts['id'];
        if ( $id <= 0 ) {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $id = isset( $_GET['simpbook_unterkunft_id'] ) ? intval( $_GET['simpbook_unterkunft_id'] ) : 0;
        }

        if ( $id <= 0 ) {
            // Kein ID angegeben → Fallback auf Grid-Ansicht
            return $this->shortcode_unterkuenfte_grid( $atts );
        }

        $unterkunft = self::get_unterkunft( $id );
        if ( ! $unterkunft || $unterkunft->status !== 'aktiv' ) {
            return '<p>' . esc_html__( 'Diese Unterkunft ist derzeit nicht verfügbar.', 'simple-appointment-booking' ) . '</p>';
        }

        $zimmer = self::get_zimmer( $id );
        $tags   = self::get_unterkunft_tags( $id );

        ob_start();
        $template = plugin_dir_path( dirname( __FILE__ ) ) . 'templates/vermietung-detail.php';
        if ( file_exists( $template ) ) {
            include $template;
        } else {
            echo '<p>' . esc_html__( 'Template nicht gefunden.', 'simple-appointment-booking' ) . '</p>';
        }
        return ob_get_clean();
    }

    // =========================================================================
    // ASSETS
    // =========================================================================

    /**
     * Admin-seitige Assets für Vermietung laden.
     */
    public function admin_assets_laden( $hook_suffix ) {
        $modus = get_option( 'simpbook_plugin_modus', 'dienstleistungen' );
        if ( $modus !== 'ferienhaeuser' ) {
            return;
        }

        // Nur auf PocketBooking-Seiten laden
        if ( strpos( $hook_suffix, 'simpbook' ) === false ) {
            return;
        }

        wp_enqueue_style(
            'simpbook-vermietung-admin',
            SIMPBOOK_PLUGIN_URL . 'css/vermietung-admin.css',
            [],
            SIMPBOOK_VERSION
        );
        wp_enqueue_script(
            'simpbook-vermietung-admin',
            SIMPBOOK_PLUGIN_URL . 'js/vermietung-admin.js',
            [ 'jquery' ],
            SIMPBOOK_VERSION,
            true
        );
        wp_localize_script( 'simpbook-vermietung-admin', 'simpbookVermietung', [
            'ajax_url'      => admin_url( 'admin-ajax.php' ),
            'nonce'         => wp_create_nonce( 'simpbook_unterkunft_speichern' ),
            'zimmer_nonce'  => wp_create_nonce( 'simpbook_zimmer_speichern' ),
            'zimmer_delete_nonce' => wp_create_nonce( 'simpbook_zimmer_loeschen' ),
            'i18n'     => [
                'confirm_delete'        => __( 'Wirklich löschen?', 'simple-appointment-booking' ),
                'confirm_delete_zimmer' => __( 'Dieses Zimmer wirklich löschen?', 'simple-appointment-booking' ),
                'saved'                 => __( 'Gespeichert.', 'simple-appointment-booking' ),
                'error'                 => __( 'Fehler beim Speichern.', 'simple-appointment-booking' ),
                'zimmer_name_required'  => __( 'Bitte geben Sie einen Zimmer-Namen ein.', 'simple-appointment-booking' ),
            ],
        ] );
    }

    /**
     * Frontend-Assets für Vermietung laden.
     */
    public function frontend_assets_laden() {
        // Nur laden wenn Vermietungs-Shortcodes auf der Seite sind
        global $post;
        if ( ! is_a( $post, 'WP_Post' ) ) {
            return;
        }

        $hat_shortcode = has_shortcode( $post->post_content, 'simpbook_unterkuenfte' )
                      || has_shortcode( $post->post_content, 'simpbook_unterkunft' );

        if ( ! $hat_shortcode ) {
            return;
        }

        wp_enqueue_style(
            'simpbook-vermietung-frontend',
            SIMPBOOK_PLUGIN_URL . 'css/vermietung-frontend.css',
            [],
            SIMPBOOK_VERSION
        );

        // Design-Einstellungen als CSS-Variablen injizieren
        $primary_color       = esc_html( get_option( 'simpbook_button_color', '#2271b1' ) );
        $primary_hover       = esc_html( get_option( 'simpbook_button_hover', '#135e96' ) );
        $button_text_color   = esc_html( get_option( 'simpbook_button_text_color', '#ffffff' ) );
        $button_border_radius = intval( get_option( 'simpbook_button_border_radius', 8 ) );
        $tile_bg             = esc_html( get_option( 'simpbook_tile_background', '#ffffff' ) );
        $tile_text_color     = esc_html( get_option( 'simpbook_tile_text_color', '#333333' ) );
        $tile_border_radius  = intval( get_option( 'simpbook_tile_border_radius', 12 ) );
        $border_radius       = intval( get_option( 'simpbook_border_radius', 8 ) );

        $custom_css = "
            :root {
                --simpbook-primary: {$primary_color};
                --simpbook-primary-hover: {$primary_hover};
                --simpbook-button-color: {$primary_color};
                --simpbook-button-hover: {$primary_hover};
                --simpbook-button-text-color: {$button_text_color};
                --simpbook-button-border-radius: {$button_border_radius}px;
                --simpbook-tile-bg: {$tile_bg};
                --simpbook-tile-text-color: {$tile_text_color};
                --simpbook-tile-border-radius: {$tile_border_radius}px;
                --simpbook-border-radius: {$border_radius}px;
            }
        ";
        wp_add_inline_style( 'simpbook-vermietung-frontend', $custom_css );
        wp_enqueue_script(
            'simpbook-vermietung-frontend',
            SIMPBOOK_PLUGIN_URL . 'js/vermietung-frontend.js',
            [],
            SIMPBOOK_VERSION,
            true
        );
        wp_localize_script( 'simpbook-vermietung-frontend', 'simpbookVermietungFrontend', [
            'ajax_url' => admin_url( 'admin-ajax.php' ),
            'nonce'    => wp_create_nonce( 'simpbook_vermietung_nonce' ),
            'i18n'     => [
                'verfuegbar'     => __( 'Verfügbar', 'simple-appointment-booking' ),
                'belegt'         => __( 'Belegt', 'simple-appointment-booking' ),
                'nicht_buchbar'  => __( 'Nicht buchbar', 'simple-appointment-booking' ),
                'anfrage'        => __( 'Anfrage ausstehend', 'simple-appointment-booking' ),
                'buchung_fehler' => __( 'Fehler bei der Buchung.', 'simple-appointment-booking' ),
            ],
        ] );
    }
}

// =========================================================================
// GLOBALE HELPER-FUNKTIONEN (für Zugriff ohne Klassen-Prefix)
// =========================================================================

/**
 * Prüft ob Vermietungs-Zugang besteht (Lizenz oder Trial).
 */
function simpbook_vermietung_hat_zugang() {
    return Simpbook_Vermietung::hat_zugang();
}

/**
 * Prüft ob Vermietungs-Lizenz aktiv ist.
 */
function simpbook_vermietung_lizenz_aktiv() {
    return Simpbook_Vermietung::lizenz_aktiv();
}

/**
 * Prüft ob Vermietungs-Trial aktiv ist.
 */
function simpbook_vermietung_trial_aktiv() {
    return Simpbook_Vermietung::trial_aktiv();
}
