<?php
if (!defined('ABSPATH')) { exit; }

class WAE_Frontend {
    public static function init() {
        add_action('wp_head', array(__CLASS__, 'output_selected_page_schema'), 30);
        add_action('wp_footer', array(__CLASS__, 'output_selected_page_schema_footer_fallback'), 5);
        add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueue_assets'));
        add_shortcode('wedding_ai_trauredner_landingpage', array(__CLASS__, 'shortcode_trauredner_landingpage'));
        add_action('init', array(__CLASS__, 'maybe_add_sitemap_rewrite'));
        add_action('template_redirect', array(__CLASS__, 'maybe_output_simple_sitemap'));
    }




    public static function maybe_add_sitemap_rewrite() {
        $o = self::opts();
        if (!empty($o['simple_sitemap_enabled']) && $o['simple_sitemap_enabled'] === '1') {
            add_rewrite_rule('^wae-sitemap\.xml$', 'index.php?wae_sitemap=1', 'top');
            add_filter('query_vars', function($vars) { $vars[] = 'wae_sitemap'; return $vars; });
        }
    }

    public static function maybe_output_simple_sitemap() {
        if ((string) get_query_var('wae_sitemap') !== '1') { return; }
        $o = self::opts();
        if (empty($o['simple_sitemap_enabled']) || $o['simple_sitemap_enabled'] !== '1') { status_header(404); return; }
        status_header(200);
        header('Content-Type: application/xml; charset=' . get_option('blog_charset'));
        $urls = array(home_url('/'));
        $wedding = self::selected_wedding_page_url($o);
        if ($wedding) { $urls[] = $wedding; }
        if (!empty($o['generated_landingpage_id'])) {
            $lp = get_permalink((int)$o['generated_landingpage_id']);
            if ($lp) { $urls[] = $lp; }
        }
        $urls = array_values(array_unique(array_filter($urls)));
        echo '<?xml version="1.0" encoding="UTF-8"?>' . "
";
        echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "
";
        foreach ($urls as $url) {
            echo '  <url><loc>' . esc_url($url) . '</loc><lastmod>' . esc_html(gmdate('c')) . '</lastmod></url>' . "
";
        }
        echo '</urlset>';
        exit;
    }

    public static function enqueue_assets() {
        wp_enqueue_style('wae-frontend', WAE_PLUGIN_URL . 'assets/frontend.css', array(), WAE_VERSION);
        wp_enqueue_script('wae-frontend', WAE_PLUGIN_URL . 'assets/frontend.js', array(), WAE_VERSION, true);
    }

    private static function opts() {
        return wp_parse_args(get_option('wae_options', array()), array(
            'rooms' => array(),
            'matching_shape' => 'rounded',
            'visitor_tone' => 'du',
            'country' => 'Deutschland',
        ));
    }


    private static function normalize_geo_string($value) {
        $value = trim((string)$value);
        $value = str_replace(array('ä','ö','ü','Ä','Ö','Ü','ß'), array('ae','oe','ue','ae','oe','ue','ss'), $value);
        $value = function_exists('mb_strtolower') ? mb_strtolower($value, 'UTF-8') : strtolower($value);
        $value = preg_replace('/\s+/', ' ', $value);
        return trim($value);
    }

    private static function geocode_location($zip, $city) {
        $zip = trim((string)$zip);
        $city = trim((string)$city);
        if ($zip === '' && $city === '') { return null; }
        $index_file = WAE_PLUGIN_DIR . 'data/ortsdaten-plz-index.json';
        if (!file_exists($index_file)) { return null; }
        $index = json_decode((string) file_get_contents($index_file), true);
        if (!is_array($index)) { return null; }
        $city_l = self::normalize_geo_string($city);
        if ($zip !== '' && !empty($index['zip'][$zip]) && is_array($index['zip'][$zip])) {
            $candidate = $index['zip'][$zip];
            return array('lat'=>$candidate['lat'] ?? '', 'lng'=>$candidate['lng'] ?? '', 'city'=>$candidate['city'] ?? '', 'plz'=>$candidate['plz'] ?? $zip);
        }
        if ($city_l !== '' && !empty($index['city'][$city_l]) && is_array($index['city'][$city_l])) {
            $candidate = $index['city'][$city_l];
            return array('lat'=>$candidate['lat'] ?? '', 'lng'=>$candidate['lng'] ?? '', 'city'=>$candidate['city'] ?? $city, 'plz'=>$candidate['plz'] ?? '');
        }
        return null;
    }

    private static $selected_page_schema_printed = false;

    public static function output_selected_page_schema() {
        self::maybe_output_selected_page_schema('head');
    }

    public static function output_selected_page_schema_footer_fallback() {
        self::maybe_output_selected_page_schema('footer');
    }

    private static function maybe_output_selected_page_schema($position = 'head') {
        if (self::$selected_page_schema_printed) { return; }
        if (!is_singular('page')) { return; }
        $o = self::opts();
        if (!self::is_selected_wedding_page($o)) { return; }
        $schema = self::build_location_schema($o);
        if (!$schema) {
            if (current_user_can('manage_options')) { echo "\n<!-- Wedding AI Engine " . esc_html(WAE_VERSION) . ": Hochzeitsseite erkannt, aber Schema nicht ausgegeben. Es fehlen wahrscheinlich Pflichtdaten wie Locationname. -->\n"; }
            return;
        }
        self::$selected_page_schema_printed = true;
        if (current_user_can('manage_options')) { echo "\n<!-- Wedding AI Engine " . esc_html(WAE_VERSION) . ": Schema auf ausgewählter Hochzeitsseite aktiv (" . esc_html($position) . "). -->\n"; }
        echo "\n" . '<script type="application/ld+json" class="wedding-ai-engine-schema" data-wae-version="' . esc_attr(WAE_VERSION) . '">' . wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . '</script>' . "\n";
    }

    private static function is_selected_wedding_page($o) {
        $current_id = (int) get_queried_object_id();
        $selected_id = self::selected_wedding_page_id($o);
        if ($selected_id && $current_id === $selected_id) { return true; }
        $stored_url = self::selected_wedding_page_url($o);
        if (!$stored_url) { return false; }
        $current_url = $current_id ? get_permalink($current_id) : '';
        if ($current_url && untrailingslashit($current_url) === untrailingslashit($stored_url)) { return true; }
        $request_uri = isset($_SERVER['REQUEST_URI']) ? esc_url_raw(home_url(wp_unslash($_SERVER['REQUEST_URI']))) : '';
        if ($request_uri && untrailingslashit(strtok($request_uri, '?')) === untrailingslashit($stored_url)) { return true; }
        return false;
    }

    private static function selected_wedding_page_id($o) {
        if (!empty($o['wedding_page_id'])) {
            return (int) $o['wedding_page_id'];
        }
        if (!empty($o['wedding_page_url']) && function_exists('url_to_postid')) {
            $post_id = url_to_postid(esc_url_raw($o['wedding_page_url']));
            return $post_id ? (int) $post_id : 0;
        }
        return 0;
    }

    private static function selected_wedding_page_url($o) {
        $post_id = self::selected_wedding_page_id($o);
        if ($post_id) {
            $permalink = get_permalink($post_id);
            if ($permalink) { return $permalink; }
        }
        if (!empty($o['wedding_page_url'])) { return esc_url_raw($o['wedding_page_url']); }
        return '';
    }

    private static function build_location_schema($o) {
        if (empty($o['location_name'])) { return null; }
        $url = !empty($o['website']) ? esc_url_raw($o['website']) : home_url('/');
        $venue = array(
            '@type' => array('EventVenue', 'LocalBusiness'),
            '@id' => trailingslashit($url) . '#wedding-ai-location',
            'name' => sanitize_text_field($o['location_name']),
            'url' => $url,
            'address' => array(
                '@type' => 'PostalAddress',
                'streetAddress' => $o['street'] ?? '',
                'postalCode' => $o['zip'] ?? '',
                'addressLocality' => $o['city'] ?? '',
                'addressCountry' => $o['country'] ?? 'Deutschland',
            ),
            'telephone' => $o['phone'] ?? '',
            'email' => $o['email'] ?? '',
            'amenityFeature' => self::amenities($o),
            'makesOffer' => array(
                '@type' => 'Offer',
                'name' => 'Hochzeiten und freie Trauungen',
                'category' => 'Wedding venue',
            ),
        );
        if (!empty($o['latitude']) && !empty($o['longitude'])) {
            $venue['geo'] = array('@type'=>'GeoCoordinates','latitude'=>(float)$o['latitude'],'longitude'=>(float)$o['longitude']);
        }
        $opening = self::opening_hours_schema($o);
        if (!empty($opening)) { $venue['openingHoursSpecification'] = $opening; }
        if (!empty($o['contact_name']) || !empty($o['phone']) || !empty($o['email'])) {
            $venue['contactPoint'] = array(
                '@type'=>'ContactPoint',
                'contactType'=>'Hochzeiten und Veranstaltungen',
                'name'=>$o['contact_name'] ?? '',
                'telephone'=>$o['phone'] ?? '',
                'email'=>$o['email'] ?? ''
            );
        }
        $same_as = array();
        foreach (array('instagram','facebook','pinterest','youtube','tiktok','linkedin','xing') as $social_key) {
            if (!empty($o[$social_key])) { $same_as[] = esc_url_raw($o[$social_key]); }
        }
        if (!empty($same_as)) { $venue['sameAs'] = $same_as; }
        $places = self::room_schema($o);
        if (!empty($places)) { $venue['containsPlace'] = $places; }
        if (!empty($o['contact_name'])) {
            $venue['employee'] = array('@type'=>'Person','name'=>$o['contact_name'],'jobTitle'=>$o['contact_role'] ?? 'Ansprechpartner');
        }
        $graph = array($venue);
        $faqs = self::build_location_schema_faqs($o);
        if (!empty($faqs)) {
            $main = array();
            foreach ($faqs as $faq) {
                $main[] = array(
                    '@type' => 'Question',
                    'name' => wp_strip_all_tags($faq['q']),
                    'acceptedAnswer' => array('@type' => 'Answer', 'text' => wp_strip_all_tags($faq['a'])),
                );
            }
            $wedding_url = self::selected_wedding_page_url($o);
            $graph[] = array(
                '@type' => 'FAQPage',
                '@id' => ($wedding_url ? trailingslashit($wedding_url) : trailingslashit($url)) . '#wedding-ai-faq',
                'mainEntity' => $main,
                'about' => array('@id' => trailingslashit($url) . '#wedding-ai-location'),
            );
        }
        return array('@context' => 'https://schema.org', '@graph' => $graph);
    }

    private static function opening_hours_schema($o) {
        if (empty($o['opening_hours']) || !is_array($o['opening_hours'])) { return array(); }
        $day_map = array('monday'=>'Monday','tuesday'=>'Tuesday','wednesday'=>'Wednesday','thursday'=>'Thursday','friday'=>'Friday','saturday'=>'Saturday','sunday'=>'Sunday');
        $out = array();
        foreach ($day_map as $key=>$schema_day) {
            $row = isset($o['opening_hours'][$key]) && is_array($o['opening_hours'][$key]) ? $o['opening_hours'][$key] : array();
            if (($row['open'] ?? '') !== '1' || empty($row['from']) || empty($row['to'])) { continue; }
            $out[] = array('@type'=>'OpeningHoursSpecification','dayOfWeek'=>$schema_day,'opens'=>$row['from'],'closes'=>$row['to']);
        }
        return $out;
    }

    private static function room_schema($o) {
        $rooms = !empty($o['rooms']) && is_array($o['rooms']) ? $o['rooms'] : array();
        $out = array();
        foreach ($rooms as $room) {
            if (empty($room['name'])) { continue; }
            $place = array('@type'=>'Place','name'=>$room['name']);
            if (!empty($room['description'])) { $place['description'] = $room['description']; }
            if (!empty($room['capacity_max'])) { $place['maximumAttendeeCapacity'] = (int)$room['capacity_max']; }
            $imgs = array();
            foreach (array('image_1','image_2') as $imgkey) {
                if (!empty($room[$imgkey])) {
                    $url = wp_get_attachment_image_url((int)$room[$imgkey], 'large');
                    if ($url) { $imgs[] = $url; }
                }
            }
            if ($imgs) { $place['image'] = $imgs; }
            $out[] = $place;
        }
        return $out;
    }

    private static function amenities($o) {
        $map = array(
            'free_ceremony_possible' => 'Freie Trauung möglich',
            'registry_office_on_site' => 'Standesamt vor Ort',
            'church_ceremony_possible' => 'Kirchliche Trauung möglich',
            'outdoor_possible' => 'Outdoor-Trauung möglich',
            'indoor_possible' => 'Indoor-Trauung möglich',
            'rain_backup' => 'Regenalternative vorhanden',
            'barrier_free' => 'Barrierefrei',
            'air_conditioned' => 'Klimatisiert',
            'playground' => 'Spielplatz vorhanden',
            'childcare_room' => 'Kinderbetreuungsraum vorhanden',
            'changing_room' => 'Wickelraum vorhanden',
            'dogs_allowed' => 'Hunde erlaubt',
            'hotel_available' => 'Übernachtung möglich',
            'camper_parking' => 'Wohnmobilstellplätze vorhanden',
            'shuttle_service' => 'Shuttle-Service möglich',
            'regional_catering' => 'Regionales Catering',
            'green_power' => 'Ökostrom',
            'sustainable_concept' => 'Nachhaltiges Konzept',
            'wifi' => 'WLAN vorhanden',
            'stage' => 'Bühne vorhanden',
            'dancefloor' => 'Tanzfläche vorhanden',
            'charging_stations' => 'Ladesäulen vorhanden',
            'free_service_providers' => 'Freie Dienstleister möglich',
            'midnight_snack' => 'Mitternachtssnack möglich',
            'fireworks' => 'Feuerwerk möglich',
            'fixed_catering_partners' => 'Feste Cateringpartner',
        );
        $items = array();
        foreach ($map as $key => $name) {
            $state = $o[$key] ?? 'unknown';
            if ($state === 'yes' || $state === 'request') {
                $items[] = array('@type'=>'LocationFeatureSpecification','name'=>$name,'value'=>($state === 'yes') ? true : 'Auf Anfrage');
            }
        }
        return $items;
    }

    private static function state($o, $key) { return $o[$key] ?? 'unknown'; }
    private static function is_yes($o, $key) { return self::state($o, $key) === 'yes'; }
    private static function is_request($o, $key) { return self::state($o, $key) === 'request'; }
    private static function is_positive($o, $key) { return self::is_yes($o, $key) || self::is_request($o, $key); }

    public static function shortcode_trauredner_landingpage() {
        $o = self::opts();
        $name = !empty($o['location_name']) ? $o['location_name'] : 'unserer Eventlocation';
        $tone = ($o['visitor_tone'] ?? 'du') === 'sie' ? 'sie' : 'du';
        $t = self::landing_texts($tone);
        $faqs = self::build_landing_faqs($o, $name, $tone);

        ob_start();
        $shape = (($o['matching_shape'] ?? 'rounded') === 'square') ? 'square' : 'rounded';
        echo '<div class="wedding-ai-landingpage wae-human-content wae-human-content-v043 wae-shape-' . esc_attr($shape) . '">';
        foreach ($t['intro'] as $paragraph) {
            $paragraph = sprintf($paragraph, $name);
            echo '<p>' . self::linked_wedding_page($paragraph, $o, $tone) . '</p>';
        }

        $room_blocks = self::room_blocks($o, $tone);
        if (!empty($room_blocks)) {
            echo '<h2>' . esc_html($t['rooms_headline']) . '</h2>';
            foreach ($t['rooms_intro'] as $p) { echo '<p>' . esc_html($p) . '</p>'; }
            foreach ($room_blocks as $block) {
                echo '<section class="wae-location-area">';
                echo '<h3>' . esc_html($block['title']) . '</h3>';
                foreach ($block['paragraphs'] as $p) { echo '<p>' . wp_kses_post($p) . '</p>'; }
                if (!empty($block['images'])) {
                    $image_count = count($block['images']) >= 2 ? 2 : 1;
                    echo '<div class="wae-area-images wae-area-images-count-' . esc_attr($image_count) . '">';
                    foreach ($block['images'] as $img_id) {
                        echo wp_get_attachment_image((int)$img_id, 'large', false, array('class'=>'wae-area-image', 'loading'=>'lazy'));
                    }
                    echo '</div>';
                }
                echo '</section>';
            }
        }

        echo '<h2>' . esc_html($t['matching_headline']) . '</h2>';
        foreach ($t['matching_paragraphs'] as $paragraph) { echo '<p>' . esc_html($paragraph) . '</p>'; }
        echo self::matching_widget($tone, $o, $name);

        echo '<h2>' . esc_html($t['faq_headline']) . '</h2>';
        foreach ($t['faq_intro'] as $p) { echo '<p>' . esc_html($p) . '</p>'; }
        foreach ($faqs as $faq) { self::faq_item($faq['q'], $faq['a']); }
        echo self::landing_schema_scripts($faqs, $o, $name, $tone);
        echo self::closing_text($tone);
        echo '</div>';
        return ob_get_clean();
    }

    private static function linked_wedding_page($paragraph, $o, $tone) {
        if (empty($o['wedding_page_url']) || strpos($paragraph, '[wedding_page_link]') === false) {
            return esc_html(str_replace('[wedding_page_link]', 'Hochzeitsseite', $paragraph));
        }
        $label = 'Hochzeitsseite';
        $parts = explode('[wedding_page_link]', $paragraph);
        $link = '<a href="' . esc_url($o['wedding_page_url']) . '">' . esc_html($label) . '</a>';
        return esc_html($parts[0]) . $link . esc_html($parts[1] ?? '');
    }

    private static function landing_texts($tone) {
        if ($tone === 'sie') {
            return array(
                'headline' => 'Den passenden Trauredner für Ihre Hochzeit bei %s finden',
                'intro' => array(
                    'Eine freie Trauung lebt von Menschen. Von der Atmosphäre des Ortes, von den Gästen, von Ihrer Geschichte und von der Person, die durch diesen besonderen Moment führt. Deshalb ist neben der Wahl der Eventlocation auch die Entscheidung für den richtigen Trauredner wichtig.',
                    'Bei %s sind Sie in dieser Entscheidung frei. Sie können selbstverständlich jeden Trauredner mitbringen, den Sie sich für Ihre Hochzeit wünschen. Vielleicht kennen Sie bereits jemanden, vielleicht haben Sie Empfehlungen bekommen oder vielleicht stehen Sie noch ganz am Anfang Ihrer Suche.',
                    'Wenn Sie noch nach einem passenden Redner suchen, möchten wir Ihnen die Auswahl etwas leichter machen. Auf dieser Seite finden Sie deshalb einen kostenlosen Service, der Ihnen hilft, Rednerinnen und Redner zu entdecken, die möglichst gut zu Ihrer Vorstellung von einer persönlichen freien Trauung passen. Weitere Informationen zu Räumen, Möglichkeiten und Angeboten rund um Ihre Feier finden Sie auf unserer [wedding_page_link].'
                ),
                'rooms_headline' => 'Freie Trauungen in unserer Eventlocation',
                'rooms_intro' => array(
                    'Eine freie Trauung braucht einen Rahmen, der zu Ihnen passt. Manche Paare wünschen sich eine helle, ruhige Atmosphäre. Andere träumen von einer Trauung im Freien, von viel Platz für Gäste oder von einem Bereich, der sich besonders persönlich gestalten lässt.',
                    'Damit Sie sich besser orientieren können, stellen wir Ihnen hier die Bereiche vor, die sich für Hochzeiten, freie Trauungen oder Feiern eignen. Die Details helfen Ihnen dabei, frühzeitig ein Gefühl dafür zu bekommen, welcher Rahmen zu Ihrer Gesellschaft und zu Ihrem Ablauf passen könnte.'
                ),
                'matching_headline' => 'Unser Service für Ihre Trauredner-Suche',
                'matching_paragraphs' => array(
                    'Die Suche nach einem Trauredner ist oft schwieriger, als es auf den ersten Blick wirkt. Es geht nicht nur darum, wer in der Nähe wohnt oder an Ihrem Hochzeitstag noch verfügbar ist. Entscheidend ist, ob Stil, Sprache, Humor, Haltung und die Art der Zeremonie wirklich zu Ihnen passen.',
                    'Das Trauredner-Matching unterstützt Sie genau bei dieser Vorauswahl. Es zeigt Rednerinnen und Redner aus dem Rent-a-Pastor Netzwerk und hilft Ihnen, Profile nach Ihren Wünschen zu vergleichen. Die einzelnen Rednerprofile liegen auf externen Profilseiten von Rent-a-Pastor und öffnen sich entsprechend außerhalb dieser Eventlocation-Website. So entsteht keine beliebige Liste, sondern eine Auswahl, mit der Sie gezielter weiterplanen können.',
                    'Die Nutzung ist kostenlos und unverbindlich. Sie können sich in Ruhe umsehen, Profile vergleichen und anschließend selbst entscheiden, ob Sie Kontakt aufnehmen möchten.'
                ),
                'faq_headline' => 'Häufige Fragen',
                'faq_intro' => array(
                    'Bei der Planung einer freien Trauung tauchen oft ähnliche Fragen auf. Einige betreffen die Eventlocation selbst, andere die Wahl des passenden Trauredners oder den Ablauf einer persönlichen Zeremonie.',
                    'Wir haben die wichtigsten Antworten für Sie zusammengestellt, damit Sie schneller einschätzen können, was vor Ort möglich ist und worauf Sie bei der Suche nach einem Trauredner achten sollten.'
                ),
            );
        }
        return array(
            'headline' => 'Den passenden Trauredner für Eure Hochzeit bei %s finden',
            'intro' => array(
                'Eine freie Trauung lebt von Menschen. Von der Atmosphäre des Ortes, von den Gästen, von Eurer Geschichte und von der Person, die durch diesen besonderen Moment führt. Deshalb ist neben der Wahl der Eventlocation auch die Entscheidung für den richtigen Trauredner wichtig.',
                'Bei %s seid Ihr in dieser Entscheidung frei. Ihr könnt selbstverständlich jeden Trauredner mitbringen, den Ihr Euch für Eure Hochzeit wünscht. Vielleicht kennt Ihr bereits jemanden, vielleicht habt Ihr Empfehlungen bekommen oder vielleicht steht Ihr noch ganz am Anfang Eurer Suche.',
                'Wenn Ihr noch nach einem passenden Redner sucht, möchten wir Euch die Auswahl etwas leichter machen. Auf dieser Seite findet Ihr deshalb einen kostenlosen Service, der Euch hilft, Rednerinnen und Redner zu entdecken, die möglichst gut zu Eurer Vorstellung von einer persönlichen freien Trauung passen. Weitere Informationen zu Räumen, Möglichkeiten und Angeboten rund um Eure Feier findet Ihr auf unserer [wedding_page_link].'
            ),
            'rooms_headline' => 'Freie Trauungen in unserer Eventlocation',
            'rooms_intro' => array(
                'Eine freie Trauung braucht einen Rahmen, der zu Euch passt. Manche Paare wünschen sich eine helle, ruhige Atmosphäre. Andere träumen von einer Trauung im Freien, von viel Platz für Gäste oder von einem Bereich, der sich besonders persönlich gestalten lässt.',
                'Damit Ihr Euch besser orientieren könnt, stellen wir Euch hier die Bereiche vor, die sich für Hochzeiten, freie Trauungen oder Feiern eignen. Die Details helfen Euch dabei, frühzeitig ein Gefühl dafür zu bekommen, welcher Rahmen zu Eurer Gesellschaft und zu Eurem Ablauf passen könnte.'
            ),
            'matching_headline' => 'Unser Service für Eure Trauredner-Suche',
            'matching_paragraphs' => array(
                'Die Suche nach einem Trauredner ist oft schwieriger, als es auf den ersten Blick wirkt. Es geht nicht nur darum, wer in der Nähe wohnt oder an Eurem Hochzeitstag noch verfügbar ist. Entscheidend ist, ob Stil, Sprache, Humor, Haltung und die Art der Zeremonie wirklich zu Euch passen.',
                'Das Trauredner-Matching unterstützt Euch genau bei dieser Vorauswahl. Es zeigt Rednerinnen und Redner aus dem Rent-a-Pastor Netzwerk und hilft Euch, Profile nach Euren Wünschen zu vergleichen. Die einzelnen Rednerprofile liegen auf externen Profilseiten von Rent-a-Pastor und öffnen sich entsprechend außerhalb dieser Eventlocation-Website. So entsteht keine beliebige Liste, sondern eine Auswahl, mit der Ihr gezielter weiterplanen könnt.',
                'Die Nutzung ist kostenlos und unverbindlich. Ihr könnt Euch in Ruhe umsehen, Profile vergleichen und anschließend selbst entscheiden, ob Ihr Kontakt aufnehmen möchtet.'
            ),
            'faq_headline' => 'Häufige Fragen',
            'faq_intro' => array(
                'Bei der Planung einer freien Trauung tauchen oft ähnliche Fragen auf. Einige betreffen die Eventlocation selbst, andere die Wahl des passenden Trauredners oder den Ablauf einer persönlichen Zeremonie.',
                'Wir haben die wichtigsten Antworten für Euch zusammengestellt, damit Ihr schneller einschätzen könnt, was vor Ort möglich ist und worauf Ihr bei der Suche nach einem Trauredner achten solltet.'
            ),
        );
    }

    private static function room_blocks($o, $tone) {
        $rooms = !empty($o['rooms']) && is_array($o['rooms']) ? $o['rooms'] : array();
        $du = $tone !== 'sie';
        $out = array();

        /*
         * v0.4.10: Raumtexte werden als zusammenhängende, redaktionelle Absätze gebaut.
         * Keine Wiederholung des Raumnamens im ersten Satz und keine Generator-Sprache.
         */
        foreach ($rooms as $room) {
            if (empty($room['name'])) { continue; }
            $paragraphs = array();
            $name = sanitize_text_field($room['name']);
            $desc = !empty($room['description']) ? trim(wp_strip_all_tags($room['description'])) : '';
            $cap = !empty($room['capacity_max']) ? (int)$room['capacity_max'] : 0;
            $min = !empty($room['capacity_min']) ? (int)$room['capacity_min'] : 0;
            $is_outdoor = (($room['outdoor'] ?? 'unknown') === 'yes');
            $is_indoor = (($room['indoor'] ?? 'unknown') === 'yes');
            $free_ceremony = (($room['free_ceremony'] ?? 'unknown') === 'yes');
            $party = (($room['party'] ?? 'unknown') === 'yes');
            $rain = (($room['rain_backup'] ?? 'unknown') === 'yes');

            $sentences = array();
            if ($desc !== '') {
                $sentences[] = esc_html($desc);
            }

            $capacity_html = '';
            if ($min > 0 && $cap > 0) { $capacity_html = '<strong>' . esc_html($min . ' bis ' . $cap . ' Gäste') . '</strong>'; }
            elseif ($cap > 0) { $capacity_html = '<strong>' . esc_html('bis zu ' . $cap . ' Gäste') . '</strong>'; }
            elseif ($min > 0) { $capacity_html = '<strong>' . esc_html('ab etwa ' . $min . ' Gäste') . '</strong>'; }

            $planning = $du ? 'Für Eure Planung ist besonders wichtig: ' : 'Für Ihre Planung ist besonders wichtig: ';
            $details = array();
            if ($capacity_html !== '') {
                $details[] = $du ? 'Dieser Bereich eignet sich für ' . $capacity_html : 'Dieser Bereich eignet sich für ' . $capacity_html;
            }
            if ($is_indoor && $is_outdoor) { $details[] = $du ? 'er kann drinnen und draußen genutzt werden' : 'er kann innen und außen genutzt werden'; }
            elseif ($is_indoor) { $details[] = 'er kann im Innenbereich genutzt werden'; }
            elseif ($is_outdoor) { $details[] = 'er kann im Außenbereich genutzt werden'; }
            if ($free_ceremony) { $details[] = $du ? 'er eignet sich für freie Trauungen' : 'er eignet sich für freie Trauungen'; }
            if ($party) { $details[] = $du ? 'er kann auch für den Empfang oder die anschließende Feier eine schöne Rolle spielen' : 'er kann auch für den Empfang oder die anschließende Feier eine passende Rolle spielen'; }
            if ($rain) { $details[] = $du ? 'eine Schlechtwetteralternative gibt Euch zusätzliche Planungssicherheit' : 'eine Schlechtwetteralternative gibt Ihnen zusätzliche Planungssicherheit'; }

            if (!empty($details)) {
                $sentences[] = $planning . ucfirst(implode(', ', $details)) . '. ' . ($du ? 'So könnt Ihr schon früh einschätzen, ob dieser Bereich zu Eurem Ablauf und zur Größe Eurer Gesellschaft passt.' : 'So können Sie schon früh einschätzen, ob dieser Bereich zu Ihrem Ablauf und zur Größe Ihrer Gesellschaft passt.');
            }

            if (!empty($room['price_from']) || !empty($room['price_to'])) {
                $price_from = isset($room['price_from']) ? trim(wp_strip_all_tags((string)$room['price_from'])) : '';
                $price_to = isset($room['price_to']) ? trim(wp_strip_all_tags((string)$room['price_to'])) : '';
                $price_html = '';
                if ($price_from !== '' && $price_to !== '') { $price_html = 'zwischen <strong>' . esc_html($price_from . ' und ' . $price_to) . '</strong>'; }
                elseif ($price_from !== '') { $price_html = 'ab <strong>' . esc_html($price_from) . '</strong>'; }
                elseif ($price_to !== '') { $price_html = 'bis <strong>' . esc_html($price_to) . '</strong>'; }
                if ($price_html !== '') {
                    $sentences[] = $du ? 'Der Preisrahmen liegt ' . $price_html . '. Die genaue Kalkulation hängt vom Datum, vom Umfang der Nutzung und von Eurem individuellen Konzept ab.' : 'Der Preisrahmen liegt ' . $price_html . '. Die genaue Kalkulation hängt vom Datum, vom Umfang der Nutzung und von Ihrem individuellen Konzept ab.';
                }
            }

            if (empty($sentences)) {
                $sentences[] = $du ? 'Dieser Bereich kann je nach Ablauf Eurer Hochzeit eine passende Rolle spielen. Sprecht am besten frühzeitig darüber, ob er sich für Eure Trauung, den Empfang oder die anschließende Feier eignet.' : 'Dieser Bereich kann je nach Ablauf Ihrer Hochzeit eine passende Rolle spielen. Sprechen Sie am besten frühzeitig darüber, ob er sich für Ihre Trauung, den Empfang oder die anschließende Feier eignet.';
            }

            $paragraphs[] = implode(' ', $sentences);

            $images = array();
            foreach (array('image_1','image_2') as $k) { if (!empty($room[$k])) { $images[] = (int)$room[$k]; } }
            $out[] = array('title'=>$name, 'paragraphs'=>$paragraphs, 'images'=>$images);
        }
        return $out;
    }


    private static function landing_image_teaser($o, $tone) {
        $rooms = !empty($o['rooms']) && is_array($o['rooms']) ? $o['rooms'] : array();
        $images = array();
        foreach ($rooms as $room) {
            foreach (array('image_1','image_2') as $key) {
                if (!empty($room[$key])) {
                    $id = (int) $room[$key];
                    if ($id > 0 && !in_array($id, $images, true)) {
                        $images[] = $id;
                    }
                }
                if (count($images) >= 2) { break 2; }
            }
        }
        if (empty($images)) { return ''; }
        $subtitle = ($tone === 'sie') ? 'Feiern Sie in unseren Räumen Ihre Trauung' : 'Feiert in unseren Räumen Eure Trauung';
        ob_start();
        echo '<section class="wae-ceremony-image-teaser">';
        echo '<p class="wae-ceremony-image-subtitle">' . esc_html($subtitle) . '</p>';
        echo '<div class="wae-ceremony-image-grid wae-ceremony-image-count-' . esc_attr(count($images)) . '">';
        foreach ($images as $img_id) {
            echo '<figure class="wae-ceremony-image-card">';
            echo wp_get_attachment_image((int)$img_id, 'large', false, array('class'=>'wae-ceremony-image', 'loading'=>'lazy'));
            echo '</figure>';
        }
        echo '</div>';
        echo '</section>';
        return ob_get_clean();
    }

    private static function matching_widget($tone, $o = array(), $location_name = '') {
        $du = $tone !== 'sie';
        $shape = (($o['matching_shape'] ?? 'rounded') === 'square') ? 'square' : 'rounded';
        $city = trim((string)($o['city'] ?? ''));
        $zip = trim((string)($o['zip'] ?? ''));
        $lat = trim((string)($o['latitude'] ?? $o['lat'] ?? ''));
        $lng = trim((string)($o['longitude'] ?? $o['lng'] ?? $o['lon'] ?? ''));
        if ($lat === '' || $lng === '') {
            $geo = self::geocode_location($zip, $city);
            if ($geo) {
                $lat = (string)($geo['lat'] ?? $lat);
                $lng = (string)($geo['lng'] ?? $lng);
            }
        }
        $location = trim($zip . ' ' . $city);
        if ($location === '') { $location = $location_name ?: 'dieser Eventlocation'; }
        $api = 'https://rent-a-pastor.com/wp-json/rentapastor/v1/redner';
        $class = 'wae-live-matching wae-live-matching-' . $shape . ' wae-rap-style-matching';
        $headline = $du ? 'Passende Trauredner finden' : 'Passende Trauredner finden';
        $intro = $du
            ? 'Mit den Reglern könnt Ihr eingrenzen, welche Art von Trauung zu Euch passt. Es geht nicht um richtig oder falsch, sondern um Eure persönliche Atmosphäre: eher locker oder feierlich, eher weltlich oder mit christlichen Elementen, eher schlicht oder ritualstark. Der Ort der Eventlocation und die Zeremonieart sind bereits hinterlegt.'
            : 'Mit den Reglern können Sie eingrenzen, welche Art von Trauung zu Ihnen passt. Es geht nicht um richtig oder falsch, sondern um Ihre persönliche Atmosphäre: eher locker oder feierlich, eher weltlich oder mit christlichen Elementen, eher schlicht oder ritualstark. Der Ort der Eventlocation und die Zeremonieart sind bereits hinterlegt.';
        $external = $du
            ? 'Die Rednerprofile öffnen sich als externe Profilseiten auf rent-a-pastor.com. Dort könnt Ihr Euch ausführlich informieren und anschließend selbst entscheiden, wen Ihr kennenlernen möchtet.'
            : 'Die Rednerprofile öffnen sich als externe Profilseiten auf rent-a-pastor.com. Dort können Sie sich ausführlich informieren und anschließend selbst entscheiden, wen Sie kennenlernen möchten.';
        $sliders = array(
            array('saekular', 'Säkular / weltanschaulich offen', 'neutral niedrig', 'sehr hoch', 50),
            array('christlich', 'Christliche Elemente', 'kaum', 'deutlich möglich', 50),
            array('humor', 'Humor / Lockerheit', 'ruhig', 'locker', 50),
            array('ritualtiefe', 'Ritualtiefe', 'schlicht', 'tiefgehend', 50),
            array('individualitaet', 'Individualität', 'klassisch', 'sehr persönlich', 50),
            array('emotions_balance', 'Emotionalität & Leichtigkeit', 'ruhig tiefgehend', 'lebendig leicht', 55),
        );
        $expert = array(
            array('modern_lifestyle_affinity', 'Moderne Lebensrealitäten', 'klassisch', 'modern', 70),
            array('guest_integration', 'Gästeeinbindung', 'dezent', 'aktiv eingebunden', 50),
            array('improvisation_flexibility', 'Spontaneität & Flexibilität', 'sehr geplant', 'sehr flexibel', 75),
            array('music_relevance_coordination', 'Musikdramaturgie', 'einfach', 'stark abgestimmt', 80),
        );
        ob_start();
        ?>
        <div class="<?php echo esc_attr($class); ?>"
             data-wae-matching
             data-api="<?php echo esc_url($api); ?>"
             data-location="<?php echo esc_attr($location); ?>"
             data-city="<?php echo esc_attr($city); ?>"
             data-zip="<?php echo esc_attr($zip); ?>"
             data-lat="<?php echo esc_attr($lat); ?>"
             data-lng="<?php echo esc_attr($lng); ?>"
             data-service="trauung"
             data-tone="<?php echo esc_attr($tone); ?>">
            <div class="wae-live-matching-head">
                <h3><?php echo esc_html($headline); ?></h3>
                <p><?php echo esc_html($intro); ?></p>
                <p class="wae-external-note"><?php echo esc_html($external); ?></p>
            </div>

            <div class="wae-rap-match-grid">
                <label class="wae-rap-match-field">
                    <span>Sprache der Zeremonie</span>
                    <select data-wae-filter="language">
                        <option value="">Deutsch</option>
                        <option value="english">Englisch</option>
                        <option value="spanish">Spanisch</option>
                        <option value="french">Französisch</option>
                        <option value="italian">Italienisch</option>
                    </select>
                </label>
                <label class="wae-rap-match-field">
                    <span>Suchradius</span>
                    <select data-wae-filter="radius">
                        <option value="80">bis 80 km</option>
                        <option value="120" selected>bis 120 km</option>
                        <option value="150">bis 150 km</option>
                        <option value="250">bis 250 km</option>
                        <option value="500">überregional</option>
                    </select>
                </label>
            </div>

            <div class="wae-rap-mixpult" aria-label="Optionale Stilregler für das Trauredner-Matching">
                <?php foreach ($sliders as $slider): list($key, $label, $left, $right, $default) = $slider; ?>
                    <div class="wae-rap-slider-field">
                        <label for="wae-<?php echo esc_attr($key); ?>"><?php echo esc_html($label); ?></label>
                        <input id="wae-<?php echo esc_attr($key); ?>" type="range" min="0" max="100" value="<?php echo esc_attr($default); ?>" data-wae-filter="<?php echo esc_attr($key); ?>">
                        <div class="wae-rap-slider-scale"><span><?php echo esc_html($left); ?></span><span><?php echo esc_html($right); ?></span></div>
                    </div>
                <?php endforeach; ?>
            </div>

            <details class="wae-rap-expert-mode">
                <summary><?php echo $du ? 'Weitere Wünsche anzeigen' : 'Weitere Wünsche anzeigen'; ?></summary>
                <div class="wae-rap-mixpult wae-rap-mixpult-expert" aria-label="Erweiterte Stilregler für das Trauredner-Matching">
                    <?php foreach ($expert as $slider): list($key, $label, $left, $right, $default) = $slider; ?>
                        <div class="wae-rap-slider-field">
                            <label for="wae-<?php echo esc_attr($key); ?>"><?php echo esc_html($label); ?></label>
                            <input id="wae-<?php echo esc_attr($key); ?>" type="range" min="0" max="100" value="<?php echo esc_attr($default); ?>" data-wae-filter="<?php echo esc_attr($key); ?>">
                            <div class="wae-rap-slider-scale"><span><?php echo esc_html($left); ?></span><span><?php echo esc_html($right); ?></span></div>
                        </div>
                    <?php endforeach; ?>
                </div>
            </details>

            <button type="button" class="wae-live-match-button" data-wae-run-matching><?php echo $du ? 'Passende Trauredner anzeigen' : 'Passende Trauredner anzeigen'; ?></button>
            <div class="wae-live-results" data-wae-results>
                <div class="wae-live-empty"><?php echo $du ? 'Klickt auf den Button, um passende Rednerprofile aus dem Rent-a-Pastor Netzwerk zu laden.' : 'Klicken Sie auf den Button, um passende Rednerprofile aus dem Rent-a-Pastor Netzwerk zu laden.'; ?></div>
            </div>
        </div>
        <?php
        return ob_get_clean();
    }

    private static function build_landing_faqs($o, $name, $tone) {
        $du = $tone !== 'sie';
        $faqs = array();
        $faqs[] = array('q' => $du ? 'Dürfen wir unseren eigenen Trauredner mitbringen?' : 'Dürfen wir unseren eigenen Trauredner mitbringen?', 'a' => $du ? 'Ja. Ihr könnt selbstverständlich jeden Trauredner mitbringen, den Ihr Euch für Eure Hochzeit wünscht. Diese Seite soll Euch nichts vorschreiben, sondern Euch unterstützen, falls Ihr noch auf der Suche seid oder verschiedene Profile vergleichen möchtet. Die Entscheidung bleibt vollständig bei Euch.' : 'Ja. Sie können selbstverständlich jeden Trauredner mitbringen, den Sie sich für Ihre Hochzeit wünschen. Diese Seite soll Ihnen nichts vorschreiben, sondern Sie unterstützen, falls Sie noch auf der Suche sind oder verschiedene Profile vergleichen möchten. Die Entscheidung bleibt vollständig bei Ihnen.');
        $faqs[] = array('q' => $du ? 'Welche Redner zeigt das Matching?' : 'Welche Redner zeigt das Matching?', 'a' => $du ? 'Das Matching zeigt Rednerinnen und Redner aus dem Rent-a-Pastor Netzwerk. Der Vorteil liegt darin, dass Ihr nicht einfach eine beliebige Liste durchsucht, sondern ausgewählte Profile vergleichen könnt. Die Profilseiten der Redner liegen auf Rent-a-Pastor und sind deshalb externe URLs. Gleichzeitig könnt Ihr nach Entfernung, Sprache, Stil und gewünschter Atmosphäre filtern. So verbindet sich die Sicherheit eines Netzwerks mit der Freiheit, selbst zu entscheiden, wer wirklich zu Euch passt.' : 'Das Matching zeigt Rednerinnen und Redner aus dem Rent-a-Pastor Netzwerk. Der Vorteil liegt darin, dass Sie nicht einfach eine beliebige Liste durchsuchen, sondern ausgewählte Profile vergleichen können. Die Profilseiten der Redner liegen auf Rent-a-Pastor und sind deshalb externe URLs. Gleichzeitig können Sie nach Entfernung, Sprache, Stil und gewünschter Atmosphäre filtern. So verbindet sich die Sicherheit eines Netzwerks mit der Freiheit, selbst zu entscheiden, wer wirklich zu Ihnen passt.');
        $faqs[] = array('q' => $du ? 'Kostet die Nutzung des Matchings etwas?' : 'Kostet die Nutzung des Matchings etwas?', 'a' => $du ? 'Nein. Ihr könnt das Matching kostenlos und unverbindlich nutzen. Es ist als Orientierung gedacht, damit Ihr Euch einen ersten Eindruck verschaffen und passende Rednerprofile in Ruhe vergleichen könnt.' : 'Nein. Sie können das Matching kostenlos und unverbindlich nutzen. Es ist als Orientierung gedacht, damit Sie sich einen ersten Eindruck verschaffen und passende Rednerprofile in Ruhe vergleichen können.');
        $faqs[] = array('q' => $du ? 'Warum ist der passende Trauredner so wichtig?' : 'Warum ist der passende Trauredner so wichtig?', 'a' => $du ? 'Eine freie Trauung lebt stark von der Person, die sie gestaltet. Der Trauredner erzählt Eure Geschichte, führt durch die Zeremonie, nimmt die Stimmung im Raum auf und prägt die Atmosphäre dieses besonderen Moments. Deshalb reicht es nicht, dass jemand gut sprechen kann. Es muss menschlich, stilistisch und inhaltlich passen.' : 'Eine freie Trauung lebt stark von der Person, die sie gestaltet. Der Trauredner erzählt Ihre Geschichte, führt durch die Zeremonie, nimmt die Stimmung im Raum auf und prägt die Atmosphäre dieses besonderen Moments. Deshalb reicht es nicht, dass jemand gut sprechen kann. Es muss menschlich, stilistisch und inhaltlich passen.');

        if (self::is_positive($o, 'free_ceremony_possible')) { $faqs[] = array('q' => 'Ist eine freie Trauung bei ' . $name . ' möglich?', 'a' => self::free_ceremony_answer($o, $du)); }
        if (self::is_positive($o, 'rain_backup')) { $faqs[] = array('q' => $du ? 'Was passiert bei schlechtem Wetter?' : 'Was passiert bei schlechtem Wetter?', 'a' => self::rain_answer($o, $du)); }
        if (self::is_positive($o, 'barrier_free')) { $faqs[] = array('q' => $du ? 'Ist die Eventlocation barrierefrei?' : 'Ist die Eventlocation barrierefrei?', 'a' => self::barrier_answer($o, $du)); }
        if (self::is_positive($o, 'dogs_allowed')) { $faqs[] = array('q' => $du ? 'Sind Hunde willkommen?' : 'Sind Hunde willkommen?', 'a' => self::dogs_answer($o, $du)); }
        $family = self::family_answer($o, $du); if ($family !== '') { $faqs[] = array('q' => $du ? 'Ist die Eventlocation für Familien mit Kindern geeignet?' : 'Ist die Eventlocation für Familien mit Kindern geeignet?', 'a' => $family); }
        $overnight = self::overnight_answer($o, $du); if ($overnight !== '') { $faqs[] = array('q' => $du ? 'Gibt es Übernachtungsmöglichkeiten oder Unterstützung bei der Anreise?' : 'Gibt es Übernachtungsmöglichkeiten oder Unterstützung bei der Anreise?', 'a' => $overnight); }
        $providers = self::providers_answer($o, $du); if ($providers !== '') { $faqs[] = array('q' => $du ? 'Können eigene Dienstleister eingebunden werden?' : 'Können eigene Dienstleister eingebunden werden?', 'a' => $providers); }
        $comfort = self::comfort_answer($o, $du); if ($comfort !== '') { $faqs[] = array('q' => $du ? 'Welche Ausstattung ist für die Feier vorhanden?' : 'Welche Ausstattung ist für die Feier vorhanden?', 'a' => $comfort); }
        $sustain = self::sustainability_answer($o, $du); if ($sustain !== '') { $faqs[] = array('q' => $du ? 'Gibt es nachhaltige Angebote?' : 'Gibt es nachhaltige Angebote?', 'a' => $sustain); }

        return array_values(array_filter($faqs, function($f){ return !empty($f['q']) && !empty($f['a']); }));
    }

    private static function build_location_schema_faqs($o) {
        $tone = (($o['visitor_tone'] ?? 'du') === 'sie') ? 'sie' : 'du';
        $du = $tone !== 'sie';
        $name = !empty($o['location_name']) ? sanitize_text_field($o['location_name']) : 'der Eventlocation';
        $faqs = array();
        if (self::is_positive($o, 'free_ceremony_possible')) { $faqs[] = array('q' => 'Ist eine freie Trauung bei ' . $name . ' möglich?', 'a' => self::free_ceremony_answer($o, $du)); }
        if (self::is_positive($o, 'rain_backup')) { $faqs[] = array('q' => 'Gibt es eine Schlechtwetteralternative?', 'a' => self::rain_answer($o, $du)); }
        if (self::is_positive($o, 'barrier_free')) { $faqs[] = array('q' => 'Ist die Eventlocation barrierefrei?', 'a' => self::barrier_answer($o, $du)); }
        if (self::is_positive($o, 'dogs_allowed')) { $faqs[] = array('q' => 'Sind Hunde erlaubt?', 'a' => self::dogs_answer($o, $du)); }
        $family = self::family_answer($o, $du); if ($family !== '') { $faqs[] = array('q' => 'Ist die Eventlocation für Familien mit Kindern geeignet?', 'a' => $family); }
        $overnight = self::overnight_answer($o, $du); if ($overnight !== '') { $faqs[] = array('q' => 'Gibt es Übernachtungsmöglichkeiten oder Unterstützung bei der Anreise?', 'a' => $overnight); }
        $providers = self::providers_answer($o, $du); if ($providers !== '') { $faqs[] = array('q' => 'Können eigene Dienstleister eingebunden werden?', 'a' => $providers); }
        $comfort = self::comfort_answer($o, $du); if ($comfort !== '') { $faqs[] = array('q' => 'Welche Ausstattung ist für die Feier vorhanden?', 'a' => $comfort); }
        $sustain = self::sustainability_answer($o, $du); if ($sustain !== '') { $faqs[] = array('q' => 'Gibt es nachhaltige Angebote?', 'a' => $sustain); }
        return array_values(array_filter($faqs, function($f){ return !empty($f['q']) && !empty($f['a']); }));
    }

    private static function free_ceremony_answer($o, $du) {
        if (self::is_yes($o, 'free_ceremony_possible')) {
            return $du ? 'Ja. Freie Trauungen sind bei uns grundsätzlich möglich. Ihr könnt Eure Zeremonie persönlich gestalten und gemeinsam mit Eurem Trauredner einen Ablauf entwickeln, der zu Euch, Euren Gästen und zur Atmosphäre der Location passt.' : 'Ja. Freie Trauungen sind bei uns grundsätzlich möglich. Sie können Ihre Zeremonie persönlich gestalten und gemeinsam mit Ihrem Trauredner einen Ablauf entwickeln, der zu Ihnen, Ihren Gästen und zur Atmosphäre der Location passt.';
        }
        return $du ? 'Eine freie Trauung ist nach Absprache möglich. Am besten klärt Ihr frühzeitig, welcher Bereich für Eure Gesellschaft und Eure Vorstellungen geeignet ist.' : 'Eine freie Trauung ist nach Absprache möglich. Am besten klären Sie frühzeitig, welcher Bereich für Ihre Gesellschaft und Ihre Vorstellungen geeignet ist.';
    }
    private static function rain_answer($o, $du) { return self::is_yes($o, 'rain_backup') ? ($du ? 'Für wechselhaftes Wetter gibt es eine Alternative. Das ist besonders bei freien Trauungen im Außenbereich beruhigend, weil Ihr nicht erst am Hochzeitstag improvisieren müsst.' : 'Für wechselhaftes Wetter gibt es eine Alternative. Das ist besonders bei freien Trauungen im Außenbereich beruhigend, weil Sie nicht erst am Hochzeitstag improvisieren müssen.') : ($du ? 'Eine Alternative bei schlechtem Wetter ist nach Absprache möglich. Wenn Ihr eine Trauung im Freien plant, solltet Ihr diesen Punkt frühzeitig gemeinsam durchgehen.' : 'Eine Alternative bei schlechtem Wetter ist nach Absprache möglich. Wenn Sie eine Trauung im Freien planen, sollten Sie diesen Punkt frühzeitig gemeinsam durchgehen.'); }
    private static function barrier_answer($o, $du) { return self::is_yes($o, 'barrier_free') ? ($du ? 'Ja. Unsere Eventlocation ist barrierearm beziehungsweise barrierefrei nutzbar. Wenn Gäste besondere Anforderungen haben, empfehlen wir trotzdem eine kurze Abstimmung, damit Wege, Toiletten und einzelne Bereiche passend geplant werden können.' : 'Ja. Unsere Eventlocation ist barrierearm beziehungsweise barrierefrei nutzbar. Wenn Gäste besondere Anforderungen haben, empfehlen wir trotzdem eine kurze Abstimmung, damit Wege, Toiletten und einzelne Bereiche passend geplant werden können.') : ''; }
    private static function dogs_answer($o, $du) { return self::is_yes($o, 'dogs_allowed') ? ($du ? 'Ja. Hunde können Teil Eures Hochzeitstages sein. Damit der Ablauf für alle entspannt bleibt, lohnt sich eine kurze Abstimmung dazu, wo sich der Hund während Zeremonie und Feier am besten aufhalten kann.' : 'Ja. Hunde können Teil Ihres Hochzeitstages sein. Damit der Ablauf für alle entspannt bleibt, lohnt sich eine kurze Abstimmung dazu, wo sich der Hund während Zeremonie und Feier am besten aufhalten kann.') : ($du ? 'Hunde sind nach Absprache möglich. Wenn Ihr Euren Hund einbinden möchtet, klärt am besten frühzeitig, welche Bereiche dafür geeignet sind.' : 'Hunde sind nach Absprache möglich. Wenn Sie Ihren Hund einbinden möchten, klären Sie am besten frühzeitig, welche Bereiche dafür geeignet sind.'); }

    private static function family_answer($o, $du) {
        $has = self::is_yes($o, 'kids_welcome') || self::is_yes($o, 'playground') || self::is_yes($o, 'childcare_room') || self::is_yes($o, 'changing_room');
        $request = self::is_request($o, 'kids_welcome') || self::is_request($o, 'playground') || self::is_request($o, 'childcare_room') || self::is_request($o, 'changing_room');
        if (!$has && !$request) { return ''; }
        if ($request && !$has) { return $du ? 'Angebote für Kinder sind nach Absprache möglich. Wenn viele Familien eingeladen sind, lohnt es sich, diesen Punkt frühzeitig gemeinsam zu besprechen.' : 'Angebote für Kinder sind nach Absprache möglich. Wenn viele Familien eingeladen sind, lohnt es sich, diesen Punkt frühzeitig gemeinsam zu besprechen.'; }
        $items = array();
        if (self::is_yes($o, 'playground')) { $items[] = $du ? 'Spielmöglichkeiten' : 'Spielmöglichkeiten'; }
        if (self::is_yes($o, 'childcare_room')) { $items[] = $du ? 'ein Kinderbereich oder Spielzimmer' : 'ein Kinderbereich oder Spielzimmer'; }
        if (self::is_yes($o, 'changing_room')) { $items[] = $du ? 'ein Wickelraum' : 'ein Wickelraum'; }
        $extra = $items ? ' Dazu gehören ' . implode(', ', $items) . '.' : '';
        return $du ? 'Kinder sind bei uns herzlich willkommen. Gerade bei Hochzeiten mit kleinen Gästen ist es schön, wenn Familien sich gut aufgehoben fühlen und der Tag für alle entspannt bleibt.' . $extra . ' So können Eltern den Hochzeitstag besser genießen und die jüngsten Gäste haben zwischendurch ihren eigenen Raum.' : 'Kinder sind bei uns herzlich willkommen. Gerade bei Hochzeiten mit kleinen Gästen ist es schön, wenn Familien sich gut aufgehoben fühlen und der Tag für alle entspannt bleibt.' . $extra . ' So können Eltern den Hochzeitstag besser genießen und die jüngsten Gäste haben zwischendurch ihren eigenen Raum.';
    }

    private static function overnight_answer($o, $du) {
        if (!(self::is_positive($o, 'hotel_available') || self::is_positive($o, 'camper_parking') || self::is_positive($o, 'shuttle_service'))) { return ''; }
        $sentences = array();
        if (self::is_yes($o, 'hotel_available')) { $sentences[] = $du ? 'Für Gäste mit längerer Anreise stehen Übernachtungsmöglichkeiten zur Verfügung.' : 'Für Gäste mit längerer Anreise stehen Übernachtungsmöglichkeiten zur Verfügung.'; }
        if (self::is_yes($o, 'camper_parking')) { $sentences[] = $du ? 'Auch Wohnmobilstellplätze können die Planung erleichtern, wenn Gäste direkt vor Ort bleiben möchten.' : 'Auch Wohnmobilstellplätze können die Planung erleichtern, wenn Gäste direkt vor Ort bleiben möchten.'; }
        if (self::is_yes($o, 'shuttle_service')) { $sentences[] = $du ? 'Ein Shuttle-Service kann zusätzlich helfen, Anreise und Heimweg entspannter zu gestalten.' : 'Ein Shuttle-Service kann zusätzlich helfen, Anreise und Heimweg entspannter zu gestalten.'; }
        if (!$sentences) { return $du ? 'Übernachtung oder Unterstützung bei der Anreise ist nach Absprache möglich. Sprecht diesen Punkt am besten frühzeitig an, wenn viele Gäste von weiter weg kommen.' : 'Übernachtung oder Unterstützung bei der Anreise ist nach Absprache möglich. Sprechen Sie diesen Punkt am besten frühzeitig an, wenn viele Gäste von weiter weg kommen.'; }
        return implode(' ', $sentences) . ' So lässt sich der Hochzeitstag für alle Beteiligten etwas entspannter planen.';
    }

    private static function providers_answer($o, $du) {
        if (self::is_yes($o, 'free_service_providers')) { return $du ? 'Ja. Eigene Dienstleister können eingebunden werden. Das gibt Euch viel Gestaltungsspielraum bei Fotografen, DJs, Floristik, Musik und natürlich auch bei der Wahl Eures Trauredners.' : 'Ja. Eigene Dienstleister können eingebunden werden. Das gibt Ihnen viel Gestaltungsspielraum bei Fotografen, DJs, Floristik, Musik und natürlich auch bei der Wahl Ihres Trauredners.'; }
        if (self::is_request($o, 'free_service_providers')) { return $du ? 'Eigene Dienstleister sind nach Absprache möglich. Wenn Ihr bestimmte Fotografen, DJs, Floristen oder Musiker im Blick habt, solltet Ihr das frühzeitig besprechen.' : 'Eigene Dienstleister sind nach Absprache möglich. Wenn Sie bestimmte Fotografen, DJs, Floristen oder Musiker im Blick haben, sollten Sie das frühzeitig besprechen.'; }
        if (self::is_yes($o, 'fixed_catering_partners')) { return $du ? 'Für bestimmte Leistungen gibt es feste Partner. Das kann die Planung erleichtern, weil Abläufe und Ansprechpartner bereits eingespielt sind.' : 'Für bestimmte Leistungen gibt es feste Partner. Das kann die Planung erleichtern, weil Abläufe und Ansprechpartner bereits eingespielt sind.'; }
        return '';
    }

    private static function comfort_answer($o, $du) {
        $features = array();
        if (self::is_yes($o, 'air_conditioned')) { $features[] = 'klimatisierte Bereiche'; }
        if (self::is_yes($o, 'wifi')) { $features[] = 'WLAN'; }
        if (self::is_yes($o, 'stage')) { $features[] = 'eine Bühne'; }
        if (self::is_yes($o, 'dancefloor')) { $features[] = 'eine Tanzfläche'; }
        if (self::is_yes($o, 'charging_stations')) { $features[] = 'Ladesäulen'; }
        if (empty($features)) { return ''; }
        return ($du ? 'Für Eure Feier stehen je nach Bereich verschiedene Ausstattungsmerkmale zur Verfügung. Dazu gehören ' : 'Für Ihre Feier stehen je nach Bereich verschiedene Ausstattungsmerkmale zur Verfügung. Dazu gehören ') . implode(', ', $features) . '. Welche Ausstattung für den konkreten Ablauf genutzt werden kann, klären wir am besten im persönlichen Gespräch.';
    }

    private static function sustainability_answer($o, $du) {
        $features = array();
        if (self::is_yes($o, 'regional_catering')) { $features[] = 'regionales Catering'; }
        if (self::is_yes($o, 'green_power')) { $features[] = 'Ökostrom'; }
        if (self::is_yes($o, 'sustainable_concept')) { $features[] = 'ein nachhaltiges Gesamtkonzept'; }
        if (empty($features)) { return ''; }
        return ($du ? 'Wenn Euch Nachhaltigkeit bei Eurer Hochzeit wichtig ist, gibt es dafür vor Ort gute Anknüpfungspunkte. Genannt werden können ' : 'Wenn Ihnen Nachhaltigkeit bei Ihrer Hochzeit wichtig ist, gibt es dafür vor Ort gute Anknüpfungspunkte. Genannt werden können ') . implode(', ', $features) . '. Welche Punkte für die Feier besonders relevant sind, lässt sich am besten im persönlichen Gespräch klären.';
    }

    private static function closing_text($tone) {
        if ($tone === 'sie') {
            return '<h2>Noch Fragen?</h2><p>Wenn Sie mehr über die Möglichkeiten einer freien Trauung in unserer Eventlocation erfahren möchten, sprechen Sie uns gerne an. Gemeinsam finden wir heraus, welcher Rahmen zu Ihrer Hochzeit passt und wie sich Ihre Zeremonie stimmig in den Tag einfügt.</p>';
        }
        return '<h2>Noch Fragen?</h2><p>Wenn Ihr mehr über die Möglichkeiten einer freien Trauung in unserer Eventlocation erfahren möchtet, sprecht uns gerne an. Gemeinsam finden wir heraus, welcher Rahmen zu Eurer Hochzeit passt und wie sich Eure Zeremonie stimmig in den Tag einfügt.</p>';
    }

    private static function landing_schema_scripts($faqs, $o, $name, $tone) {
        $graph = array();
        if (!empty($faqs)) {
            $main = array();
            foreach ($faqs as $faq) {
                $main[] = array('@type'=>'Question','name'=>wp_strip_all_tags($faq['q']),'acceptedAnswer'=>array('@type'=>'Answer','text'=>wp_kses_post($faq['a'])));
            }
            $graph[] = array('@type'=>'FAQPage','@id'=>trailingslashit(get_permalink()) . '#faq','mainEntity'=>$main);
        }
        $page_url = get_permalink() ? get_permalink() : home_url('/trauredner/');
        $graph[] = array(
            '@type' => array('WebApplication','Service'),
            '@id' => trailingslashit($page_url) . '#trauredner-matching',
            'name' => 'Trauredner-Matching für freie Trauungen',
            'applicationCategory' => 'ServiceMatchingApplication',
            'operatingSystem' => 'Web',
            'url' => $page_url,
            'serviceType' => 'Trauredner-Matching für freie Trauungen',
            'description' => 'Kostenloses Matchingtool für Brautpaare, das passende Traurednerinnen und Trauredner aus dem Rent-a-Pastor Netzwerk anhand von Ort, Stil, Sprache, Humor und gewünschter Atmosphäre empfiehlt.',
            'provider' => array('@id'=>'https://rent-a-pastor.com/#organization'),
            'isBasedOn' => array('@id'=>'https://rent-a-pastor.com/wp-json/rentapastor/v1/redner#dataset'),
            'areaServed' => !empty($o['city']) ? array('@type'=>'City','name'=>sanitize_text_field($o['city'])) : array('@type'=>'Country','name'=>'Deutschland'),
            'offers' => array('@type'=>'Offer','price'=>'0','priceCurrency'=>'EUR','description'=>'Die Nutzung des Trauredner-Matchings ist kostenlos und unverbindlich.'),
            'mentions' => array('@id'=>trailingslashit($page_url) . '#rentapastor-kooperation')
        );
        $graph[] = array(
            '@type'=>'Organization',
            '@id'=>'https://rent-a-pastor.com/#organization',
            'name'=>'Rent-a-Pastor',
            'url'=>'https://rent-a-pastor.com/',
            'foundingDate'=>'2013',
            'description'=>'Rent-a-Pastor ist ein Rednernetzwerk für freie Trauungen, freie Taufen, Eheerneuerungen und Trauerfeiern im deutschsprachigen Raum.'
        );
        $graph[] = array(
            '@type'=>'Dataset',
            '@id'=>'https://rent-a-pastor.com/wp-json/rentapastor/v1/redner#dataset',
            'name'=>'Rent-a-Pastor Rednerdatenbank',
            'description'=>'Öffentliche strukturierte Rednerdatenbank des Rent-a-Pastor Netzwerks mit Profilen, Regionen, Leistungen und Matchinginformationen.',
            'url'=>'https://rent-a-pastor.com/wp-json/rentapastor/v1/redner',
            'creator'=>array('@id'=>'https://rent-a-pastor.com/#organization'),
            'publisher'=>array('@id'=>'https://rent-a-pastor.com/#organization'),
            'distribution'=>array('@type'=>'DataDownload','contentUrl'=>'https://rent-a-pastor.com/wp-json/rentapastor/v1/redner','encodingFormat'=>'application/json')
        );
        $graph[] = array(
            '@type'=>'CreativeWork',
            '@id'=>trailingslashit($page_url) . '#rentapastor-kooperation',
            'name'=>'Kooperationspartnerschaft mit rent-a-pastor.com',
            'description'=>'Diese Eventlocation stellt ihren Brautpaaren als zusätzlichen Service ein Trauredner-Matching in Kooperation mit rent-a-pastor.com zur Verfügung. Die empfohlenen Rednerprofile liegen auf externen Rent-a-Pastor-Profilseiten.',
            'about'=>array('@id'=>trailingslashit($page_url) . '#trauredner-matching'),
            'publisher'=>array('@id'=>'https://rent-a-pastor.com/#organization')
        );
        $schema = array('@context'=>'https://schema.org','@graph'=>$graph);
        return "\n" . '<script type="application/ld+json" class="wedding-ai-engine-landing-schema">' . wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . '</script>' . "\n";
    }

    private static function faq_item($q, $a) {
        if ($a === '') { return; }
        echo '<h3>'.esc_html($q).'</h3><p>'.esc_html($a).'</p>';
    }
}
