<?php
/**
 * Tam Rank™ Meta Boxes
 */

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

class TamRank_Meta_Boxes
{

    public function __construct()
    {
        add_action('add_meta_boxes', array($this, 'add_meta_boxes'));
        add_action('save_post', array($this, 'save_meta_boxes'));
        add_action('admin_enqueue_scripts', array($this, 'enqueue_meta_box_scripts'));
        add_action('admin_footer', array($this, 'render_floating_widget'));
        add_action('wp_ajax_tamrank_save_schema_template', array($this, 'ajax_save_schema_template'));
        add_action('wp_ajax_tamrank_get_schema_velden', array($this, 'ajax_get_schema_velden'));
        add_action('wp_ajax_tam_rank_calculate_score', array($this, 'ajax_calculate_live_score'));
    }

    /**
     * AJAX handler for live score calculation
     * Uses centralized TamRank_Meta_Calculator
     */
    public function ajax_calculate_live_score()
    {
        // Check nonces
        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'tam_rank_meta_nonce')) {
            wp_send_json_error(array('message' => tamrank__('error_nonce_invalid', 'Invalid security token. Please refresh the page.'), 'code' => 'nonce_invalid'));
        }

        // Capability: only users who can edit posts may use the live-score calculator
        if (!current_user_can('edit_posts')) {
            wp_send_json_error(array('message' => tamrank__('error_permission_denied', 'You do not have permission for this action.'), 'code' => 'permission_denied'));
        }

        // Get inputs
        $title = isset($_POST['title']) ? sanitize_text_field(wp_unslash($_POST['title'])) : '';
        $description = isset($_POST['description']) ? sanitize_textarea_field(wp_unslash($_POST['description'])) : '';
        $focus_keyword = isset($_POST['focus_keyword']) ? sanitize_text_field(wp_unslash($_POST['focus_keyword'])) : '';
        $slug = isset($_POST['slug']) ? sanitize_title(wp_unslash($_POST['slug'])) : '';

        if (class_exists('TamRank_Meta_Calculator')) {
            $score = TamRank_Meta_Calculator::calculate([
                'title' => $title,
                'description' => $description,
                'focus_keyword' => $focus_keyword,
                'slug' => $slug
            ]);
            wp_send_json_success(array('score' => $score));
        } else {
            wp_send_json_error(array('message' => tamrank__('error_calculator_unavailable', 'The score calculator is not available.'), 'code' => 'not_found'));
        }
    }

    /**
     * AJAX handler for getting schema fields dynamically
     */
    public function ajax_get_schema_velden()
    {
        // Check nonce
        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'tamrank_schema_preview')) {
            wp_send_json_error(array('message' => tamrank__('error_nonce_invalid', 'Invalid security token. Please refresh the page.'), 'code' => 'nonce_invalid'));
        }

        // Get parameters
        $post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
        $schema_type = isset($_POST['schema_type']) ? sanitize_text_field(wp_unslash($_POST['schema_type'])) : '';
        $bron = isset($_POST['bron']) ? sanitize_text_field(wp_unslash($_POST['bron'])) : 'automatisch';
        $template_id = isset($_POST['template_id']) ? sanitize_text_field(wp_unslash($_POST['template_id'])) : '';

        if (!$post_id || !current_user_can('edit_post', $post_id)) {
            wp_send_json_error(array('message' => tamrank__('error_permission_denied', 'You do not have permission for this action.'), 'code' => 'permission_denied'));
        }

        // Get current overrides
        $overrides = get_post_meta($post_id, 'tamrank_schema_overrides', true);
        if (!is_array($overrides)) {
            $overrides = array();
        }

        // Check if there are manual fields (for template bron)
        $has_manual_fields = false;
        if ($bron === 'template' && !empty($template_id)) {
            $templates_manager = new TAMRANK_Schema_Templates();
            $template = $templates_manager->get_template($template_id);
            if ($template && isset($template['field_mappings'])) {
                foreach ($template['field_mappings'] as $property => $mapping) {
                    if (isset($mapping['source']) && $mapping['source'] === 'manual') {
                        $has_manual_fields = true;
                        break;
                    }
                }
            }
        }

        // Render the fields
        ob_start();
        $this->render_schema_velden_content($schema_type, $overrides, $bron, $template_id);
        $html = ob_get_clean();

        wp_send_json_success(array(
            'html' => $html,
            'schema_type' => $schema_type,
            'has_manual_fields' => $has_manual_fields
        ));
    }

    /**
     * AJAX handler for saving schema template selection
     */
    public function ajax_save_schema_template()
    {
        // Check nonce
        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'tamrank_schema_template_change')) {
            wp_send_json_error(array('message' => tamrank__('error_nonce_invalid', 'Invalid security token. Please refresh the page.'), 'code' => 'nonce_invalid'));
        }

        // Check permissions
        $post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
        if (!$post_id || !current_user_can('edit_post', $post_id)) {
            wp_send_json_error(array('message' => tamrank__('error_permission_denied', 'You do not have permission for this action.'), 'code' => 'permission_denied'));
        }

        // Get template ID
        $template_id = isset($_POST['template_id']) ? sanitize_text_field(wp_unslash($_POST['template_id'])) : '';

        // Save the template selection (without underscore prefix to match the read in render_schema_tab_content)
        update_post_meta($post_id, 'tamrank_schema_template_id', $template_id);

        wp_send_json_success(array('template_id' => $template_id));
    }

    /**
     * Get meta box title with icon
     */
    private function get_meta_box_title()
    {
        return '<div style="display: flex; align-items: center; gap: 6px;">
            <svg width="20" height="20" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
                <rect x="4" y="4" width="32" height="32" rx="8" fill="#1e293b"/>
                <rect x="10" y="10" width="20" height="5" rx="2" fill="#10b981"/>
                <rect x="15" y="10" width="5" height="20" rx="2" fill="#10b981"/>
                <rect x="22" y="18" width="5" height="12" rx="2" fill="#10b981" opacity="0.5"/>
            </svg>
            <span>TamRank SEO</span>
        </div>';
    }

    public function add_meta_boxes()
    {
        // Freemium model: Meta boxes always available
        // Basic SEO features (meta title, description, focus keyword) are FREE
        // Advanced features (AI, Schema) show PRO badges

        $general_settings = tam_rank_cached_option('tam_rank_general_settings', array());

        // Only add if enabled in settings
        if (isset($general_settings['enable_meta_boxes']) && !$general_settings['enable_meta_boxes']) {
            return;
        }

        $post_types = get_post_types(array('public' => true));

        // SEO meta boxes do not belong on media attachments — they are not
        // standalone indexable pages, and meta title/description/focus-keyword
        // make no sense there. WP 7.0's revamped attachment editor started
        // surfacing the box on the media edit screen, so exclude it explicitly.
        unset($post_types['attachment']);

        foreach ($post_types as $post_type) {
            add_meta_box(
                'tam-rank-seo',
                $this->get_meta_box_title(),
                array($this, 'render_seo_meta_box'),
                $post_type,
                'normal',
                'high'
            );
        }
    }

    public function enqueue_meta_box_scripts($hook)
    {
        if ($hook === 'post.php' || $hook === 'post-new.php') {
            // No SEO meta box on media attachments, so skip its assets too.
            $screen = get_current_screen();
            if ($screen && isset($screen->post_type) && $screen->post_type === 'attachment') {
                return;
            }
            wp_enqueue_script('tam-rank-meta-box', TAM_RANK_PLUGIN_URL . 'assets/js/meta-box.js', array('jquery'), TAM_RANK_VERSION, true);
            wp_localize_script('tam-rank-meta-box', 'tamRankMeta', array(
                'ajaxUrl' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce('tam_rank_meta_nonce'),
                'postId' => get_the_ID(),
                'strings' => array(
                    'chars_count_suffix' => tamrank__('chars_count_suffix', 'characters'),
                    'chars_too_short' => tamrank__('chars_too_short', 'too short - minimum %d'),
                    'chars_too_long' => tamrank__('chars_too_long', 'too long - maximum %d'),
                    'chars_good' => tamrank__('chars_good', 'good'),
                    'seo_warnings_title' => tamrank__('seo_warnings_title', 'There are some SEO warnings:'),
                    'proceed_confirmation' => tamrank__('proceed_confirmation', 'Do you want to proceed anyway?'),
                    'meta_title_too_short' => tamrank__('meta_title_too_short', 'Meta title is too short (less than 30 characters)'),
                    'meta_title_too_long' => tamrank__('meta_title_too_long', 'Meta title is too long (more than 60 characters)'),
                    'meta_desc_too_short' => tamrank__('meta_desc_too_short', 'Meta description is too short (less than 120 characters)'),
                    'meta_desc_too_long' => tamrank__('meta_desc_too_long', 'Meta description is too long (more than 160 characters)'),
                    'focus_keyword_not_in_title' => tamrank__('focus_keyword_not_in_title', 'Focus keyword does not appear in the meta title'),
                    'focus_keyword_not_in_desc' => tamrank__('focus_keyword_not_in_desc', 'Focus keyword does not appear in the meta description'),
                    'proceed' => tamrank__('proceed', 'Proceed'),
                    'cancel' => tamrank__('cancel', 'Cancel')
                )
            ));

            // TamRank Meta Boxes CSS
            wp_enqueue_style(
                'tamrank-meta-boxes',
                TAM_RANK_PLUGIN_URL . 'assets/css/tamrank-meta-boxes.css',
                array('tamrank-variables'),
                TAM_RANK_VERSION
            );

            // Live counter on the advanced robots directives panel.
            wp_enqueue_script(
                'tamrank-robots',
                TAM_RANK_PLUGIN_URL . 'assets/js/tr-robots.js',
                array(),
                TAM_RANK_VERSION,
                true
            );

            // TamRank Total Score Widget CSS & JS
            wp_enqueue_style(
                'tamrank-total-score',
                TAM_RANK_PLUGIN_URL . 'assets/css/tamrank-total-score.css',
                array('tamrank-variables'),
                TAM_RANK_VERSION
            );

            wp_enqueue_script(
                'tamrank-total-score',
                TAM_RANK_PLUGIN_URL . 'assets/js/tamrank-total-score.js',
                array('jquery', 'tam-rank-meta-box'),
                TAM_RANK_VERSION,
                true
            );

            wp_localize_script('tamrank-total-score', 'tamRankTotalScore', array(
                'ajaxUrl' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce('tamrank_total_score_nonce'),
                'postId' => get_the_ID(),
                'strings' => array(
                    'score_excellent' => tamrank__('score_excellent', 'Excellent'),
                    'score_good' => tamrank__('score_good', 'Good'),
                    'score_fair' => tamrank__('score_fair', 'Needs attention'),
                    'score_poor' => tamrank__('score_poor', 'Needs improvement'),
                    'view_details' => tamrank__('view_details_btn', 'View details'),
                    'hide_details' => tamrank__('hide_details_btn', 'Hide details')
                )
            ));
        }
    }

    public function render_seo_meta_box($post)
    {
        // Add nonce field
        wp_nonce_field('tam_rank_meta_nonce', 'tam_rank_meta_nonce');

        // Get current values
        $meta_title = get_post_meta($post->ID, '_tam_rank_meta_title', true);
        $meta_description = get_post_meta($post->ID, '_tam_rank_meta_description', true);
        $noindex = get_post_meta($post->ID, '_tam_rank_noindex', true);
        $nofollow = get_post_meta($post->ID, '_tam_rank_nofollow', true);
        $robots_directives = tamrank_get_robots_directive_values($post->ID, 'post');
        $canonical = get_post_meta($post->ID, '_tam_rank_canonical', true);
        $focus_keyword = get_post_meta($post->ID, '_tam_rank_focus_keyword', true);
        $custom_slug = get_post_meta($post->ID, '_tam_rank_custom_slug', true);

        // Default values
        if (empty($meta_title)) {
            $meta_title = $post->post_title;
        }

        // Get current slug
        $current_slug = $post->post_name;

        // Calculate live optimization score using Central Service
        // Calculate live optimization score using Central Service
        $live_score = TamRank_Score_Service::get_instance()->get_meta_score($post->ID);
        ?>
        <div class="tam-rank-meta-box">
            <?php
            // Audit exclusion notice
            $audit_excluded_ids  = get_option('tam_rank_audit_excluded_posts', array());
            $is_audit_excluded   = in_array($post->ID, array_map('intval', (array) $audit_excluded_ids), true);
            $general_settings_mb = tam_rank_cached_option('tam_rank_general_settings', array());
            $noindex_excluded    = !empty($general_settings_mb['audit_exclude_noindex']) && !empty($noindex);
            if ($is_audit_excluded || $noindex_excluded): ?>
                <div class="tr-audit-excluded-notice">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-width="2"/><path d="M12 16H12.01M12 8V12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
                    <?php tamrank_e('post_excluded_from_audit', 'This page is excluded from the SEO audit'); ?>
                    <?php if ($noindex_excluded && !$is_audit_excluded): ?>
                        <span class="tr-audit-excluded-reason">(noindex)</span>
                    <?php endif; ?>
                </div>
            <?php endif; ?>
            <!-- Tab Navigation -->
            <div class="tam-meta-tabs">
                <button type="button" class="tam-meta-tab active" data-tab="seo">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <circle cx="11" cy="11" r="8" stroke="currentColor" stroke-width="2" />
                        <path d="M21 21L16.65 16.65" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
                    </svg>
                    <?php tamrank_e('tab_seo', 'SEO'); ?>
                </button>
                <button type="button" class="tam-meta-tab" data-tab="content">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path
                            d="M14 2H6C5.46957 2 4.96086 2.21071 4.58579 2.58579C4.21071 2.96086 4 3.46957 4 4V20C4 20.5304 4.21071 21.0391 4.58579 21.4142C4.96086 21.7893 5.46957 22 6 22H18C18.5304 22 19.0391 21.7893 19.4142 21.4142C19.7893 21.0391 20 20.5304 20 20V8L14 2Z"
                            stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
                        <polyline points="14 2 14 8 20 8" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                            stroke-linejoin="round" />
                        <line x1="16" y1="13" x2="8" y2="13" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                            stroke-linejoin="round" />
                        <line x1="16" y1="17" x2="8" y2="17" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                            stroke-linejoin="round" />
                        <polyline points="10 9 9 9 8 9" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                            stroke-linejoin="round" />
                    </svg>
                    <?php tamrank_e('tab_content', 'Content'); ?>
                </button>
                <button type="button" class="tam-meta-tab" data-tab="schema">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path d="M12 2L2 7L12 12L22 7L12 2Z" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                            stroke-linejoin="round" />
                        <path d="M2 17L12 22L22 17" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                            stroke-linejoin="round" />
                        <path d="M2 12L12 17L22 12" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                            stroke-linejoin="round" />
                    </svg>
                    <?php tamrank_e('tab_schema', 'Schema'); ?>
                </button>
                <button type="button" class="tam-meta-tab" data-tab="social">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path
                            d="M18 2H15C13.6739 2 12.4021 2.52678 11.4645 3.46447C10.5268 4.40215 10 5.67392 10 7V10H7V14H10V22H14V14H17L18 10H14V7C14 6.73478 14.1054 6.48043 14.2929 6.29289C14.4804 6.10536 14.7348 6 15 6H18V2Z"
                            stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
                    </svg>
                    <?php tamrank_e('tab_social', 'Social'); ?>
                </button>
                <?php
                // "Request indexing" — the same action as the row action in the
                // posts list, offered where the editing actually happens (Frans,
                // 19 Aug), on the tab bar's own line and pushed to the far right
                // (Sam, 26 Aug). It acts on the page, not on one tab's fields, so
                // the row that is always visible is where it belongs. Renders
                // nothing on a draft/private page, on a non-public type or
                // without Search Console connected.
                if (class_exists('TamRank_Indexing')) {
                    TamRank_Indexing::render_edit_screen_action('post', $post->ID);
                }
                ?>
            </div>

            <!-- SEO Tab Content -->
            <div class="tam-meta-tab-content active" id="tam-tab-seo">
                <div class="tam-seo-layout">
                    <!-- Left Column: Optimization Score & Tips (Sticky) -->
                    <div class="tam-seo-sidebar">
                        <!-- Optimization Score -->
                        <div class="tam-score-card">
                            <h3 class="tam-score-card__title">
                                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="var(--tr-color-primary)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                    <path d="M3 3V21H21" />
                                    <path d="M18 9L13 14L9 10L3 16" />
                                </svg>
                                <?php tamrank_e('optimization_score', 'Optimization Score'); ?>
                            </h3>
                            <div class="tam-score-card__value">
                                <span id="live-score-value-main" class="tam-score-card__number" style="color: <?php echo esc_attr($this->get_score_color($live_score)); ?>;">
                                    <?php echo intval($live_score); ?>%
                                </span>
                            </div>
                            <div class="tam-score-card__bar">
                                <div id="live-score-bar-main" class="tam-score-card__fill" style="width: <?php echo esc_attr(intval($live_score)); ?>%; background: <?php echo esc_attr($this->get_score_color($live_score)); ?>;">
                                </div>
                            </div>
                            <p class="tam-score-card__hint">
                                <?php tamrank_e('live_update_message', 'Updates live as you type'); ?>
                            </p>
                        </div>

                        <!-- SEO Tips -->
                        <div id="seo-tips" class="tam-tips-card">
                            <h4 class="tam-tips-card__title">
                                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--tr-color-status-attention)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                    <path d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z" />
                                </svg>
                                <?php tamrank_e('improvements', 'Improvements'); ?>
                            </h4>
                            <div id="seo-tips-list" class="tam-tips-card__list">
                                <p class="tam-tips-card__empty">
                                    <?php tamrank_e('fill_fields_for_tips', 'Fill in the fields to receive tips'); ?>
                                </p>
                            </div>
                        </div>
                    </div>

                    <!-- Right Column: Form Fields -->
                    <?php
                    // Separate concerns — section visibility (FREE toggle) vs the
                    // AI generator gate. The generator UI + AJAX moved to tam-rank-pro
                    // (cluster-7a strip); PRO answers `tamrank_meta_ai_enabled` with the
                    // licence check. FREE-only → filter false → upsell shown, no buttons.
                    $show_ai_section = (bool) get_option('tam_rank_ai_enabled', true);
                    $show_ai_buttons = $show_ai_section && apply_filters('tamrank_meta_ai_enabled', false);
                    ?>
                    <div class="tam-seo-fields">

                        <!-- 1. Focus Zoekwoord -->
                        <div class="tam-field-group">
                            <label for="_tam_rank_focus_keyword">
                                <?php tamrank_e('focus_keyword', 'Focus Keyword'); ?>
                                <?php echo tamrank_render_info_tooltip(tamrank__('focus_keyword_tooltip', 'The main keyword you want this page to rank for. Use this word in your title, description and content for better visibility.')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- returns escaped, plugin-generated tooltip markup (helper escapes text + attributes internally) ?>
                            </label>
                            <input type="text" id="_tam_rank_focus_keyword" name="_tam_rank_focus_keyword"
                                value="<?php echo esc_attr($focus_keyword); ?>" class="tam-input">
                        </div>

                        <!-- 2. Meta Titel -->
                        <div class="tam-field-group">
                            <div class="tam-field-header">
                                <label for="_tam_rank_meta_title">
                                    <?php tamrank_e('meta_title', 'Meta Title'); ?>
                                    <?php echo tamrank_render_info_tooltip(tamrank__('meta_title_tooltip', 'The title that appears in search results. Keep it between 30-60 characters for best display.')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- returns escaped, plugin-generated tooltip markup (helper escapes text + attributes internally) ?>
                                </label>
                            </div>
                            <input type="text" id="_tam_rank_meta_title" name="_tam_rank_meta_title"
                                value="<?php echo esc_attr($meta_title); ?>" class="tam-input" data-char-count="true"
                                data-optimal-min="30" data-optimal-max="60">
                            <?php if ($show_ai_buttons): ?>
                            <div class="tr-field-card__footer">
                                <div class="char-counter" id="title-counter"></div>
                                <button type="button"
                                        class="tr-btn tr-btn--ai tr-btn--sm"
                                        id="tr-generate-title"
                                        data-type="title"
                                        data-post-id="<?php echo esc_attr($post->ID); ?>">
                                    &#10022; <?php tamrank_e('generate_with_ai', 'Generate with AI'); ?>
                                </button>
                            </div>
                            <?php endif; ?>
                            <?php $this->render_variable_buttons('_tam_rank_meta_title'); ?>
                        </div>

                        <!-- 3. Meta Beschrijving -->
                        <div class="tam-field-group">
                            <div class="tam-field-header">
                                <label for="_tam_rank_meta_description">
                                    <?php tamrank_e('meta_description', 'Meta Description'); ?>
                                    <?php echo tamrank_render_info_tooltip(tamrank__('meta_description_tooltip', 'A short summary of the page content. This text appears under the title in search results and helps users decide whether to click on your link.')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- returns escaped, plugin-generated tooltip markup (helper escapes text + attributes internally) ?>
                                </label>
                            </div>
                            <textarea id="_tam_rank_meta_description" name="_tam_rank_meta_description" rows="4"
                                class="tam-input tam-textarea" data-char-count="true" data-optimal-min="120"
                                data-optimal-max="160"><?php echo esc_textarea($meta_description); ?></textarea>
                            <?php if ($show_ai_buttons): ?>
                            <div class="tr-field-card__footer">
                                <div class="char-counter" id="description-counter"></div>
                                <label for="tr-writing-style" class="tr-style-selector__label"><?php tamrank_e('style_label', 'Style:'); ?></label>
                                <select id="tr-writing-style" class="tr-style-selector__select">
                                    <option value="professional"><?php tamrank_e('style_professional', 'Professional'); ?></option>
                                    <option value="casual"><?php tamrank_e('style_casual', 'Casual'); ?></option>
                                    <option value="persuasive"><?php tamrank_e('style_persuasive', 'Persuasive'); ?></option>
                                </select>
                                <button type="button"
                                        class="tr-btn tr-btn--ai tr-btn--sm"
                                        id="tr-generate-description"
                                        data-type="description"
                                        data-post-id="<?php echo esc_attr($post->ID); ?>">
                                    &#10022; <?php tamrank_e('generate_with_ai', 'Generate with AI'); ?>
                                </button>
                            </div>
                            <?php endif; ?>
                            <?php $this->render_variable_buttons('_tam_rank_meta_description'); ?>
                        </div>

                        <?php if ($show_ai_buttons): ?>
                        <!-- AI Containers (loading, error, suggestions) -->
                        <div class="tam-ai-loading" style="display: none;">
                            <div class="tam-ai-loading-spinner"></div>
                            <span><?php tamrank_e('ai_generating', 'AI is generating...'); ?></span>
                        </div>
                        <div class="tam-ai-error" style="display: none;">
                            <span class="tam-ai-error-icon">&#9888;&#65039;</span>
                            <span class="tam-ai-error-message"></span>
                            <button type="button" class="tam-ai-error-close">&times;</button>
                        </div>
                        <div class="tam-ai-suggestions-container" style="display: none;">
                            <div class="tam-ai-suggestions-header">
                                <h5><?php tamrank_e('ai_suggestions', 'AI Suggestions'); ?></h5>
                                <button type="button" class="tam-ai-close-suggestions">&times;</button>
                            </div>
                            <div class="tam-ai-suggestions-list"></div>
                            <div class="tam-ai-suggestions-footer">
                                <button type="button" class="tr-btn tr-btn--secondary tr-btn--sm tam-ai-regenerate-btn">
                                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                        <path d="M21 2v6h-6M3 12a9 9 0 0 1 15-6.7L21 8M3 22v-6h6M21 12a9 9 0 0 1-15 6.7L3 16"/>
                                    </svg>
                                    <?php tamrank_e('regenerate', 'Regenerate'); ?>
                                </button>
                            </div>
                        </div>
                        <?php endif; ?>

                        <?php if ($show_ai_section && !$show_ai_buttons): ?>
                        <!-- AI Meta Generator PRO upsell -->
                        <div class="tr-inline-tip" style="border-style: solid;">
                            <div class="tr-inline-tip__icon">
                                <svg fill="none" viewBox="0 0 24 24" stroke-width="2"><path d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z"/></svg>
                            </div>
                            <div class="tr-inline-tip__text">
                                <strong><?php tamrank_e('ai_meta_generator', 'AI Meta Generator'); ?></strong> &mdash; <?php tamrank_e('ai_meta_generator_desc', 'Generate optimized titles and descriptions in 4 writing styles, tailored to your brand.'); ?>
                            </div>
                            <span class="tr-badge tr-badge--pro">PRO</span>
                            <a href="<?php echo esc_url(tam_rank_get_upgrade_url('meta_box', 'ai_meta_generator')); ?>" class="tr-inline-tip__link" target="_blank" rel="noopener"><?php tamrank_e('view_pro', 'View PRO'); ?> &rarr;</a>
                        </div>
                        <?php endif; ?>

                        <!-- 4. URL Slug + Canonical URL (naast elkaar) -->
                        <div class="tam-seo-fields-row">
                            <!-- URL Slug -->
                            <div class="tam-field-group">
                                <div class="tam-field-header">
                                    <label for="_tam_rank_custom_slug">
                                        <?php tamrank_e('url_slug', 'URL Slug'); ?>
                                        <?php echo tamrank_render_info_tooltip(tamrank__('url_slug_tooltip', 'The last part of the URL of this page. A short, descriptive slug helps search engines and visitors understand what the page is about. When changed, a 301 redirect is automatically created.')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- returns escaped, plugin-generated tooltip markup (helper escapes text + attributes internally) ?>
                                    </label>
                                </div>
                                <input type="text" id="_tam_rank_custom_slug" name="_tam_rank_custom_slug"
                                    value="<?php echo esc_attr($custom_slug ?: $current_slug); ?>" class="tam-input"
                                    placeholder="<?php echo esc_attr($current_slug); ?>">
                            </div>

                            <!-- Canonical URL -->
                            <div class="tam-field-group">
                                <div class="tam-field-header">
                                    <label for="_tam_rank_canonical">
                                        <?php tamrank_e('canonical_url', 'Canonical URL'); ?>
                                        <?php echo tamrank_render_info_tooltip(tamrank__('canonical_url_tooltip', 'The canonical URL helps search engines understand which version of a page is the main version. Only use this for duplicate content to prevent search engines from deducting points.')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- returns escaped, plugin-generated tooltip markup (helper escapes text + attributes internally) ?>
                                    </label>
                                </div>
                                <input type="url" id="_tam_rank_canonical" name="_tam_rank_canonical"
                                    value="<?php echo esc_attr($canonical); ?>" class="tam-input"
                                    placeholder="<?php echo esc_url(get_permalink($post->ID)); ?>">
                                <span class="tr-field-card__hint"><?php tamrank_e('leave_empty_for_auto', 'Leave empty for automatic'); ?></span>
                            </div>
                        </div>

                        <!-- 5. Google Preview -->
                        <div class="tam-field-group">
                            <h4 class="tam-section-title"><?php tamrank_e('google_preview', 'Google Preview'); ?></h4>
                            <div class="google-preview">
                                <div class="preview-url"><?php echo esc_url(get_permalink($post->ID)); ?></div>
                                <div class="preview-title" id="preview-title">
                                    <?php echo esc_html($meta_title ?: $post->post_title); ?>
                                </div>
                                <div class="preview-description" id="preview-description">
                                    <?php echo esc_html($meta_description); ?>
                                </div>
                            </div>
                        </div>

                        <!-- 6. Secondary Keywords (FREE) -->
                        <?php
                        $keywords_data = TamRank_Keywords::get_keywords($post->ID);
                        $secondary_keywords = $keywords_data['secondary'];
                        $secondary_enabled = get_post_meta($post->ID, '_tamrank_secondary_keywords_enabled', true);
                        // Default to disabled (hidden) when not set yet
                        if ($secondary_enabled === '') {
                            $secondary_enabled = '0';
                        }
                        ?>
                        <div class="tam-field-group tr-secondary-kw">
                            <div class="tr-secondary-kw__header">
                                <div class="tr-secondary-kw__title">
                                    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                                        stroke-width="2" class="tr-icon--accent">
                                        <path
                                            d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z" />
                                    </svg>
                                    <label>
                                        <?php tamrank_e('secondary_keywords', 'Secondary Keywords'); ?>
                                    </label>
                                </div>

                                <label class="tamrank-toggle-switch">
                                    <span class="tamrank-toggle-switch__label"><?php tamrank_e('enable_secondary_keywords', 'Enable'); ?></span>
                                    <div class="tamrank-toggle-switch__track">
                                        <input type="checkbox" id="tr-secondary-kw-toggle"
                                            name="_tamrank_secondary_keywords_enabled" value="1" <?php checked($secondary_enabled, '1'); ?>>
                                        <span class="tamrank-toggle-slider"></span>
                                    </div>
                                </label>
                            </div>

                            <p class="tr-secondary-kw__desc">
                                <?php tamrank_e('secondary_keywords_description', 'Optimize for up to 4 additional related keywords. Great for targeting long-tail variations and related terms.'); ?>
                            </p>

                                <div id="tr-secondary-kw-fields"
                                    class="tr-secondary-kw__fields<?php echo $secondary_enabled == '1' ? ' tr-secondary-kw__fields--visible' : ''; ?>">
                                    <div id="tamrank-secondary-keywords-container">
                                        <?php
                                        // Show 4 keyword slots
                                        for ($i = 0; $i < 4; $i++):
                                            $value = isset($secondary_keywords[$i]) ? $secondary_keywords[$i] : '';
                                            ?>
                                            <div class="tamrank-secondary-keyword-item">
                                                <div class="tamrank-secondary-keyword-item__row">
                                                    <span class="tr-secondary-kw__badge">
                                                        <?php echo esc_html($i + 1); ?>
                                                    </span>
                                                    <input type="text" name="_tamrank_secondary_keywords[]"
                                                        value="<?php echo esc_attr($value); ?>"
                                                        placeholder="<?php echo esc_attr(sprintf(tamrank__('secondary_keyword_placeholder', 'Secondary keyword %d (optional)'), $i + 1)); ?>"
                                                        class="tam-input tamrank-secondary-keyword-input">
                                                    <?php if ($i > 0): ?>
                                                        <button type="button" class="tamrank-clear-keyword"
                                                            aria-label="<?php echo esc_attr(tamrank__('clear_keyword', 'Clear keyword')); ?>"
                                                            data-tr-tooltip="<?php echo esc_attr(tamrank__('clear_keyword', 'Clear keyword')); ?>">
                                                            <svg width="14" height="14" viewBox="0 0 24 24" fill="none"
                                                                stroke="currentColor" stroke-width="2">
                                                                <path d="M18 6L6 18M6 6l12 12" />
                                                            </svg>
                                                        </button>
                                                    <?php endif; ?>
                                                </div>
                                            </div>
                                        <?php endfor; ?>
                                    </div>

                                    <!-- Keyword Suggestions (dynamically updated by JavaScript) -->
                                    <div id="tamrank-suggestions-box" class="tr-suggestions-box"
                                        <?php echo empty($focus_keyword) ? 'style="display: none;"' : ''; ?>>
                                        <span class="tr-suggestions-box__label"><?php tamrank_e('keyword_suggestions', 'Suggestions:'); ?></span>
                                        <div class="tamrank-keyword-suggestions">
                                            <?php
                                            if (!empty($focus_keyword)) {
                                                $suggestions = TamRank_Keywords::get_keyword_suggestions($focus_keyword);
                                                foreach ($suggestions as $suggestion):
                                                    ?>
                                                    <button type="button" class="tamrank-add-suggestion"
                                                        data-keyword="<?php echo esc_attr($suggestion); ?>">
                                                        + <?php echo esc_html($suggestion); ?>
                                                    </button>
                                                    <?php
                                                endforeach;
                                            }
                                            ?>
                                        </div>
                                    </div>
                                </div><!-- #tr-secondary-kw-fields -->
                        </div>

                        <!-- 7. Robot Instructies -->
                        <div class="tr-danger-separator">
                            <span class="tr-danger-separator__label"><?php tamrank_e('danger_zone', 'Danger Zone'); ?></span>
                        </div>
                        <div class="tam-field-group tr-robots">
                            <label>
                                <?php tamrank_e('robot_instructions', 'Robot Instructions'); ?>
                                <?php echo tamrank_render_info_tooltip(tamrank__('robot_instructions_help', 'Decide how search engines handle this page. Noindex hides it from results; Nofollow tells engines not to follow links.')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- returns escaped, plugin-generated tooltip markup (helper escapes text + attributes internally) ?>
                            </label>
                            <div class="tr-robots__grid">
                                <?php
                                tamrank_render_robots_checkbox(array(
                                    'id'      => '_tam_rank_noindex',
                                    'name'    => '_tam_rank_noindex',
                                    'checked' => (bool) $noindex,
                                    'label'   => tamrank__('noindex', 'Noindex'),
                                    'desc'    => tamrank__('noindex_help', 'Hide this page from search engines'),
                                ));

                                tamrank_render_robots_checkbox(array(
                                    'id'      => '_tam_rank_nofollow',
                                    'name'    => '_tam_rank_nofollow',
                                    'checked' => (bool) $nofollow,
                                    'label'   => tamrank__('nofollow', 'Nofollow'),
                                    'desc'    => tamrank__('nofollow_help', 'Don\'t follow links on this page'),
                                ));
                                ?>
                            </div>

                            <?php tamrank_render_advanced_robots_fields($robots_directives, 'post'); ?>
                        </div>

                        <?php // AI containers moved above URL/Canonical fields ?>

                    </div>
                </div>
            </div><!-- End SEO Tab Content -->

            <!-- Content Tab Content -->
            <div class="tam-meta-tab-content" id="tam-tab-content">
                <?php $this->render_content_tab($post); ?>
            </div><!-- End Content Tab Content -->

            <!-- Schema Tab Content -->
            <div class="tam-meta-tab-content" id="tam-tab-schema">
                <?php $this->render_schema_tab_content($post); ?>
            </div><!-- End Schema Tab Content -->

            <!-- Social Tab Content -->
            <div class="tam-meta-tab-content" id="tam-tab-social">
                <?php $this->render_social_tab_content($post); ?>
            </div><!-- End Social Tab Content -->

            <?php
            /**
             * Fires at the bottom of the meta box. Add-ons (e.g. the PRO change
             * tracker) hook this to render their own panels, such as the change
             * history timeline.
             *
             * @param WP_Post $post The current post.
             */
            do_action('tamrank_meta_change_history', $post);
            ?>

        </div><!-- End tam-rank-meta-box -->


        <?php ob_start(); ?>
            jQuery(document).ready(function ($) {
                // Character counter function with input border validation
                function updateCharCounter(input, counterId) {
                    const $input = $(input);
                    const $counter = $('#' + counterId);
                    const length = $input.val().length;
                    const optimalMin = parseInt($input.data('optimal-min')) || 0;
                    const optimalMax = parseInt($input.data('optimal-max')) || 0;

                    let counterClass = 'tam-success';
                    let inputClass = 'tam-valid';
                    let message = length + ' <?php echo esc_js(tamrank__('metabox_chars_suffix', 'characters')); ?>';

                    if (length === 0) {
                        // Empty input
                        $input.removeClass('tam-valid tam-warning tam-error');
                        $counter.removeClass('tam-success tam-warning tam-error').text('');
                        return;
                    } else if (length < optimalMin) {
                        counterClass = 'tam-warning';
                        inputClass = 'tam-warning';
                        message = length + ' <?php echo esc_js(tamrank__('metabox_chars_suffix', 'characters')); ?>';
                    } else if (length > optimalMax) {
                        counterClass = 'tam-warning';
                        inputClass = 'tam-warning';
                        message = length + ' <?php echo esc_js(tamrank__('metabox_chars_suffix', 'characters')); ?>';
                    } else {
                        message = length + ' <?php echo esc_js(tamrank__('metabox_chars_suffix', 'characters')); ?>';
                    }

                    // Update counter
                    $counter.removeClass('tam-success tam-warning tam-error').addClass(counterClass).text(message);

                    // Update input border color
                    $input.removeClass('tam-valid tam-warning tam-error').addClass(inputClass);
                }

                // Initialize character counters
                updateCharCounter('#_tam_rank_meta_title', 'title-counter');
                updateCharCounter('#_tam_rank_meta_description', 'description-counter');

                // Update preview in real-time
                $('#_tam_rank_meta_title').on('input', function () {
                    const title = $(this).val() || $('#title').val();
                    $('#preview-title').text(title);
                    updateCharCounter(this, 'title-counter');
                });

                $('#_tam_rank_meta_description').on('input', function () {
                    $('#preview-description').text($(this).val());
                    updateCharCounter(this, 'description-counter');
                });

                // Update slug preview with validation
                $('#_tam_rank_custom_slug').on('input', function () {
                    let slug = $(this).val();

                    // Auto-sanitize: convert to lowercase, replace spaces with hyphens, remove special chars
                    slug = slug.toLowerCase()
                        .replace(/\s+/g, '-')           // Replace spaces with hyphens
                        .replace(/[^a-z0-9-]/g, '')     // Remove special characters
                        .replace(/-+/g, '-')            // Replace multiple hyphens with single
                        .replace(/^-|-$/g, '');         // Remove leading/trailing hyphens

                    // Update the input value with sanitized slug
                    if ($(this).val() !== slug) {
                        $(this).val(slug);
                    }

                    // Update preview
                    const previewSlug = slug || $(this).attr('placeholder');
                    $('#slug-preview').text(previewSlug);

                    // Validate URL Slug: check if focus keyword is in URL
                    const focusKeyword = $('#_tam_rank_focus_keyword').val();
                    const $input = $(this);

                    if (slug.length === 0) {
                        // Empty slug - no colored border
                        $input.removeClass('tam-valid tam-warning tam-error');
                    } else if (focusKeyword && slug.includes(focusKeyword.toLowerCase().replace(/\s+/g, '-'))) {
                        // Keyword found in URL - green border
                        $input.removeClass('tam-warning tam-error').addClass('tam-valid');
                    } else if (focusKeyword && slug.length > 0) {
                        // Keyword NOT found in URL - orange border
                        $input.removeClass('tam-valid tam-error').addClass('tam-warning');
                    } else {
                        // No keyword set but has slug - no colored border
                        $input.removeClass('tam-valid tam-warning tam-error');
                    }

                    updateLiveScore();
                });

                // Focus Keyword validation
                $('#_tam_rank_focus_keyword').on('input', function () {
                    const $input = $(this);
                    const keyword = $input.val().trim();

                    if (keyword.length === 0) {
                        // Empty - no colored border
                        $input.removeClass('tam-valid tam-warning tam-error');
                    } else {
                        // Has keyword - green border
                        $input.removeClass('tam-warning tam-error').addClass('tam-valid');
                    }

                    // Re-validate URL slug when keyword changes
                    $('#_tam_rank_custom_slug').trigger('input');

                    updateLiveScore();
                });

                // =============================================
                // SECONDARY KEYWORDS
                // =============================================

                // Generate keyword suggestions based on primary keyword
                function generateKeywordSuggestions(primaryKeyword) {
                    if (!primaryKeyword || primaryKeyword.length < 2) {
                        return [];
                    }

                    const suggestions = [];
                    const currentYear = new Date().getFullYear();
                    const lowerKeyword = primaryKeyword.toLowerCase();

                    // "best" variation
                    if (lowerKeyword.indexOf('best') === -1) {
                        suggestions.push('best ' + primaryKeyword);
                    }

                    // Year variation
                    if (primaryKeyword.indexOf(currentYear.toString()) === -1) {
                        suggestions.push(primaryKeyword + ' ' + currentYear);
                    }

                    // "how to" variation
                    if (lowerKeyword.indexOf('how') === -1 && lowerKeyword.indexOf('what') === -1) {
                        suggestions.push('how to ' + primaryKeyword);
                    }

                    // "tips" variation
                    if (lowerKeyword.indexOf('tips') === -1) {
                        suggestions.push(primaryKeyword + ' tips');
                    }

                    return suggestions.slice(0, 4);
                }

                // Update suggestions when primary keyword changes
                function updateKeywordSuggestions() {
                    const primaryKeyword = $('#_tam_rank_focus_keyword').val().trim();
                    const $suggestionsBox = $('#tamrank-suggestions-box');

                    if (!$suggestionsBox.length) {
                        return; // Element does not exist on this screen
                    }

                    if (!primaryKeyword) {
                        $suggestionsBox.hide();
                        return;
                    }

                    const suggestions = generateKeywordSuggestions(primaryKeyword);
                    const $container = $('.tamrank-keyword-suggestions');

                    if (suggestions.length === 0) {
                        $suggestionsBox.hide();
                        return;
                    }

                    // Show and populate
                    $suggestionsBox.show();
                    $container.empty();

                    suggestions.forEach(function (suggestion) {
                        $container.append(
                            $('<button>', {
                                'type': 'button',
                                'class': 'tamrank-add-suggestion',
                                'data-keyword': suggestion,
                                'text': '+ ' + suggestion
                            })
                        );
                    });
                }

                // Update suggestions on primary keyword input
                $('#_tam_rank_focus_keyword').on('input', updateKeywordSuggestions);

                // Initialize on page load
                setTimeout(updateKeywordSuggestions, 100);

                // Toggle secondary keywords on/off
                $('#tr-secondary-kw-toggle').on('change', function () {
                    const isEnabled = $(this).is(':checked');
                    const $content = $('#tr-secondary-kw-fields');

                    if (isEnabled) {
                        $content.slideDown(300);
                    } else {
                        $content.slideUp(300);
                    }
                });

                // Clear keyword button
                $(document).on('click', '.tamrank-clear-keyword', function () {
                    $(this).closest('.tamrank-secondary-keyword-item').find('input').val('').trigger('input');
                });

                // Add suggestion chips
                $(document).on('click', '.tamrank-add-suggestion', function () {
                    const keyword = $(this).data('keyword');

                    // Find first empty secondary keyword input
                    const $emptyInput = $('.tamrank-secondary-keyword-input').filter(function () {
                        return !$(this).val().trim();
                    }).first();

                    if ($emptyInput.length) {
                        $emptyInput.val(keyword).trigger('input');

                        // Visual feedback
                        $(this).addClass('tamrank-add-suggestion--added').text('✓ <?php echo esc_js(tamrank__('metabox_keyword_added', 'Added')); ?>');

                        setTimeout(() => {
                            $(this).fadeOut(200);
                        }, 1000);
                    } else {
                        alert('<?php echo esc_js(tamrank__('all_keyword_slots_filled', 'All keyword slots are filled')); ?>');
                    }
                });

                // Validate secondary keywords on input
                $(document).on('input', '.tamrank-secondary-keyword-input', function () {
                    const $input = $(this);
                    const value = $input.val().trim();

                    if (value.length === 0) {
                        $input.removeClass('tam-valid tam-warning tam-error');
                    } else if (value.length < 2) {
                        $input.removeClass('tam-valid').addClass('tam-error');
                    } else {
                        $input.removeClass('tam-error').addClass('tam-valid');
                    }
                });

                // Update from post title if meta title is empty
                $('#title').on('input', function () {
                    if (!$('#_tam_rank_meta_title').val()) {
                        $('#preview-title').text($(this).val());
                    }
                });

                // Score color helper (design system)
                function getScoreColorSeo(score) {
                    var style = getComputedStyle(document.documentElement);
                    if (score >= 80) return style.getPropertyValue('--tr-color-status-excellent').trim();
                    if (score >= 60) return style.getPropertyValue('--tr-color-status-good').trim();
                    if (score >= 40) return style.getPropertyValue('--tr-color-status-attention').trim();
                    return style.getPropertyValue('--tr-color-status-improve').trim();
                }

                // Live Score Calculator
                function updateLiveScore() {
                    let score = 0;
                    const maxScore = 50; // Updated to 50 for better distribution

                    // Get field values
                    const metaTitle = $('#_tam_rank_meta_title').val() || $('#title').val();
                    const metaDescription = $('#_tam_rank_meta_description').val();
                    const focusKeyword = $('#_tam_rank_focus_keyword').val();
                    const customSlug = $('#_tam_rank_custom_slug').val();

                    // Check Meta Title (15 points max)
                    if (metaTitle) {
                        const titleLength = metaTitle.length;

                        // Length check (10 points)
                        if (titleLength >= 30 && titleLength <= 60) {
                            score += 10;
                        } else if (titleLength > 0 && titleLength < 30) {
                            score += 3; // Too short
                        } else if (titleLength > 60) {
                            score += 5; // Too long but still has content
                        }

                        // Focus keyword in title (5 points)
                        if (focusKeyword && metaTitle.toLowerCase().includes(focusKeyword.toLowerCase())) {
                            score += 5;
                        }
                    }

                    // Check Meta Description (15 points max)
                    if (metaDescription) {
                        const descLength = metaDescription.length;

                        // Length check (10 points)
                        if (descLength >= 120 && descLength <= 160) {
                            score += 10;
                        } else if (descLength > 0 && descLength < 120) {
                            score += 3; // Too short
                        } else if (descLength > 160) {
                            score += 5; // Too long but still has content
                        }

                        // Focus keyword in description (5 points)
                        if (focusKeyword && metaDescription.toLowerCase().includes(focusKeyword.toLowerCase())) {
                            score += 5;
                        }
                    }

                    // Focus Keyword Set (10 points)
                    if (focusKeyword) {
                        score += 10;
                    }

                    // URL Structure (10 points)
                    if (customSlug) {
                        score += 5;

                        // Bonus if focus keyword in URL
                        if (focusKeyword && customSlug.toLowerCase().includes(focusKeyword.toLowerCase().replace(/\s+/g, '-'))) {
                            score += 5;
                        }
                    }

                    // Convert to 0-100 scale
                    const percentage = Math.min(100, Math.round((score / maxScore) * 100));

                    // Update color based on score
                    let color = getScoreColorSeo(percentage);

                    // Update main meta box score (in main content area)
                    $('#live-score-value-main').text(percentage + '%').css('color', color);
                    $('#live-score-bar-main').css('width', percentage + '%').css('background', color);

                    // Update sidebar score (in audit meta box)
                    $('#live-score-value').text(percentage + '%').css('color', color);
                    $('#live-score-bar').css('width', percentage + '%').css('background', color);

                    // Update SEO tips
                    updateSeoTips(metaTitle, metaDescription, focusKeyword, customSlug);
                }

                // Generate SEO tips based on current state
                function updateSeoTips(metaTitle, metaDescription, focusKeyword, customSlug) {
                    const tips = [];

                    // Meta title tips
                    const titleLength = metaTitle ? metaTitle.length : 0;
                    if (!metaTitle || titleLength === 0) {
                        tips.push({ passed: false, text: '<?php echo esc_js(tamrank__('meta_title', 'Meta Title')); ?>', detail: '<?php echo esc_js(tamrank__('not_set', 'Not set')); ?>' });
                    } else if (titleLength < 30) {
                        tips.push({ passed: false, text: '<?php echo esc_js(tamrank__('meta_title', 'Meta Title')); ?>', detail: '<?php echo esc_js(tamrank__('meta_title_too_short', 'Meta Title too short (less than 30 characters)')); ?> (' + titleLength + '/30)' });
                    } else if (titleLength > 60) {
                        tips.push({ passed: false, text: '<?php echo esc_js(tamrank__('meta_title', 'Meta Title')); ?>', detail: '<?php echo esc_js(tamrank__('meta_title_too_long', 'Meta Title too long (more than 60 characters)')); ?> (' + titleLength + '/60)' });
                    } else {
                        tips.push({ passed: true, text: '<?php echo esc_js(tamrank__('meta_title', 'Meta Title')); ?>', detail: titleLength + ' <?php echo esc_js(tamrank__('characters', 'characters')); ?>' });
                    }

                    // Meta description tips
                    const descLength = metaDescription ? metaDescription.length : 0;
                    if (!metaDescription || descLength === 0) {
                        tips.push({ passed: false, text: '<?php echo esc_js(tamrank__('meta_description', 'Meta Description')); ?>', detail: '<?php echo esc_js(tamrank__('not_set', 'Not set')); ?>' });
                    } else if (descLength < 120) {
                        tips.push({ passed: false, text: '<?php echo esc_js(tamrank__('meta_description', 'Meta Description')); ?>', detail: '<?php echo esc_js(tamrank__('desc_too_short', 'Too short (less than 120 characters)')); ?> (' + descLength + '/120)' });
                    } else if (descLength > 160) {
                        tips.push({ passed: false, text: '<?php echo esc_js(tamrank__('meta_description', 'Meta Description')); ?>', detail: '<?php echo esc_js(tamrank__('desc_too_long', 'Too long (more than 160 characters)')); ?> (' + descLength + '/160)' });
                    } else {
                        tips.push({ passed: true, text: '<?php echo esc_js(tamrank__('meta_description', 'Meta Description')); ?>', detail: descLength + ' <?php echo esc_js(tamrank__('characters', 'characters')); ?>' });
                    }

                    // URL slug tip
                    if (!customSlug || customSlug.length === 0) {
                        tips.push({ passed: false, text: '<?php echo esc_js(tamrank__('url_slug', 'URL Slug')); ?>', detail: '<?php echo esc_js(tamrank__('not_set', 'Not set')); ?>' });
                    } else {
                        tips.push({ passed: true, text: '<?php echo esc_js(tamrank__('url_slug', 'URL Slug')); ?>', detail: '<?php echo esc_js(tamrank__('set', 'Set')); ?>' });
                    }

                    // Focus keyword tips
                    if (!focusKeyword) {
                        tips.push({ passed: false, text: '<?php echo esc_js(tamrank__('focus_keyword', 'Focus Keyword')); ?>', detail: '<?php echo esc_js(tamrank__('no_focus_keyword', 'No focus keyword set')); ?>' });
                    } else {
                        tips.push({ passed: true, text: '<?php echo esc_js(tamrank__('focus_keyword', 'Focus Keyword')); ?>', detail: '<?php echo esc_js(tamrank__('focus_keyword_set', 'Focus keyword set')); ?>' });

                        if (metaTitle && metaTitle.toLowerCase().includes(focusKeyword.toLowerCase())) {
                            tips.push({ passed: true, text: '<?php echo esc_js(tamrank__('title_contains_keyword', 'Keyword in Title')); ?>', detail: '<?php echo esc_js(tamrank__('found', 'Found')); ?>' });
                        } else {
                            tips.push({ passed: false, text: '<?php echo esc_js(tamrank__('title_contains_keyword', 'Keyword in Title')); ?>', detail: '<?php echo esc_js(tamrank__('not_found', 'Not found')); ?>' });
                        }

                        if (metaDescription && metaDescription.toLowerCase().includes(focusKeyword.toLowerCase())) {
                            tips.push({ passed: true, text: '<?php echo esc_js(tamrank__('description_contains_keyword', 'Keyword in Description')); ?>', detail: '<?php echo esc_js(tamrank__('found', 'Found')); ?>' });
                        } else {
                            tips.push({ passed: false, text: '<?php echo esc_js(tamrank__('description_contains_keyword', 'Keyword in Description')); ?>', detail: '<?php echo esc_js(tamrank__('not_found', 'Not found')); ?>' });
                        }

                        // Check if focus keyword is in URL
                        if (customSlug && customSlug.toLowerCase().includes(focusKeyword.toLowerCase().replace(/\s+/g, '-'))) {
                            tips.push({ passed: true, text: '<?php echo esc_js(tamrank__('url_contains_keyword', 'Keyword in URL')); ?>', detail: '<?php echo esc_js(tamrank__('found', 'Found')); ?>' });
                        } else {
                            tips.push({ passed: false, text: '<?php echo esc_js(tamrank__('url_contains_keyword', 'Keyword in URL')); ?>', detail: '<?php echo esc_js(tamrank__('not_found', 'Not found')); ?>' });
                        }
                    }

                    // Render tips
                    let html = '<ul class="tam-tips-list">';
                    tips.forEach(function (tip) {
                        const cls = tip.passed ? 'tam-tip--passed' : 'tam-tip--failed';
                        const icon = tip.passed ? '✓' : '✗';
                        html += '<li class="tam-tip ' + cls + '">';
                        html += '<span class="tam-tip__icon">' + icon + '</span>';
                        html += '<span class="tam-tip__text"><strong>' + tip.text + '</strong>';
                        if (tip.detail) {
                            html += ' <span class="tam-tip__detail">(' + tip.detail + ')</span>';
                        }
                        html += '</span></li>';
                    });
                    html += '</ul>';
                    $('#seo-tips-list').html(html);
                }

                // Trigger score updates on field changes
                $('#_tam_rank_meta_title, #_tam_rank_meta_description, #_tam_rank_focus_keyword, #_tam_rank_custom_slug').on('input', function () {
                    updateLiveScore();
                });

                // Also update when post title changes (as it's used as fallback)
                $('#title').on('input', function () {
                    updateLiveScore();
                });

                // Initial calculation
                updateLiveScore();

                // Initialize validation for Focus Keyword and URL Slug on page load
                $('#_tam_rank_focus_keyword').trigger('input');
                $('#_tam_rank_custom_slug').trigger('input');

                // Tab switching functionality
                $('.tam-meta-tab').on('click', function (e) {
                    e.preventDefault();
                    const tabId = $(this).data('tab');

                    // Update active tab button
                    $('.tam-meta-tab').removeClass('active');
                    $(this).addClass('active');

                    // Update active tab content
                    $('.tam-meta-tab-content').removeClass('active');
                    $('#tam-tab-' + tabId).addClass('active');

                    // Trigger resize for any elements that need it (like schema preview)
                    $(window).trigger('resize');
                });

                // Check URL hash to auto-switch to correct tab (SEO, Content, or Schema)
                function checkHashAndSwitchTab() {
                    var hash = window.location.hash;
                    var tabName = null;

                    // Determine which tab to switch to based on hash
                    if (hash === '#tam-tab-seo') {
                        tabName = 'seo';
                    } else if (hash === '#tam-tab-content') {
                        tabName = 'content';
                    } else if (hash === '#tam-rank-schema-tab' || hash === '#tam-tab-schema') {
                        tabName = 'schema';
                    }

                    if (tabName) {
                        // Switch to the specified tab
                        $('.tam-meta-tab').removeClass('active');
                        $('.tam-meta-tab[data-tab="' + tabName + '"]').addClass('active');
                        $('.tam-meta-tab-content').removeClass('active');
                        $('#tam-tab-' + tabName).addClass('active');

                        // Scroll to the meta box
                        setTimeout(function () {
                            const $metaBox = $('#tam-rank-seo').closest('.postbox');
                            if ($metaBox.length) {
                                // Open if collapsed
                                if ($metaBox.hasClass('closed')) {
                                    $metaBox.removeClass('closed');
                                    $metaBox.find('.inside').show();
                                }
                                // Scroll to it
                                $metaBox[0].scrollIntoView({ behavior: 'smooth', block: 'start' });
                                // Highlight
                                setTimeout(function () {
                                    $metaBox.css({
                                        'box-shadow': '0 0 20px rgba(37, 172, 117, 0.5)',
                                        'transition': 'box-shadow 0.3s ease'
                                    });
                                    setTimeout(function () {
                                        $metaBox.css('box-shadow', '');
                                    }, 2000);
                                }, 500);
                            }
                        }, 300);
                    }
                }

                // Check on page load
                checkHashAndSwitchTab();

                // Also check after a delay (for Gutenberg)
                setTimeout(checkHashAndSwitchTab, 500);
                setTimeout(checkHashAndSwitchTab, 1500);
            });
        <?php wp_add_inline_script('tam-rank-meta-box', ob_get_clean()); ?>
        <?php
    }

    /**
     * Render Schema tab content - Nieuwe UX versie
     *
     * Structuur:
     * 1. Statusbalk bovenaan met actief schema en bron
     * 2. Bronkeuze sectie (accordion)
     * 3. Extra schema's sectie
     * 4. Velden sectie (ingeklapt)
     * 5. JSON-LD preview (achter knop)
     * 6. TAMRANK advies blok
     */
    private function render_schema_tab_content($post)
    {
        // Haal schema manager op
        $schema_manager = tamrank_get_schema_manager();
        if (!$schema_manager) {
            echo '<p style="padding: 20px; color: #475569;">' . esc_html__('Schema Manager not found.', 'tam-rank') . '</p>';
            return;
        }

        $templates_manager = $schema_manager->get_templates();
        if (!$templates_manager) {
            echo '<p style="padding: 20px; color: #475569;">' . esc_html__('Schema Templates not found.', 'tam-rank') . '</p>';
            return;
        }

        // Haal beschikbare templates op voor dit post type
        $templates = $templates_manager->get_templates_for_post_type($post->post_type);

        // Haal detectie data op via detector manager
        $detector_manager = null;
        $metabox_data = array('detectie' => null);
        if (class_exists('TAMRANK_Schema_Detector_Manager')) {
            $detector_manager = TAMRANK_Schema_Detector_Manager::krijg_instantie();
            if ($detector_manager) {
                $metabox_data = $detector_manager->krijg_metabox_data($post->ID);
            }
        }

        // Huidige instellingen
        $enabled = get_post_meta($post->ID, 'tamrank_schema_enabled', true);
        $template_id = get_post_meta($post->ID, 'tamrank_schema_template_id', true);
        $overrides = get_post_meta($post->ID, 'tamrank_schema_overrides', true);
        $schema_bron = get_post_meta($post->ID, 'tamrank_schema_bron', true); // 'automatisch', 'template', 'geen'

        if ($enabled === '') {
            $enabled = '1'; // Standaard ingeschakeld
        }

        if (empty($schema_bron) || $schema_bron === 'handmatig') {
            // Standaard naar automatisch (gratis feature)
            if ($enabled !== '1') {
                $schema_bron = 'geen';
            } elseif (!empty($template_id)) {
                $schema_bron = 'template';
            } else {
                $schema_bron = 'automatisch';
            }
        }

        if (!is_array($overrides)) {
            $overrides = array();
        }

        // Template als eerste selecteren indien niet ingesteld
        if (empty($template_id) && !empty($templates)) {
            $template_id = key($templates);
        }

        $current_template = isset($templates[$template_id]) ? $templates[$template_id] : (!empty($templates) ? reset($templates) : null);
        $schema_types = tamrank_get_schema_types();
        $schema_config = $current_template ? ($schema_types[$current_template['schema_type']] ?? array('properties' => array())) : array('properties' => array());

        // Bepaal effectief schema type en bron label
        $effectief_schema_type = '';
        $effectief_extra_schemas = array();
        $bron_label = '';

        // Check of detectie data beschikbaar en geldig is
        $detectie_beschikbaar = isset($metabox_data['detectie'])
            && is_array($metabox_data['detectie'])
            && !empty($metabox_data['detectie']['hoofd_schema'])
            && !empty($metabox_data['detectie']['is_geldig']);

        if ($schema_bron === 'geen' || $enabled !== '1') {
            $bron_label = tamrank__('no_page_schema', 'No page schema active');
        } elseif ($schema_bron === 'automatisch' && $detectie_beschikbaar) {
            // Automatisch: gebruik gedetecteerd schema
            $effectief_schema_type = $metabox_data['detectie']['hoofd_schema'];
            $effectief_extra_schemas = $metabox_data['detectie']['extra_schemas'] ?? array();
            $bron_label = tamrank__('schema_source_auto', 'TAMRANK automatic recommendation');
        } elseif ($schema_bron === 'automatisch' && !$detectie_beschikbaar) {
            // Automatisch maar geen detectie - probeer alsnog detectie te forceren
            $bron_label = tamrank__('schema_source_auto', 'TAMRANK automatic recommendation'); // Standaard label zetten
            if ($detector_manager) {
                $detectie_result = $detector_manager->voer_detectie_uit($post);
                if ($detectie_result && $detectie_result->is_geldig()) {
                    $effectief_schema_type = $detectie_result->krijg_hoofd_schema();
                    $effectief_extra_schemas = $detectie_result->krijg_extra_schemas();
                    // Update metabox_data voor later gebruik
                    $metabox_data['detectie'] = array(
                        'hoofd_schema' => $effectief_schema_type,
                        'extra_schemas' => $effectief_extra_schemas,
                        'betrouwbaarheid' => $detectie_result->krijg_betrouwbaarheid(),
                        'is_geldig' => true
                    );
                }
            }
        } elseif ($schema_bron === 'template' && $current_template) {
            $effectief_schema_type = $current_template['schema_type'];
            /* translators: %s: template name */
            $bron_label = sprintf(tamrank__('schema_template_label', 'Schema template: %s'), esc_html($current_template['name']));
        } elseif ($current_template) {
            // Fallback naar template als niets anders werkt
            $effectief_schema_type = $current_template['schema_type'];
            /* translators: %s: template name */
            $bron_label = sprintf(tamrank__('schema_template_label', 'Schema template: %s'), esc_html($current_template['name']));
        }

        // Nonce voor schema opslag
        wp_nonce_field('tamrank_schema_meta_box', 'tamrank_schema_nonce');

        // Haal globale schema instellingen op
        $globale_instellingen = get_option('tamrank_schema_settings', array());
        $globaal_entiteit_type = isset($globale_instellingen['entity_type']) ? $globale_instellingen['entity_type'] : 'Organization';

        // Bereid detectie data VROEG voor - zodat alle secties toegang hebben
        // BELANGRIJK: $detectie_hoofd moet gebaseerd zijn op de geselecteerde BRON, niet altijd detectie data
        $detectie_hoofd = '';
        $detectie_extra = array();
        $detectie_betrouwbaarheid = 0;

        // Automatische detectie data (voor de "Automatisch" kaart en wanneer die bron actief is)
        $auto_detectie_hoofd = '';
        $auto_detectie_extra = array();
        $auto_detectie_betrouwbaarheid = 0;

        if (!empty($metabox_data['detectie']['hoofd_schema'])) {
            $auto_detectie_hoofd = $metabox_data['detectie']['hoofd_schema'];
            $auto_detectie_extra = $metabox_data['detectie']['extra_schemas'] ?? array();
            $auto_detectie_betrouwbaarheid = $metabox_data['detectie']['betrouwbaarheid'] ?? 0;

            // BreadcrumbList wordt ALTIJD toegevoegd voor posts, pages en products
            if (tamrank_post_type_has_breadcrumb_schema($post->post_type)) {
                if (!in_array('BreadcrumbList', $auto_detectie_extra, true)) {
                    $auto_detectie_extra[] = 'BreadcrumbList';
                }
            }
        }

        // Bepaal het HOOFD schema type gebaseerd op de geselecteerde BRON
        if ($schema_bron === 'automatisch' && !empty($auto_detectie_hoofd)) {
            // Automatisch bron: gebruik detectie data
            $detectie_hoofd = $auto_detectie_hoofd;
            $detectie_extra = $auto_detectie_extra;
            $detectie_betrouwbaarheid = $auto_detectie_betrouwbaarheid;
        } elseif ($schema_bron === 'template' && !empty($effectief_schema_type)) {
            // Template bron: gebruik template schema type, GEEN extra's
            $detectie_hoofd = $effectief_schema_type;
            $detectie_extra = array(); // Templates hebben geen automatische extra's
        } elseif (!empty($effectief_schema_type)) {
            // Fallback
            $detectie_hoofd = $effectief_schema_type;
            $detectie_extra = $effectief_extra_schemas;
        }

        // Filter de extra-schema chips op wat de renderer ECHT bouwt.
        // De detector beveelt extra's aan op score, maar build_extra_schemas() dropt
        // elk type zonder bruikbare content (HowTo zonder stappen, FAQ zonder Q&A,
        // VideoObject zonder embed, ...). Zonder deze filter tonen we een chip terwijl
        // het schema niet in de JSON-LD belandt. Eén bron-van-waarheid = de gebouwde
        // graph (get_renderable_types gebruikt dezelfde build als de JSON-LD preview).
        $faq_al_van_iemand_anders = false;
        if ($enabled === '1' && $schema_bron === 'automatisch' && !empty($detectie_extra)) {
            $faq_was_gedetecteerd = in_array('FAQPage', $detectie_extra, true);
            $renderer_voor_chips  = $schema_manager->get_renderer();
            if ($renderer_voor_chips && method_exists($renderer_voor_chips, 'get_renderable_types')) {
                $renderbare_types = $renderer_voor_chips->get_renderable_types($post, $schema_bron);
                // Alleen filteren als de build daadwerkelijk types opleverde; bij een
                // lege uitkomst (build mislukt/transient) tonen we liever de detectie
                // dan alle chips te verbergen.
                if (!empty($renderbare_types)) {
                    $auto_detectie_extra = array_values(array_intersect($auto_detectie_extra, $renderbare_types));
                    $detectie_extra      = array_values(array_intersect($detectie_extra, $renderbare_types));
                }

                // De detector stelde FAQPage voor maar de renderer bouwt hem niet.
                // Is dat omdat de pagina er zelf al een draagt, leg dat dan uit; anders
                // ziet de redacteur alleen een chip verdwijnen zonder reden.
                if ($faq_was_gedetecteerd
                    && !in_array('FAQPage', $detectie_extra, true)
                    && method_exists($renderer_voor_chips, 'get_faq_skip_reason')) {
                    $faq_al_van_iemand_anders = in_array(
                        $renderer_voor_chips->get_faq_skip_reason(),
                        array('existing_faqpage_in_source', 'faq_block_from_other_plugin'),
                        true
                    );
                }
            }
        }

        // Betrouwbaarheid percentages - apart voor auto detectie kaart
        $auto_betrouwbaarheid_pct = round($auto_detectie_betrouwbaarheid * 100);
        $betrouwbaarheid_pct = round($detectie_betrouwbaarheid * 100);

        // Hidden fields voor bron tracking
        ?>
        <input type="hidden" name="tamrank_schema_bron" id="tamrank_schema_bron" value="<?php echo esc_attr($schema_bron); ?>">
        <input type="hidden" name="tamrank_schema_enabled" id="tamrank_schema_enabled_hidden"
            value="<?php echo esc_attr($enabled); ?>">

        <div class="tamrank-schema-tab-nieuwe-ux">

            <!-- ============================================ -->
            <!-- SECTIE 0: SITE-BREED ACTIEF -->
            <!-- ============================================ -->
            <div class="tam-schema-status-banner">
                <div class="tam-schema-status-banner__left">
                    <svg class="tam-schema-status-banner__icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <rect x="3" y="3" width="18" height="18" rx="2" />
                        <path d="M9 21V9h6v12" />
                        <path d="M9 9V3h6v6" />
                    </svg>
                    <span class="tam-schema-status-banner__text">
                        <?php echo esc_html(tamrank__('site_wide_active', 'Site-wide active')); ?>:
                        <strong><?php echo esc_html(tamrank__($globaal_entiteit_type, $globaal_entiteit_type)); ?></strong>
                    </span>
                </div>
                <span class="tam-schema-status-banner__sub">
                    <?php echo esc_html__('Set in TamRank', 'tam-rank'); ?> →
                    <a href="<?php echo esc_url(admin_url('admin.php?page=tam-rank-schema&tab=instellingen')); ?>"><?php echo esc_html__('Settings', 'tam-rank'); ?></a>
                </span>
            </div>

            <!-- ============================================ -->
            <!-- SECTIE 1: SCHEMA VOOR DEZE PAGINA -->
            <!-- ============================================ -->
            <div id="tam-schema-status-sectie" class="tam-schema-sectie tam-schema-card">
                <div class="tam-schema-card__row">
                    <div class="tam-schema-card__main">
                        <div class="tam-schema-section-label">
                            <?php tamrank_e('schema_for_page', 'Schema for this page'); ?>
                        </div>

                        <div id="tam-schema-badges-container" class="tam-schema-badges">
                            <?php if ($enabled === '1' && $schema_bron !== 'geen' && !empty($detectie_hoofd)): ?>
                                <span class="tam-schema-badge tam-schema-badge--primary">
                                    <?php echo esc_html($detectie_hoofd); ?>
                                </span>
                                <?php if (!empty($detectie_extra) && true): ?>
                                    <span class="tam-schema-badge--separator">+</span>
                                    <?php foreach ($detectie_extra as $extra): ?>
                                        <span class="tam-schema-badge tam-schema-badge--outline">
                                            <?php echo esc_html($extra); ?>
                                        </span>
                                    <?php endforeach; ?>
                                <?php endif; ?>
                            <?php else: ?>
                                <span class="tam-schema-badge--empty"><?php tamrank_e('no_page_schema', 'No page schema active'); ?></span>
                            <?php endif; ?>
                        </div>

                        <!-- Bron info -->
                        <div id="tam-bron-info-container" class="tam-bron-info">
                            <?php if ($enabled === '1' && $schema_bron !== 'geen'): ?>
                                <span><?php tamrank_e('source', 'Source'); ?>: <span
                                        id="tam-bron-label-tekst"><?php echo esc_html($bron_label); ?></span></span>
                                <?php if (!empty($detectie_extra) && true): ?>
                                    <span class="tam-bron-info__separator">·</span>
                                    <span><?php echo esc_html(tamrank__('extras_automatic', 'Extras automatic')); ?></span>
                                <?php endif; ?>
                            <?php else: ?>
                                <span id="tam-bron-label-tekst" class="tam-bron-info__muted"><?php echo esc_html($bron_label); ?></span>
                            <?php endif; ?>
                        </div>

                        <?php if ($faq_al_van_iemand_anders): ?>
                            <div class="tam-bron-info">
                                <span class="tam-bron-info__muted">
                                    <?php echo esc_html(tamrank__('schema_faq_already_present', 'This page already has FAQ schema from your theme or another plugin, so TamRank leaves that to them.')); ?>
                                </span>
                            </div>
                        <?php endif; ?>
                    </div>

                    <button type="button" id="tam-schema-aanpassen-toggle" class="tr-btn tr-btn--secondary tr-btn--sm">
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                            <path d="M12 3v18M3 12h18" />
                        </svg>
                        <span class="tam-toggle-text"><?php tamrank_e('customize', 'Customize'); ?></span>
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
                            id="tam-aanpassen-chevron" class="tam-accordion-chevron">
                            <polyline points="6 9 12 15 18 9" />
                        </svg>
                    </button>
                </div>
            </div>

            <!-- ============================================ -->
            <!-- SECTIE 2: INSTELLINGEN PANEEL (accordion) -->
            <!-- ============================================ -->
            <div id="tam-schema-instellingen-paneel" class="tam-schema-instellingen-paneel">

                <!-- Bronkeuze sectie -->
                <div class="tam-schema-sectie tam-bronkeuze-sectie">
                    <div class="tam-bronkeuze-label"><?php echo esc_html(tamrank__('choose_schema_source', 'Choose schema source')); ?></div>

                    <div class="tam-bronkeuze-grid">
                        <!-- Automatic schema source -->
                        <div class="tam-bronkeuze-kaart-wrap">
                                <?php if (!empty($detectie_hoofd)): ?>
                                    <button type="button" class="tr-btn tr-btn--tertiary tr-btn--sm tam-detecteer-opnieuw" data-post-id="<?php echo esc_attr($post->ID); ?>">
                                        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                            <polyline points="23 4 23 10 17 10" />
                                            <path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10" />
                                        </svg>
                                        <?php echo esc_html(tamrank__('re_detect', 'Re-detect')); ?>
                                    </button>
                                <?php endif; ?>
                                <label class="tam-bronkeuze-kaart <?php echo $schema_bron === 'automatisch' ? 'tam-bronkeuze-actief' : ''; ?>">
                                    <input type="radio" name="tamrank_schema_bron_keuze" value="automatisch" <?php checked($schema_bron, 'automatisch'); ?> class="tam-bronkeuze-radio">
                                    <div class="tam-bronkeuze-kaart__body">
                                        <div class="tam-bronkeuze-kaart__header">
                                            <div class="tam-bronkeuze-icon">
                                                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                                    <path d="M12 3l1.912 5.813a2 2 0 001.272 1.272L21 12l-5.816 1.915a2 2 0 00-1.272 1.272L12 21l-1.912-5.813a2 2 0 00-1.272-1.272L3 12l5.816-1.915a2 2 0 001.272-1.272L12 3z" />
                                                    <path d="M5 3v4" /><path d="M3 5h4" />
                                                    <path d="M19 17v4" /><path d="M17 19h4" />
                                                </svg>
                                            </div>
                                            <span class="tam-bronkeuze-kaart__titel"><?php echo esc_html(tamrank__('automatic', 'Automatic')); ?></span>
                                        </div>
                                        <span class="tam-bronkeuze-kaart__sub"><?php echo esc_html(tamrank__('schema_detect_best', 'TamRank detects the best schema')); ?></span>

                                        <div id="tam-auto-schema-badges" class="tam-schema-badges tam-auto-badges">
                                            <?php if (!empty($auto_detectie_hoofd)): ?>
                                                <span class="tam-schema-badge tam-schema-badge--primary"><?php echo esc_html($auto_detectie_hoofd); ?></span>
                                                <?php if (!empty($auto_detectie_extra)): ?>
                                                    <span class="tam-schema-badge--separator">+</span>
                                                    <?php foreach ($auto_detectie_extra as $extra): ?>
                                                        <span class="tam-schema-badge tam-schema-badge--outline"><?php echo esc_html($extra); ?></span>
                                                    <?php endforeach; ?>
                                                <?php endif; ?>
                                            <?php else: ?>
                                                <span class="tam-bronkeuze-kaart__hint"><?php echo esc_html(tamrank__('click_re_detect', "Click 'Re-detect' to determine schema")); ?></span>
                                            <?php endif; ?>
                                        </div>

                                        <div id="tam-auto-betrouwbaarheid" class="tam-bronkeuze-betrouwbaarheid" <?php echo empty($auto_detectie_hoofd) ? 'style="display: none;"' : ''; ?>>
                                            <div class="tam-bronkeuze-betrouwbaarheid__track">
                                                <div class="tam-bronkeuze-betrouwbaarheid__fill" style="width: <?php echo esc_attr($auto_betrouwbaarheid_pct); ?>%;"></div>
                                            </div>
                                            <span class="tam-bronkeuze-betrouwbaarheid__pct"><?php echo esc_html($auto_betrouwbaarheid_pct); ?>%</span>
                                        </div>
                                    </div>
                                    <span class="tam-bronkeuze-kaart__selected"><?php tamrank_e('selected', 'Selected'); ?> ✓</span>
                                </label>
                        </div>

                        <!-- Schema sjabloon -->
                        <label class="tam-bronkeuze-kaart <?php echo $schema_bron === 'template' ? 'tam-bronkeuze-actief' : ''; ?> <?php echo empty($templates) ? 'tam-bronkeuze-kaart--disabled' : ''; ?>">
                            <input type="radio" name="tamrank_schema_bron_keuze" value="template" <?php checked($schema_bron, 'template'); ?> <?php echo empty($templates) ? 'disabled' : ''; ?> class="tam-bronkeuze-radio">
                            <div class="tam-bronkeuze-kaart__body">
                                <div class="tam-bronkeuze-kaart__header">
                                    <div class="tam-bronkeuze-icon">
                                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2">
                                            <rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
                                            <line x1="3" y1="9" x2="21" y2="9" />
                                            <line x1="9" y1="21" x2="9" y2="9" />
                                        </svg>
                                    </div>
                                    <span class="tam-bronkeuze-kaart__titel"><?php echo esc_html(tamrank__('schema_template', 'Schema template')); ?></span>
                                </div>
                                <span class="tam-bronkeuze-kaart__sub"><?php echo esc_html(tamrank__('use_predefined_template', 'Use a predefined template')); ?></span>
                            </div>
                            <span class="tam-bronkeuze-kaart__selected"><?php tamrank_e('selected', 'Selected'); ?> ✓</span>
                        </label>

                        <!-- Geen schema -->
                        <label class="tam-bronkeuze-kaart <?php echo $schema_bron === 'geen' ? 'tam-bronkeuze-actief' : ''; ?>">
                            <input type="radio" name="tamrank_schema_bron_keuze" value="geen" <?php checked($schema_bron, 'geen'); ?> class="tam-bronkeuze-radio">
                            <div class="tam-bronkeuze-kaart__body">
                                <div class="tam-bronkeuze-kaart__header">
                                    <div class="tam-bronkeuze-icon">
                                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2">
                                            <circle cx="12" cy="12" r="10" />
                                            <line x1="4.93" y1="4.93" x2="19.07" y2="19.07" />
                                        </svg>
                                    </div>
                                    <span class="tam-bronkeuze-kaart__titel"><?php echo esc_html(tamrank__('no_schema', 'No schema')); ?></span>
                                </div>
                                <span class="tam-bronkeuze-kaart__sub"><?php echo esc_html(tamrank__('dont_show_page_schema', 'Do not show page schema')); ?></span>
                            </div>
                            <span class="tam-bronkeuze-kaart__selected"><?php tamrank_e('selected', 'Selected'); ?> ✓</span>
                        </label>
                    </div>

                    <!-- Template selectie (alleen zichtbaar bij 'template' bron) -->
                    <div id="tam-template-selectie" class="tam-template-selectie" <?php echo $schema_bron !== 'template' ? 'style="display: none;"' : ''; ?>>
                        <label for="tamrank_schema_template_id" class="tam-template-selectie__label">
                            <?php echo esc_html(tamrank__('select_schema_template', 'Select schema template')); ?>
                        </label>
                        <div class="tam-template-selectie__row">
                            <select name="tamrank_schema_template_id" id="tamrank_schema_template_id" class="tam-template-selectie__select">
                                <?php if (!empty($templates)): ?>
                                    <?php foreach ($templates as $tid => $tpl): ?>
                                        <option value="<?php echo esc_attr($tid); ?>" <?php selected($template_id, $tid); ?>>
                                            <?php echo esc_html($tpl['name']); ?>
                                            (<?php echo esc_html($schema_types[$tpl['schema_type']]['label'] ?? $tpl['schema_type']); ?>)
                                        </option>
                                    <?php endforeach; ?>
                                <?php else: ?>
                                    <option value=""><?php tamrank_e('no_templates_available', 'No templates available'); ?></option>
                                <?php endif; ?>
                            </select>
                            <a href="<?php echo esc_url(admin_url('admin.php?page=tam-rank-schema')); ?>" class="tr-btn tr-btn--secondary tr-btn--sm">
                                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <circle cx="12" cy="12" r="3" />
                                    <path
                                        d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" />
                                </svg>
                                <?php tamrank_e('manage_templates', 'Manage templates'); ?>
                            </a>
                        </div>
                    </div>

                </div>

                <!-- TAMRANK Advies is nu geïntegreerd in de Automatisch bronkeuze kaart -->

            </div><!-- einde instellingen paneel -->

            <!-- ============================================ -->
            <!-- SECTIE 3: VELDEN AANPASSEN (ingeklapt) -->
            <!-- ============================================ -->
            <?php if ($schema_bron !== 'geen' && $enabled === '1'): ?>
                <div class="tam-schema-sectie tam-schema-card tam-schema-card--no-padding" id="tam-velden-sectie">
                    <button type="button" id="tam-velden-toggle" class="tam-accordion-toggle tam-accordion-toggle--disabled" disabled>
                        <div class="tam-accordion-toggle__label">
                            <svg id="tam-velden-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
                                <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
                            </svg>
                            <span id="tam-velden-label" class="tam-accordion-toggle__text"><?php tamrank_e('adjust_fields', 'Adjust fields'); ?></span>
                            <span id="tam-velden-schema-type" class="tam-accordion-toggle__sub">(<?php echo esc_html($effectief_schema_type ?: tamrank__('no_type', 'no type')); ?>)</span>
                            <span id="tam-velden-geen-melding" class="tam-accordion-toggle__hint"><?php tamrank_e('no_fields_to_fill', '— no fields to fill'); ?></span>
                        </div>
                        <svg id="tam-velden-chevron" class="tam-accordion-chevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                            <polyline points="6 9 12 15 18 9" />
                        </svg>
                    </button>

                    <div id="tam-velden-content" class="tam-accordion-content">
                        <?php $this->render_schema_velden_content($effectief_schema_type, $overrides, $schema_bron, $template_id); ?>
                    </div>
                </div>
            <?php endif; ?>

            <!-- ============================================ -->
            <!-- SECTIE 4: JSON-LD PREVIEW (achter knop) -->
            <!-- ============================================ -->
            <?php if ($schema_bron !== 'geen' && $enabled === '1'): ?>
                <div class="tam-schema-sectie tam-jsonld-sectie">
                    <button type="button" id="tam-jsonld-toggle" class="tam-jsonld-toggle">
                        <div class="tam-jsonld-toggle__label">
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <polyline points="16 18 22 12 16 6" />
                                <polyline points="8 6 2 12 8 18" />
                            </svg>
                            <span><?php echo esc_html(tamrank__('json_ld_preview', 'JSON-LD Preview')); ?></span>
                        </div>
                        <svg id="tam-jsonld-chevron" class="tam-jsonld-toggle__chevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                            <polyline points="6 9 12 15 18 9" />
                        </svg>
                    </button>

                    <div id="tam-jsonld-content" class="tam-jsonld-content">
                        <?php
                        // Genereer schema preview direct server-side (zelfde als pagina output)
                        $schema_preview_html = '';
                        $schema_preview_data = null;

                        if ($schema_bron !== 'geen' && $enabled === '1') {
                            $renderer = $schema_manager->get_renderer();
                            if ($renderer && method_exists($renderer, 'get_schema_preview')) {
                                $schema_preview_data = $renderer->get_schema_preview($post, $schema_bron);
                            }
                        }

                        if ($schema_preview_data) {
                            $schema_preview_html = '<pre>' . esc_html(wp_json_encode($schema_preview_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)) . '</pre>';
                        } elseif ($schema_bron === 'geen' || $enabled !== '1') {
                            $schema_preview_html = '<em class="tam-jsonld-muted">' . esc_html__('Schema is disabled', 'tam-rank') . '</em>';
                        } else {
                            $schema_preview_html = '<em class="tam-jsonld-error">' . esc_html__('No schema detected. Click "Detect Schema" to start.', 'tam-rank') . '</em>';
                        }
                        ?>
                        <div id="schema-preview">
                            <?php echo wp_kses_post($schema_preview_html); ?>
                        </div>

                        <div class="tam-jsonld-actions">
                            <a href="<?php echo esc_url(add_query_arg('url', get_permalink($post), 'https://search.google.com/test/rich-results')); ?>"
                                target="_blank" class="tr-btn tr-btn--secondary tr-btn--sm">
                                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
                                    <polyline points="15 3 21 3 21 9" />
                                    <line x1="10" y1="14" x2="21" y2="3" />
                                </svg>
                                <?php echo esc_html(tamrank__('google_rich_results_test', 'Google Rich Results Test')); ?>
                            </a>
                        </div>
                    </div>
                </div>
            <?php endif; ?>

        </div><!-- einde tamrank-schema-tab-nieuwe-ux -->

        <!-- Hidden nonce voor detectie -->
        <input type="hidden" id="tamrank_detectie_nonce"
            value="<?php echo esc_attr($metabox_data['nonce'] ?? wp_create_nonce('tamrank_schema_detectie')); ?>">

        <?php
        // Voeg de JavaScript en CSS toe
        $this->render_schema_tab_scripts($post, $templates, $template_id, $schema_bron);
    }

    /**
     * Render TAMRANK Advies blok - schoon design zoals screenshot
     * Toont aanbevolen schema's met hoofd (groen) + extra's (blauw)
     * Score is direct zichtbaar, status is correct gebaseerd op bronkeuze
     *
     * @param WP_Post $post Huidige post
     * @param array $metabox_data Detectie data
     */
    private function render_extra_schemas_advies_blok($post, $metabox_data)
    {
        $detectie = $metabox_data['detectie'] ?? null;
        $effectief = $metabox_data['effectief'] ?? null;
        $heeft_detectie = !empty($detectie) && !empty($detectie['is_geldig']);

        // Niet tonen als geen detectie
        if (!$heeft_detectie) {
            return;
        }

        // BreadcrumbList wordt ALTIJD toegevoegd voor posts, pages en products
        if (tamrank_post_type_has_breadcrumb_schema($post->post_type)) {
            if (!isset($detectie['extra_schemas'])) {
                $detectie['extra_schemas'] = array();
            }
            if (!in_array('BreadcrumbList', $detectie['extra_schemas'], true)) {
                $detectie['extra_schemas'][] = 'BreadcrumbList';
            }
        }

        // Haal huidige bronkeuze op - advies is alleen "Actief" als bronkeuze "automatisch" is
        $schema_bron = get_post_meta($post->ID, 'tamrank_schema_bron', true);
        if (empty($schema_bron)) {
            $schema_bron = 'automatisch';
        }

        // Advies is alleen actief als de bronkeuze "automatisch" is
        $advies_actief = ($schema_bron === 'automatisch');

        // Betrouwbaarheid percentage
        $betrouwbaarheid = round($detectie['betrouwbaarheid'] * 100);
        ?>
        <!-- TAMRANK ADVIES -->
        <div id="tam-advies-blok" class="tam-advies-blok"
            style="background: #ecfdf5; border: 1px solid #a7f3d0; border-radius: 12px; padding: 16px 20px; margin-bottom: 16px;">
            <div style="display: flex; align-items: flex-start; gap: 12px;">
                <!-- Icoon (lamp) -->
                <div
                    style="width: 40px; height: 40px; background: #d1fae5; border-radius: 10px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#059669" stroke-width="2">
                        <path
                            d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" />
                    </svg>
                </div>

                <!-- Content -->
                <div style="flex: 1;">
                    <!-- Header: titel + status -->
                    <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
                        <span style="font-size: 15px; font-weight: 700; color: #1e293b;"><?php echo esc_html__('TamRank advice', 'tam-rank'); ?></span>
                        <span id="tam-advies-status-badge"
                            style="padding: 3px 10px; border-radius: 9999px; font-size: 12px; font-weight: 500; <?php echo $advies_actief ? 'background: #d1fae5; color: #065f46;' : 'background: #fef3c7; color: #92400e;'; ?>">
                            <?php echo esc_html($advies_actief ? tamrank__('active', 'Active') : tamrank__('inactive', 'Inactive')); ?>
                        </span>
                    </div>

                    <!-- Schema badges: Hoofd (groen) + Extra's (blauw) -->
                    <div style="display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px;">
                        <!-- Hoofd schema badge (groen met witte achtergrond) -->
                        <span
                            style="display: inline-flex; align-items: center; padding: 6px 14px; background: white; color: #059669; border: 1px solid #a7f3d0; border-radius: 8px; font-size: 13px; font-weight: 600;">
                            <?php echo esc_html($detectie['hoofd_schema']); ?>
                        </span>

                        <?php if (!empty($detectie['extra_schemas'])): ?>
                            <span style="color: #94a3b8; font-size: 14px;">+</span>
                            <?php foreach ($detectie['extra_schemas'] as $extra): ?>
                                <!-- Extra schema badges (blauw) -->
                                <span
                                    style="display: inline-flex; align-items: center; padding: 5px 12px; background: white; color: #3b82f6; border: 1px solid #bfdbfe; border-radius: 8px; font-size: 12px; font-weight: 500;">
                                    <?php echo esc_html($extra); ?>
                                </span>
                            <?php endforeach; ?>
                        <?php endif; ?>
                    </div>

                    <!-- Betrouwbaarheid - direct zichtbaar -->
                    <div style="display: flex; align-items: center; gap: 16px; flex-wrap: wrap;">
                        <div style="display: flex; align-items: center; gap: 8px;">
                            <span
                                style="font-size: 11px; color: #64748b; text-transform: uppercase; letter-spacing: 0.05em;"><?php echo esc_html__('Reliability', 'tam-rank'); ?></span>
                            <div style="width: 120px; height: 6px; background: #e2e8f0; border-radius: 3px; overflow: hidden;">
                                <div
                                    style="height: 100%; background: #10b981; border-radius: 3px; width: <?php echo esc_attr($betrouwbaarheid); ?>%;">
                                </div>
                            </div>
                            <span
                                style="font-size: 12px; font-weight: 600; color: #334155;"><?php echo esc_html($betrouwbaarheid); ?>%</span>
                        </div>
                        <span style="color: #cbd5e1;">·</span>
                        <span style="font-size: 12px; color: #64748b;"><?php echo esc_html__('Automatic content analysis', 'tam-rank'); ?></span>
                    </div>
                </div>
            </div>
        </div>
        <?php
    }

    /**
     * Render velden content voor een specifiek schema type
     * Toont bewerkbare velden op basis van het schema type en de bron
     *
     * @param string $schema_type Het schema type (Article, VideoObject, etc.)
     * @param array $overrides Huidige override waarden
     * @param string $bron De bronkeuze (automatisch, template, geen)
     * @param string $template_id Optioneel template ID
     */
    private function render_schema_velden_content($schema_type, $overrides, $bron, $template_id = '')
    {
        if (empty($schema_type)) {
            echo '<div style="padding: 16px; text-align: center; color: #94a3b8;">' . esc_html__('Select a schema type first to edit fields.', 'tam-rank') . '</div>';
            return;
        }

        // Haal schema configuratie op
        $schema_types = tamrank_get_schema_types();
        $schema_config = isset($schema_types[$schema_type]) ? $schema_types[$schema_type] : null;

        if (!$schema_config || empty($schema_config['properties'])) {
            echo '<div style="padding: 16px; text-align: center; color: #94a3b8;">' . esc_html__('No editable fields for this schema type.', 'tam-rank') . '</div>';
            return;
        }

        // Haal template field_mappings op als bron 'template' is
        $template = null;
        $field_mappings = array();
        if ($bron === 'template' && !empty($template_id)) {
            $templates_manager = new TAMRANK_Schema_Templates();
            $template = $templates_manager->get_template($template_id);
            if ($template && isset($template['field_mappings'])) {
                $field_mappings = $template['field_mappings'];
            }
        }

        // Bron labels voor weergave
        $source_labels = array(
            'post_title'           => tamrank__('source_post_title', 'Page title'),
            'meta_description'     => tamrank__('source_meta_description', 'Meta description'),
            'excerpt'              => tamrank__('source_excerpt', 'Excerpt'),
            'content_excerpt'      => tamrank__('source_content_excerpt', 'Content excerpt'),
            'featured_image'       => tamrank__('source_featured_image', 'Featured image'),
            'first_content_image'  => tamrank__('source_first_content_image', 'First content image'),
            'author_name'          => tamrank__('source_author_name', 'Author name'),
            'author_url'           => tamrank__('source_author_url', 'Author URL'),
            'post_date'            => tamrank__('source_post_date', 'Publication date'),
            'post_modified'        => tamrank__('source_post_modified', 'Modified date'),
            'global_organization'  => tamrank__('source_global_organization', 'Global organization'),
            'global_logo'          => tamrank__('source_global_logo', 'Global logo'),
            'manual'               => tamrank__('source_manual', 'Manual'),
            'auto_wordcount'       => tamrank__('source_auto_wordcount', 'Automatic (word count)'),
            'tags'                 => tamrank__('source_tags', 'Tags'),
            'category'             => tamrank__('source_category', 'Category'),
            'post_url'             => tamrank__('source_post_url', 'Page URL'),
            'woo_price'            => tamrank__('source_woo_price', 'WooCommerce price'),
            'woo_category'         => tamrank__('source_woo_category', 'WooCommerce category'),
            'woo_sku'              => tamrank__('source_woo_sku', 'WooCommerce SKU'),
            'woo_stock'            => tamrank__('source_woo_stock', 'WooCommerce stock'),
            'woo_weight'           => tamrank__('source_woo_weight', 'WooCommerce weight'),
            'custom_field'         => tamrank__('source_custom_field', 'Custom field'),
        );

        // Skip complexe nested types die niet handmatig te bewerken zijn via simpele input velden
        $skip_types = array(
            'person',
            'organization',
            'nested_organization',
            'nested_offer',
            'nested_rating',
            'nested_course_instance',
            'video_clips',
            'nested_address',
            'nested_hours',
            'nested_geo'
        );

        // Filter properties - skip alleen complexe nested types
        $properties_to_show = array();
        foreach ($schema_config['properties'] as $property => $prop_config) {
            $field_type = $prop_config['type'] ?? 'text';

            // Skip complexe nested types
            if (in_array($field_type, $skip_types)) {
                continue;
            }

            $properties_to_show[$property] = $prop_config;
        }

        // Check of er velden zijn om te tonen
        if (empty($properties_to_show)) {
            echo '<div style="padding: 16px; text-align: center; color: #94a3b8;">' . esc_html__('No editable fields for this schema type.', 'tam-rank') . '</div>';
            return;
        }

        // Sorteer velden: handmatige velden eerst, dan automatische velden
        $manual_fields = array();
        $auto_fields = array();
        $other_fields = array();

        foreach ($properties_to_show as $property => $prop_config) {
            if ($bron === 'template' && !empty($field_mappings)) {
                $mapping = isset($field_mappings[$property]) ? $field_mappings[$property] : null;
                $source = isset($mapping['source']) ? $mapping['source'] : '';

                if ($source === 'manual') {
                    $manual_fields[$property] = $prop_config;
                } elseif (!empty($source)) {
                    $auto_fields[$property] = $prop_config;
                } else {
                    $other_fields[$property] = $prop_config;
                }
            } else {
                $other_fields[$property] = $prop_config;
            }
        }

        // Combineer: handmatig eerst, dan andere, dan automatisch
        $sorted_properties = array_merge($manual_fields, $other_fields, $auto_fields);

        ?>
        <div style="padding-top: 16px;">
            <?php if ($bron === 'template' && $template && !empty($manual_fields)): ?>
                <div class="tam-template-info-banner">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <circle cx="12" cy="12" r="10" />
                        <line x1="12" y1="16" x2="12" y2="12" />
                        <circle cx="12" cy="8" r="0.5" fill="currentColor" stroke="none" />
                    </svg>
                    <span><?php echo wp_kses_post(sprintf(tamrank__('fill_fields_for_template', 'Fill in the fields below for template %s'), '<strong>' . esc_html($template['name']) . '</strong>')); ?></span>
                </div>
            <?php endif; ?>

            <?php
            $has_shown_auto_header = false;
            foreach ($sorted_properties as $property => $prop_config):
                $field_type = $prop_config['type'] ?? 'text';
                $is_required = $prop_config['required'] ?? false;
                $placeholder = $prop_config['placeholder'] ?? '';

                // Bepaal of dit veld handmatig moet worden ingevuld (voor templates)
                $is_manual_field = false;
                $is_auto_field = false;
                $auto_source = '';
                $auto_value = '';

                if ($bron === 'template' && !empty($field_mappings)) {
                    $mapping = isset($field_mappings[$property]) ? $field_mappings[$property] : null;
                    $source = isset($mapping['source']) ? $mapping['source'] : '';

                    if ($source === 'manual') {
                        $is_manual_field = true;
                        if (isset($mapping['value']) && !empty($mapping['value'])) {
                            $placeholder = $mapping['value'];
                        }
                    } elseif (!empty($source)) {
                        $is_auto_field = true;
                        $auto_source = $source;
                        // Haal de waarde uit de mapping indien beschikbaar
                        if (isset($mapping['value'])) {
                            $auto_value = $mapping['value'];
                        }
                    }
                }

                // Bepaal bron tekst
                if ($is_auto_field) {
                    $bron_tekst = $source_labels[$auto_source] ?? $auto_source;
                } elseif ($is_manual_field) {
                    $bron_tekst = tamrank__('fill_in_manually', 'Fill in manually');
                } else {
                    $default_source = isset($prop_config['sources'][0]) ? $prop_config['sources'][0] : 'auto';
                    $bron_tekst = $source_labels[$default_source] ?? tamrank__('automatic', 'Automatic');
                }

                // Toon header voor automatische velden sectie (alleen bij template)
                if ($is_auto_field && !$has_shown_auto_header && $bron === 'template' && !empty($auto_fields)):
                    $has_shown_auto_header = true;
                    ?>
                    <div style="margin: 20px 0 12px 0; padding: 8px 12px; background: #f1f5f9; border-radius: 6px;">
                        <span
                            style="font-size: 12px; color: #64748b; font-weight: 500;"><?php tamrank_e('automatically_filled_fields', 'Automatically filled fields'); ?></span>
                    </div>
                <?php endif; ?>

                <div
                    style="display: flex; align-items: flex-start; gap: 16px; padding: 12px 0; border-bottom: 1px solid #f1f5f9; <?php echo $is_auto_field ? 'opacity: 0.7;' : ''; ?>">
                    <div style="flex: 1; min-width: 0;">
                        <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 4px;">
                            <span
                                style="font-size: 13px; font-weight: 500; color: #334155;"><?php echo esc_html($prop_config['label'] ?? $property); ?></span>
                            <?php if ($is_required && !$is_auto_field): ?>
                                <span style="color: #dc2626; font-size: 11px;">*</span>
                            <?php endif; ?>
                        </div>
                        <span style="font-size: 11px; color: #94a3b8;"><?php echo esc_html($bron_tekst); ?></span>
                    </div>
                    <div style="flex: 2;">
                        <?php if ($is_auto_field): ?>
                            <!-- Automatisch veld - read-only weergave -->
                            <div
                                style="padding: 8px 12px; background: #f1f5f9; border: 1px solid #e2e8f0; border-radius: 6px; font-size: 13px; color: #64748b;">
                                <?php if (!empty($auto_value)): ?>
                                    <?php echo esc_html($auto_value); ?>
                                <?php else: ?>
                                    <em><?php esc_html_e('Filled in automatically', 'tam-rank'); ?></em>
                                <?php endif; ?>
                            </div>
                        <?php elseif ($field_type === 'select' && !empty($prop_config['options'])): ?>
                            <select name="tamrank_schema_overrides[<?php echo esc_attr($property); ?>]" class="widefat"
                                style="padding: 8px 12px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 13px; background: white;">
                                <option value=""><?php esc_html_e('-- Select --', 'tam-rank'); ?></option>
                                <?php foreach ($prop_config['options'] as $value => $label): ?>
                                    <option value="<?php echo esc_attr($value); ?>" <?php selected($overrides[$property] ?? '', $value); ?>>
                                        <?php echo esc_html($label); ?>
                                    </option>
                                <?php endforeach; ?>
                            </select>
                        <?php elseif ($field_type === 'date'): ?>
                            <input type="date" name="tamrank_schema_overrides[<?php echo esc_attr($property); ?>]"
                                value="<?php echo esc_attr($overrides[$property] ?? ''); ?>" class="widefat"
                                style="padding: 8px 12px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 13px; background: white;">
                        <?php elseif ($field_type === 'number'): ?>
                            <input type="number" name="tamrank_schema_overrides[<?php echo esc_attr($property); ?>]"
                                value="<?php echo esc_attr($overrides[$property] ?? ''); ?>" class="widefat" step="any"
                                style="padding: 8px 12px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 13px; background: white;"
                                placeholder="<?php echo esc_attr($placeholder); ?>">
                        <?php elseif ($field_type === 'url' || $field_type === 'image'): ?>
                            <input type="url" name="tamrank_schema_overrides[<?php echo esc_attr($property); ?>]"
                                value="<?php echo esc_attr($overrides[$property] ?? ''); ?>" class="widefat"
                                style="padding: 8px 12px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 13px; background: white;"
                                placeholder="<?php echo esc_attr($placeholder ?: 'https://...'); ?>">
                        <?php else: ?>
                            <input type="text" name="tamrank_schema_overrides[<?php echo esc_attr($property); ?>]"
                                value="<?php echo esc_attr($overrides[$property] ?? ''); ?>" class="widefat"
                                style="padding: 8px 12px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 13px; background: white;"
                                placeholder="<?php echo esc_attr($placeholder); ?>">
                        <?php endif; ?>
                    </div>
                </div>
            <?php endforeach; ?>
        </div>
        <?php
    }

    /**
     * Render het TAMRANK advies blok (legacy - niet meer in gebruik)
     *
     * @param WP_Post $post Huidige post
     * @param array $metabox_data Detectie data
     * @deprecated Gebruik render_extra_schemas_advies_blok()
     */
    private function render_schema_advies_blok($post, $metabox_data)
    {
        if (empty($metabox_data) || empty($metabox_data['detectie']) || !$metabox_data['detectie']['is_geldig']) {
            return;
        }

        $detectie = $metabox_data['detectie'];
        $effectief = $metabox_data['effectief'] ?? null;

        // Bepaal of advies actief is
        $advies_actief = false;
        if ($effectief) {
            $advies_actief = ($effectief['hoofd_type'] === $detectie['hoofd_schema']);
        }
        ?>
        <div class="tam-schema-sectie tam-advies-blok"
            style="background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%); border: 1px solid #93c5fd; border-radius: 12px; padding: 20px;">
            <div style="display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap;">
                <div style="flex: 1; min-width: 200px;">
                    <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 12px;">
                        <div
                            style="width: 32px; height: 32px; background: #3b82f6; border-radius: 8px; display: flex; align-items: center; justify-content: center;">
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2">
                                <path
                                    d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" />
                            </svg>
                        </div>
                        <div>
                            <h4 style="margin: 0; font-size: 14px; font-weight: 600; color: #1e40af;"><?php esc_html_e('TamRank advice', 'tam-rank'); ?></h4>
                            <span style="font-size: 11px; color: #3b82f6;"><?php echo esc_html($detectie['label']); ?>
                                (<?php echo esc_html(round($detectie['betrouwbaarheid'] * 100)); ?>%)</span>
                        </div>
                    </div>

                    <div style="display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px;">
                        <!-- Hoofd schema badge -->
                        <span
                            style="display: inline-flex; align-items: center; gap: 4px; padding: 5px 12px; background: #3b82f6; color: white; border-radius: 6px; font-size: 12px; font-weight: 600;">
                            <?php echo esc_html($detectie['hoofd_schema']); ?>
                        </span>

                        <?php if (!empty($detectie['extra_schemas'])): ?>
                            <?php foreach ($detectie['extra_schemas'] as $extra): ?>
                                <span
                                    style="display: inline-flex; align-items: center; gap: 4px; padding: 5px 12px; background: #60a5fa; color: white; border-radius: 6px; font-size: 11px; font-weight: 500;">
                                    <?php echo esc_html($extra); ?>
                                </span>
                            <?php endforeach; ?>
                        <?php endif; ?>
                    </div>

                    <p style="margin: 0; font-size: 12px; color: #1e40af;">
                        <?php esc_html_e('Based on the content of this page', 'tam-rank'); ?>
                    </p>
                </div>

                <div style="display: flex; flex-direction: column; align-items: flex-end; gap: 8px;">
                    <?php if ($advies_actief): ?>
                        <span
                            style="display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; background: #22c55e; color: white; border-radius: 6px; font-size: 12px; font-weight: 500;">
                            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <polyline points="20 6 9 17 4 12" />
                            </svg>
                            <?php esc_html_e('Active', 'tam-rank'); ?>
                        </span>
                    <?php else: ?>
                        <span
                            style="display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; background: #f59e0b; color: white; border-radius: 6px; font-size: 12px; font-weight: 500;">
                            <?php esc_html_e('Differs', 'tam-rank'); ?>
                        </span>
                    <?php endif; ?>

                    <button type="button" class="tam-accepteer-advies" data-post-id="<?php echo esc_attr($post->ID); ?>"
                        style="display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; background: <?php echo $advies_actief ? '#e2e8f0' : '#3b82f6'; ?>; color: <?php echo $advies_actief ? '#64748b' : 'white'; ?>; border: none; border-radius: 8px; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.2s;"
                        <?php echo $advies_actief ? 'disabled' : ''; ?>>
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                            <polyline points="20 6 9 17 4 12" />
                        </svg>
                        <?php esc_html_e('Apply advice', 'tam-rank'); ?>
                    </button>
                </div>
            </div>
        </div>
        <?php
    }

    /**
     * Render JavaScript en CSS voor de nieuwe schema tab
     */
    private function render_schema_tab_scripts($post, $templates, $template_id, $schema_bron)
    {
        ob_start();
        ?>
            jQuery(document).ready(function ($) {
                // =============================================
                // ACCORDION TOGGLES
                // =============================================

                // Aanpassen knop - toggle instellingen paneel
                $(document).on('click', '#tam-schema-aanpassen-toggle', function (e) {
                    e.preventDefault();
                    var $paneel = $('#tam-schema-instellingen-paneel');
                    var $tekst = $(this).find('.tam-toggle-text');
                    var $icon = $(this).find('svg');
                    var isVisible = $paneel.is(':visible');

                    $paneel.slideToggle(200, function () {
                        // Update tekst en icon na animatie
                        if (!isVisible) {
                            $tekst.text('<?php echo esc_js(tamrank__('close', 'Close')); ?>');
                            $icon.css('transform', 'rotate(45deg)');
                        } else {
                            $tekst.text('<?php echo esc_js(tamrank__('customize', 'Customize')); ?>');
                            $icon.css('transform', 'rotate(0deg)');
                        }
                    });
                });

                // Velden toggle - alleen als niet disabled
                $('#tam-velden-toggle').on('click', function () {
                    if ($(this).prop('disabled')) {
                        return;
                    }

                    var $content = $('#tam-velden-content');
                    var $chevron = $('#tam-velden-chevron');

                    $content.slideToggle(200);
                    $chevron.css('transform', $content.is(':visible') ? 'rotate(180deg)' : 'rotate(0deg)');
                });

                // Functie om velden toggle te enablen/disablen
                function updateVeldenToggleState(hasManualFields) {
                    var $toggle = $('#tam-velden-toggle');
                    var $icon = $('#tam-velden-icon');
                    var $label = $('#tam-velden-label');
                    var $melding = $('#tam-velden-geen-melding');

                    if (hasManualFields) {
                        // Enable de toggle
                        $toggle.prop('disabled', false)
                            .css({ 'cursor': 'pointer', 'opacity': '1' });
                        $icon.attr('stroke', '#475569');
                        $label.css('color', '#334155');
                        $melding.hide();
                    } else {
                        // Disable de toggle en sluit content
                        $toggle.prop('disabled', true)
                            .css({ 'cursor': 'not-allowed', 'opacity': '0.5' });
                        $icon.attr('stroke', '#94a3b8');
                        $label.css('color', '#94a3b8');
                        $melding.show();

                        // Sluit de content als deze open is
                        var $content = $('#tam-velden-content');
                        var $chevron = $('#tam-velden-chevron');
                        if ($content.is(':visible')) {
                            $content.slideUp(200);
                            $chevron.css('transform', 'rotate(0deg)');
                        }
                    }
                }

                // JSON-LD toggle
                $('#tam-jsonld-toggle').on('click', function () {
                    var $content = $('#tam-jsonld-content');
                    var $chevron = $('#tam-jsonld-chevron');

                    $content.slideToggle(200);
                    $chevron.css('transform', $content.is(':visible') ? 'rotate(180deg)' : 'rotate(0deg)');

                    // Laad preview als nog niet geladen
                    if ($content.is(':visible')) {
                        tamrankUpdateSchemaPreview();
                    }
                });

                // =============================================
                // BRONKEUZE LOGICA
                // =============================================

                // Update "Schema voor deze pagina" sectie gebaseerd op bron keuze
                // Detectie data (via PHP gerenderd - gebruik dezelfde variabelen als de Automatisch kaart)
                // BELANGRIJK: Deze variabele wordt bijgewerkt door schema-detector.js na herdetectie
                window.tamrankDetectieData = {
                    hoofdSchema: '<?php echo esc_js(isset($detectie_hoofd) ? $detectie_hoofd : ''); ?>',
                    extraSchemas: <?php echo wp_json_encode(isset($detectie_extra) && is_array($detectie_extra) ? $detectie_extra : array(), JSON_HEX_TAG | JSON_HEX_AMP); ?>,
                    betrouwbaarheid: <?php echo floatval(isset($detectie_betrouwbaarheid) ? $detectie_betrouwbaarheid : 0); ?>
                };

                function updateSchemaVoorDezePagina(bron) {
                    var $badgesContainer = $('#tam-schema-badges-container');
                    var $bronInfoContainer = $('#tam-bron-info-container');

                    // Gebruik globale detectie data, of haal uit Automatisch kaart badges als fallback
                    var detectieHoofdSchema = tamrankDetectieData.hoofdSchema;
                    var detectieExtraSchemas = tamrankDetectieData.extraSchemas;

                    // Fallback: haal detectie data uit de Automatisch kaart badges als tamrankDetectieData leeg is
                    if (!detectieHoofdSchema || detectieHoofdSchema === '') {
                        var $hoofdBadge = $('#tam-auto-schema-badges .tam-schema-badge--primary');
                        if ($hoofdBadge.length > 0) {
                            detectieHoofdSchema = $hoofdBadge.first().text().trim();
                            tamrankDetectieData.hoofdSchema = detectieHoofdSchema;

                            var $extraBadges = $('#tam-auto-schema-badges .tam-schema-badge--outline');
                            if ($extraBadges.length > 0) {
                                detectieExtraSchemas = [];
                                $extraBadges.each(function () {
                                    detectieExtraSchemas.push($(this).text().trim());
                                });
                                tamrankDetectieData.extraSchemas = detectieExtraSchemas;
                            }
                        }
                    }

                    // Bron labels
                    var bronLabels = {
                        'automatisch': '<?php echo esc_js(tamrank__('schema_source_auto', 'TAMRANK automatic suggestion')); ?>',
                        'template': '<?php echo esc_js(tamrank__('schema_theme', 'Theme schema')); ?>',
                        'geen': '<?php echo esc_js(tamrank__('schema_disabled', 'Schema disabled')); ?>'
                    };

                    if (bron === 'geen') {
                        // Geen schema actief
                        $badgesContainer.html('<span class="tam-geen-schema-tekst" style="color: #94a3b8; font-size: 13px;"><?php echo esc_js(tamrank__('no_schema_active', 'No page schema active')); ?></span>');
                        $bronInfoContainer.html('<span style="color: #94a3b8;"><?php echo esc_js(tamrank__('schema_disabled_page', 'Schema disabled for this page')); ?></span>');
                    } else if (bron === 'automatisch') {
                        // Automatisch: toon gedetecteerde schema's
                        if (detectieHoofdSchema && detectieHoofdSchema !== '') {
                            var badgesHtml = '<span class="tam-hoofd-badge" style="display: inline-flex; align-items: center; padding: 6px 14px; background: #ecfdf5; color: #059669; border: 1px solid #a7f3d0; border-radius: 8px; font-size: 13px; font-weight: 600;">' + detectieHoofdSchema + '</span>';

                            // Show any extra auto-detected schemas alongside the main one
                            if (detectieExtraSchemas && detectieExtraSchemas.length > 0) {
                                badgesHtml += '<span class="tam-plus-separator" style="color: #cbd5e1; font-size: 14px;">+</span>';
                                for (var i = 0; i < detectieExtraSchemas.length; i++) {
                                    badgesHtml += '<span class="tam-extra-badge" style="display: inline-flex; align-items: center; padding: 5px 12px; background: #eff6ff; color: #3b82f6; border: 1px solid #bfdbfe; border-radius: 8px; font-size: 12px; font-weight: 500;">' + detectieExtraSchemas[i] + '</span>';
                                }
                            }

                            $badgesContainer.html(badgesHtml);
                            var bronLabel = '<?php echo esc_js(tamrank__('source', 'Source')); ?>';
                            var bronInfoHtml = '<span>' + bronLabel + ': <span id="tam-bron-label-tekst">' + bronLabels[bron] + '</span></span>';
                            // Note the extras were auto-detected
                            if (detectieExtraSchemas && detectieExtraSchemas.length > 0) {
                                bronInfoHtml += '<span style="color: #cbd5e1;">·</span><span><?php echo esc_js(tamrank__('metabox_schema_extras_auto', 'Extras automatic')); ?></span>';
                            }
                            $bronInfoContainer.html(bronInfoHtml);
                        } else {
                            // Geen detectie beschikbaar - toon fallback bericht
                            $badgesContainer.html('<span style="color: #94a3b8; font-size: 13px;"><?php echo esc_js(tamrank__('metabox_schema_autodetect_active', 'Automatic detection active')); ?></span>');
                            $bronInfoContainer.html('<span>' + bronLabel + ': <span id="tam-bron-label-tekst">' + bronLabels[bron] + '</span></span>');
                        }
                    } else if (bron === 'template') {
                        // Template: toon geselecteerde template info
                        var $templateSelect = $('#tamrank_schema_template_id');
                        var templateName = $templateSelect.find('option:selected').text();
                        var templateType = templateName.match(/\(([^)]+)\)/);
                        var schemaType = templateType ? templateType[1] : '<?php echo esc_js(tamrank__('metabox_schema_theme_fallback', 'Schema theme')); ?>';

                        if ($templateSelect.val() && $templateSelect.val() !== '') {
                            $badgesContainer.html('<span class="tam-hoofd-badge" style="display: inline-flex; align-items: center; padding: 6px 14px; background: #ecfdf5; color: #059669; border: 1px solid #a7f3d0; border-radius: 8px; font-size: 13px; font-weight: 600;">' + schemaType + '</span>');
                            $bronInfoContainer.html('<span>' + bronLabel + ': <span id="tam-bron-label-tekst"><?php echo esc_js(tamrank__('schema_theme', 'Theme schema')); ?>: ' + templateName.replace(/\s*\([^)]+\)/, '').trim() + '</span></span>');
                        } else {
                            $badgesContainer.html('<span style="color: #94a3b8; font-size: 13px;"><?php echo esc_js(tamrank__('metabox_schema_select_theme', 'Select a schema theme...')); ?></span>');
                            $bronInfoContainer.html('<span>' + bronLabel + ': <span id="tam-bron-label-tekst">' + bronLabels[bron] + '</span></span>');
                        }
                    }
                }

                // Bronkeuze radio buttons
                $('input[name="tamrank_schema_bron_keuze"]').on('change', function () {
                    var bron = $(this).val();

                    // Update hidden field
                    $('#tamrank_schema_bron').val(bron);

                    // Update enabled status
                    if (bron === 'geen') {
                        $('#tamrank_schema_enabled_hidden').val('0');
                    } else {
                        $('#tamrank_schema_enabled_hidden').val('1');
                    }

                    // Update kaart styling via classes
                    $('.tam-bronkeuze-kaart').each(function () {
                        var $kaart = $(this);
                        var $input = $kaart.find('input[type="radio"]');

                        if ($input.is(':checked')) {
                            $kaart.addClass('tam-bronkeuze-actief');
                        } else {
                            $kaart.removeClass('tam-bronkeuze-actief');
                        }
                    });

                    // Toon/verberg subsecties
                    $('#tam-template-selectie').toggle(bron === 'template');

                    // Toon/verberg secties en update "Schema voor deze pagina"
                    updateSchemaVoorDezePagina(bron);

                    if (bron === 'geen') {
                        // Verberg: Velden aanpassen, JSON-LD Preview
                        $('#tam-velden-toggle').closest('.tam-schema-sectie').hide();
                        $('#tam-jsonld-toggle').closest('.tam-schema-sectie').hide();
                    } else {
                        // Toon: Velden aanpassen, JSON-LD Preview (als ze bestaan)
                        $('#tam-velden-toggle').closest('.tam-schema-sectie').show();
                        $('#tam-jsonld-toggle').closest('.tam-schema-sectie').show();
                    }

                    // Update statusbalk
                    updateStatusbalk(bron);

                    // Update JSON-LD preview
                    tamrankUpdateSchemaPreview();

                    // Update velden op basis van nieuwe bron
                    updateSchemaVelden(bron);
                });

                // Functie om velden dynamisch te herladen
                function updateSchemaVelden(bron) {
                    var schemaType = '';
                    var templateId = $('#tamrank_schema_template_id').val() || '';

                    // Bepaal schema type op basis van bron
                    if (bron === 'automatisch') {
                        // Gebruik gedetecteerd schema type (uit globale detectie data)
                        schemaType = tamrankDetectieData.hoofdSchema;

                        // Fallback: haal uit badge als globale data leeg is
                        if (!schemaType) {
                            var $hoofdBadge = $('#tam-auto-schema-badges .tam-schema-badge--primary');
                            if ($hoofdBadge.length > 0) {
                                schemaType = $hoofdBadge.first().text().trim();
                                tamrankDetectieData.hoofdSchema = schemaType;
                            }
                        }
                    } else if (bron === 'template') {
                        // Haal schema type uit template naam (bijv. "Article Template (Article)" -> "Article")
                        var templateName = $('#tamrank_schema_template_id option:selected').text();
                        var match = templateName.match(/\(([^)]+)\)/);
                        var schemaTypeLabel = match ? match[1] : ''; // Met spaties voor weergave
                        schemaType = schemaTypeLabel.replace(/\s+/g, ''); // Zonder spaties voor lookup (Local Business -> LocalBusiness)
                    } else {
                        // geen - verberg velden sectie
                        return;
                    }

                    // Update het label boven de velden toggle (gebruik label met spaties voor weergave)
                    var displayLabel = (typeof schemaTypeLabel !== 'undefined' && schemaTypeLabel) ? schemaTypeLabel : schemaType;
                    // Update het label boven de velden toggle
                    var displayLabel = (typeof schemaTypeLabel !== 'undefined' && schemaTypeLabel) ? schemaTypeLabel : schemaType;
                    var noTypeLabel = '<?php echo esc_js(tamrank__('no_type', 'no type')); ?>';
                    $('#tam-velden-schema-type').text('(' + (displayLabel || noTypeLabel) + ')');

                    // Als geen schema type, toon bericht
                    if (!schemaType) {
                        $('#tam-velden-content').html('<div style="padding: 16px; text-align: center; color: #94a3b8;"><?php echo esc_js(tamrank__('metabox_schema_select_type_first', 'First select a schema type to edit fields.')); ?></div>');
                        return;
                    }

                    // AJAX call om velden te laden
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: {
                            action: 'tamrank_get_schema_velden',
                            nonce: '<?php echo esc_js(wp_create_nonce('tamrank_schema_preview')); ?>',
                            post_id: <?php echo intval($post->ID); ?>,
                            schema_type: schemaType,
                            bron: bron,
                            template_id: templateId
                        },
                        beforeSend: function () {
                            $('#tam-velden-content').html('<div style="padding: 16px; text-align: center; color: #94a3b8;"><em><?php echo esc_js(tamrank__('metabox_schema_loading_fields', 'Loading fields...')); ?></em></div>');
                        },
                        success: function (response) {
                            if (response.success) {
                                $('#tam-velden-content').html(response.data.html);

                                // Update de toggle state op basis van handmatige velden
                                updateVeldenToggleState(response.data.has_manual_fields);

                                // Als er handmatige velden zijn, open de accordion automatisch
                                if (response.data.has_manual_fields) {
                                    var $content = $('#tam-velden-content');
                                    var $chevron = $('#tam-velden-chevron');

                                    if (!$content.is(':visible')) {
                                        $content.slideDown(200);
                                        $chevron.css('transform', 'rotate(180deg)');
                                    }
                                }
                            } else {
                                $('#tam-velden-content').html('<div style="padding: 16px; text-align: center; color: #dc2626;"><?php echo esc_js(tamrank__('metabox_schema_fields_error', 'Error loading fields.')); ?></div>');
                                updateVeldenToggleState(false);
                            }
                        },
                        error: function () {
                            $('#tam-velden-content').html('<div style="padding: 16px; text-align: center; color: #dc2626;"><?php echo esc_js(tamrank__('metabox_schema_fields_error', 'Error loading fields.')); ?></div>');
                            updateVeldenToggleState(false);
                        }
                    });
                }

                // Template selector change - update preview AND badges AND velden
                $('#tamrank_schema_template_id').on('change', function () {
                    tamrankUpdateSchemaPreview();
                    var bron = $('input[name="tamrank_schema_bron_keuze"]:checked').val();
                    if (bron === 'template') {
                        updateSchemaVoorDezePagina(bron);
                        updateSchemaVelden(bron);
                    }
                });

                // =============================================
                // ADVIES OVERNEMEN
                // =============================================

                $('.tam-accepteer-advies').on('click', function () {
                    var $button = $(this);
                    var postId = $button.data('post-id');
                    var origineleTekst = $button.html();

                    $button.prop('disabled', true).html(
                        '<svg class="tam-spin" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
                        '<path d="M21 12a9 9 0 11-6.219-8.56"/></svg> <?php echo esc_js(tamrank__('metabox_busy', 'Working...')); ?>'
                    );

                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: {
                            action: 'tamrank_accepteer_schema',
                            nonce: $('#tamrank_detectie_nonce').val(),
                            post_id: postId
                        },
                        success: function (response) {
                            if (response.success) {
                                // Update naar automatisch bron
                                $('input[name="tamrank_schema_bron_keuze"][value="automatisch"]').prop('checked', true).trigger('change');

                                // Update button naar actief status
                                $button.html('<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"/></svg> <?php echo esc_js(tamrank__('metabox_active', 'Active')); ?>');
                                $button.css({
                                    'background': '#e2e8f0',
                                    'color': '#64748b'
                                });

                                // Update advies status badge
                                $button.prev('span').html('<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"/></svg> <?php echo esc_js(tamrank__('metabox_active', 'Active')); ?>');
                                $button.prev('span').css('background', '#22c55e');

                                toonMelding('<?php echo esc_js(tamrank__('schema_advice_applied', 'Schema advice applied!')); ?>', 'succes');
                            } else {
                                $button.prop('disabled', false).html(origineleTekst);
                                toonMelding(response.data?.bericht || '<?php echo esc_js(tamrank__('metabox_generic_error', 'An error occurred')); ?>', 'fout');
                            }
                        },
                        error: function () {
                            $button.prop('disabled', false).html(origineleTekst);
                            toonMelding('<?php echo esc_js(tamrank__('metabox_generic_error', 'An error occurred')); ?>', 'fout');
                        }
                    });
                });

                // =============================================
                // HELPER FUNCTIES
                // =============================================

                function updateStatusbalk(bron) {
                    var $statusbalk = $('.tam-schema-statusbalk');
                    var $bronLabelContainer = $('#tam-bron-label-container');
                    var $bronLabelTekst = $('#tam-bron-label-tekst');

                    // Bron labels mapping
                    var bronLabels = {
                        'automatisch': '<?php echo esc_js(tamrank__('schema_detected', 'Automatically detected')); ?>',
                        'template': '<?php echo esc_js(tamrank__('schema_template', 'Schema template')); ?>',
                        'geen': '<?php echo esc_js(tamrank__('schema_disabled', 'Schema disabled')); ?>'
                    };

                    // Update achtergrond/rand
                    if (bron === 'geen') {
                        $statusbalk.css({
                            'background': '#fef2f2',
                            'border-color': '#fecaca'
                        });
                        $bronLabelContainer.html('<span id="tam-bron-label-tekst" style="color: #dc2626;">' + bronLabels[bron] + '</span>');
                    } else {
                        $statusbalk.css({
                            'background': 'linear-gradient(135deg, #f1f5f9 0%, #f1f5f9 100%)',
                            'border-color': '#e2e8f0'
                        });
                        var bronLabel = '<?php echo esc_js(tamrank__('source', 'Source')); ?>';
                        $bronLabelContainer.html(bronLabel + ': <span id="tam-bron-label-tekst">' + bronLabels[bron] + '</span>');
                    }
                }

                // Maak tamrankUpdateSchemaPreview globaal beschikbaar voor schema-detector.js
                window.tamrankUpdateSchemaPreview = function () {
                    var postId = <?php echo intval($post->ID); ?>;
                    var templateId = $('#tamrank_schema_template_id').val();
                    var bron = $('input[name="tamrank_schema_bron_keuze"]:checked').val() || $('#tamrank_schema_bron').val() || 'automatisch';

                    var overrides = {};
                    $('input[name^="tamrank_schema_overrides"]').each(function () {
                        var name = $(this).attr('name');
                        var matches = name.match(/\[([^\]]+)\]/);
                        if (matches && matches[1] && $(this).val()) {
                            overrides[matches[1]] = $(this).val();
                        }
                    });

                    $('#schema-preview').html('<em class="tam-jsonld-muted"><?php echo esc_js(tamrank__('metabox_preview_generating', 'Generating preview...')); ?></em>');

                    // Als bron "geen" is, toon lege preview
                    if (bron === 'geen') {
                        $('#schema-preview').html('<em class="tam-jsonld-muted"><?php echo esc_js(tamrank__('metabox_schema_disabled', 'Schema is disabled')); ?></em>');
                        return;
                    }

                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: {
                            action: 'tamrank_preview_schema',
                            nonce: '<?php echo esc_js(wp_create_nonce('tamrank_schema_preview')); ?>',
                            post_id: postId,
                            template_id: templateId,
                            bron: bron,
                            overrides: overrides
                        },
                        success: function (response) {
                            if (response.success) {
                                var formatted = JSON.stringify(response.data, null, 2);
                                $('#schema-preview').html('<pre>' + escapeHtml(formatted) + '</pre>');
                            } else {
                                $('#schema-preview').html('<em class="tam-jsonld-error"><?php echo esc_js(tamrank__('metabox_error_prefix', 'Error')); ?>: ' + escapeHtml(response.data || '<?php echo esc_js(tamrank__('metabox_unknown_error', 'Unknown error')); ?>') + '</em>');
                            }
                        },
                        error: function (xhr, status, error) {
                            var errorMsg = '<?php echo esc_js(tamrank__('preview_load_error', 'Error loading preview')); ?>';
                            if (error) errorMsg += ': ' + error;
                            if (xhr.responseText && xhr.responseText.length < 200) errorMsg += ' (' + xhr.responseText + ')';
                            $('#schema-preview').html('<em class="tam-jsonld-error">' + escapeHtml(errorMsg) + '</em>');
                        }
                    });
                }

                function escapeHtml(text) {
                    var map = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' };
                    return text.replace(/[&<>"']/g, function (m) { return map[m]; });
                }

                function toonMelding(bericht, type) {
                    var kleuren = {
                        succes: { bg: '#f0fdf4', border: '#86efac', text: '#166534' },
                        fout: { bg: '#fef2f2', border: '#fca5a5', text: '#991b1b' }
                    };
                    var kleur = kleuren[type] || kleuren.fout;

                    $('.tam-schema-melding').remove();

                    var $melding = $('<div class="tam-schema-melding" style="position: fixed; top: 40px; right: 20px; z-index: 100000; padding: 12px 20px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); background: ' + kleur.bg + '; border: 2px solid ' + kleur.border + '; color: ' + kleur.text + '; font-size: 14px; font-weight: 500;">' + bericht + '</div>');

                    $('body').append($melding);
                    $melding.hide().fadeIn(200);

                    setTimeout(function () {
                        $melding.fadeOut(200, function () { $(this).remove(); });
                    }, 3000);
                }

                // Kopieer JSON-LD
                $('#tam-copy-jsonld').on('click', function () {
                    var jsonText = $('#schema-preview pre').text();
                    if (jsonText) {
                        navigator.clipboard.writeText(jsonText).then(function () {
                            toonMelding('<?php echo esc_js(tamrank__('jsonld_copied', 'JSON-LD copied!')); ?>', 'succes');
                        }).catch(function () {
                            toonMelding('<?php echo esc_js(tamrank__('copy_failed', 'Copy failed')); ?>', 'fout');
                        });
                    }
                });

                // Extra schema toggle styling
                $('#tamrank_extra_auto_detect').on('change', function () {
                    var $thumb = $(this).siblings('.tam-toggle-thumb-small');
                    var $track = $(this).siblings('.tam-toggle-track-small');

                    if (this.checked) {
                        $thumb.css('left', '20px');
                        $track.css('background', 'linear-gradient(135deg, #10b981 0%, #22c55e 100%)');
                    } else {
                        $thumb.css('left', '2px');
                        $track.css('background', 'linear-gradient(135deg, #e2e8f0 0%, #cbd5e1 100%)');
                    }
                });

                // =============================================
                // INITIËLE LOAD - Check velden state bij page load
                // =============================================
                (function () {
                    var bron = $('input[name="tamrank_schema_bron_keuze"]:checked').val() || '<?php echo esc_js($schema_bron); ?>';
                    if (bron && bron !== 'geen') {
                        // Trigger een velden update om de toggle state te bepalen
                        updateSchemaVelden(bron);
                    }
                })();

            });
        <?php
        wp_add_inline_script('tam-rank-meta-box', ob_get_clean());
    }


    /**
     * Render Social tab content
     */
    private function render_social_tab_content($post)
    {
        // Get current values
        $social_title = get_post_meta($post->ID, '_tam_rank_social_title', true);
        $social_description = get_post_meta($post->ID, '_tam_rank_social_description', true);
        $social_image = get_post_meta($post->ID, '_tam_rank_social_image', true);

        // Fallbacks
        $meta_title = get_post_meta($post->ID, '_tam_rank_meta_title', true);
        $meta_description = get_post_meta($post->ID, '_tam_rank_meta_description', true);

        $display_title = !empty($social_title) ? $social_title : (!empty($meta_title) ? $meta_title : $post->post_title);
        $display_description = !empty($social_description) ? $social_description : (!empty($meta_description) ? $meta_description : wp_trim_words($post->post_content, 25, '...'));

        // Get featured image as fallback
        $featured_image_url = '';
        if (!empty($social_image)) {
            $featured_image_url = $social_image;
        } elseif (has_post_thumbnail($post->ID)) {
            $featured_image_url = get_the_post_thumbnail_url($post->ID, 'large');
        }

        $site_name = get_bloginfo('name');
        $post_url = get_permalink($post->ID);
        $domain = wp_parse_url($post_url, PHP_URL_HOST);
        ?>
        <div class="tam-social-tab-content">
            <div class="tam-social-layout">
                <!-- Left Column: Input Fields (Sticky) -->
                <div class="tam-social-sidebar">
                    <!-- Social Title -->
                    <div class="tam-field-group">
                        <div class="tam-field-header">
                            <label for="_tam_rank_social_title">
                                <?php echo esc_html(tamrank__('social_title', 'Social Title')); ?>
                                <?php echo tamrank_render_info_tooltip(tamrank__('social_title_tooltip', 'This title is used for Facebook, X (Twitter), LinkedIn and other social media. Leave empty to use the SEO title.')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- returns escaped, plugin-generated tooltip markup (helper escapes text + attributes internally) ?>
                            </label>
                            <div class="char-counter" id="social-title-counter"></div>
                        </div>
                        <input type="text" id="_tam_rank_social_title" name="_tam_rank_social_title"
                            value="<?php echo esc_attr($social_title); ?>" class="tam-input" data-char-count="true"
                            data-optimal-min="30" data-optimal-max="60" placeholder="<?php echo esc_attr($display_title); ?>">
                    </div>

                    <!-- Social Description -->
                    <div class="tam-field-group">
                        <div class="tam-field-header">
                            <label for="_tam_rank_social_description">
                                <?php echo esc_html(tamrank__('social_description', 'Social Description')); ?>
                                <?php echo tamrank_render_info_tooltip(tamrank__('social_description_tooltip', 'This description is shown when your content is shared on social media. Leave empty to use the SEO description.')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- returns escaped, plugin-generated tooltip markup (helper escapes text + attributes internally) ?>
                            </label>
                            <div class="char-counter" id="social-desc-counter"></div>
                        </div>
                        <textarea id="_tam_rank_social_description" name="_tam_rank_social_description" rows="4"
                            class="tam-input tam-textarea" data-char-count="true" data-optimal-min="50" data-optimal-max="200"
                            placeholder="<?php echo esc_attr(wp_trim_words($display_description, 25, '...')); ?>"><?php echo esc_textarea($social_description); ?></textarea>
                    </div>

                    <!-- Social Image -->
                    <div class="tam-field-group">
                        <label for="_tam_rank_social_image">
                            <?php echo esc_html(tamrank__('social_image', 'Social Image')); ?>
                            <?php echo tamrank_render_info_tooltip(tamrank__('social_image_tooltip', 'Upload an image for social media. Recommended size: 1200x630 pixels. If you don\'t upload an image, the featured image will be used.')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- returns escaped, plugin-generated tooltip markup (helper escapes text + attributes internally) ?>
                        </label>
                        <input type="hidden" id="_tam_rank_social_image" name="_tam_rank_social_image"
                            value="<?php echo esc_url($social_image); ?>">

                        <div class="tam-image-preview" id="social-image-preview"
                            style="<?php echo empty($social_image) ? 'display: none;' : ''; ?>">
                            <?php if (!empty($social_image)): ?>
                                <img src="<?php echo esc_url($social_image); ?>"
                                    alt="<?php echo esc_attr(tamrank__('social_preview', 'Social preview')); ?>">
                                <button type="button" class="tam-remove-image"
                                    aria-label="<?php echo esc_attr(tamrank__('remove_image', 'Remove image')); ?>"
                                    data-tr-tooltip="<?php echo esc_attr(tamrank__('remove_image', 'Remove image')); ?>">&times;</button>
                            <?php endif; ?>
                        </div>

                        <div class="tam-image-upload-buttons">
                            <button type="button" id="upload-social-image" class="button tam-btn tam-btn-green">
                                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                                    stroke-width="2" class="tam-btn-icon">
                                    <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
                                    <circle cx="8.5" cy="8.5" r="1.5"></circle>
                                    <polyline points="21 15 16 10 5 21"></polyline>
                                </svg>
                                <?php echo esc_html(tamrank__('upload_image', 'Upload Image')); ?>
                            </button>
                        </div>

                        <?php if (!empty($featured_image_url) && empty($social_image)): ?>
                            <p class="tam-fallback-hint">
                                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
                                    class="tam-fallback-hint__icon">
                                    <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
                                    <polyline points="22 4 12 14.01 9 11.01"></polyline>
                                </svg>
                                <?php echo esc_html(tamrank__('featured_image_fallback', 'Featured image will be used as fallback')); ?>
                            </p>
                        <?php endif; ?>
                    </div>
                </div>

                <!-- Right Column: Live Previews -->
                <div>
                    <h4 class="tam-section-title"><?php tamrank_e('live_previews', 'Live Previews'); ?></h4>

                    <!-- Facebook Preview -->
                    <div class="tam-social-preview-card">
                        <div class="tam-preview-header">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="#1877F2">
                                <path
                                    d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z" />
                            </svg>
                            <span class="tam-preview-header__label tam-preview-header__label--facebook">Facebook</span>
                        </div>
                        <div class="tam-preview-body tam-facebook-preview">
                            <div class="tam-preview-image" id="fb-preview-image">
                                <?php if (!empty($featured_image_url)): ?>
                                    <img src="<?php echo esc_url($featured_image_url); ?>" alt="">
                                <?php else: ?>
                                    <div class="tam-no-image">
                                        <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#cbd5e1"
                                            stroke-width="1.5">
                                            <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
                                            <circle cx="8.5" cy="8.5" r="1.5"></circle>
                                            <polyline points="21 15 16 10 5 21"></polyline>
                                        </svg>
                                    </div>
                                <?php endif; ?>
                            </div>
                            <div class="tam-preview-content">
                                <div class="tam-preview-domain"><?php echo esc_html($domain); ?></div>
                                <div class="tam-preview-title" id="fb-preview-title"><?php echo esc_html($display_title); ?>
                                </div>
                                <div class="tam-preview-desc" id="fb-preview-desc">
                                    <?php echo esc_html(wp_trim_words($display_description, 20, '...')); ?>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- X (Twitter) Preview -->
                    <div class="tam-social-preview-card">
                        <div class="tam-preview-header">
                            <svg width="18" height="18" viewBox="0 0 24 24" fill="#000">
                                <path
                                    d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
                            </svg>
                            <span class="tam-preview-header__label tam-preview-header__label--x">X (Twitter)</span>
                        </div>
                        <div class="tam-preview-body tam-twitter-preview">
                            <div class="tam-preview-image" id="x-preview-image">
                                <?php if (!empty($featured_image_url)): ?>
                                    <img src="<?php echo esc_url($featured_image_url); ?>" alt="">
                                <?php else: ?>
                                    <div class="tam-no-image">
                                        <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#cbd5e1"
                                            stroke-width="1.5">
                                            <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
                                            <circle cx="8.5" cy="8.5" r="1.5"></circle>
                                            <polyline points="21 15 16 10 5 21"></polyline>
                                        </svg>
                                    </div>
                                <?php endif; ?>
                            </div>
                            <div class="tam-preview-content">
                                <div class="tam-preview-title" id="x-preview-title"><?php echo esc_html($display_title); ?>
                                </div>
                                <div class="tam-preview-desc" id="x-preview-desc">
                                    <?php echo esc_html(wp_trim_words($display_description, 15, '...')); ?>
                                </div>
                                <div class="tam-preview-domain"><?php echo esc_html($domain); ?></div>
                            </div>
                        </div>
                    </div>

                    <!-- LinkedIn Preview -->
                    <div class="tam-social-preview-card">
                        <div class="tam-preview-header">
                            <svg width="18" height="18" viewBox="0 0 24 24" fill="#0A66C2">
                                <path
                                    d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" />
                            </svg>
                            <span class="tam-preview-header__label tam-preview-header__label--linkedin">LinkedIn</span>
                        </div>
                        <div class="tam-preview-body tam-linkedin-preview">
                            <div class="tam-preview-image" id="li-preview-image">
                                <?php if (!empty($featured_image_url)): ?>
                                    <img src="<?php echo esc_url($featured_image_url); ?>" alt="">
                                <?php else: ?>
                                    <div class="tam-no-image">
                                        <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#cbd5e1"
                                            stroke-width="1.5">
                                            <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
                                            <circle cx="8.5" cy="8.5" r="1.5"></circle>
                                            <polyline points="21 15 16 10 5 21"></polyline>
                                        </svg>
                                    </div>
                                <?php endif; ?>
                            </div>
                            <div class="tam-preview-content">
                                <div class="tam-preview-title" id="li-preview-title"><?php echo esc_html($display_title); ?>
                                </div>
                                <div class="tam-preview-domain"><?php echo esc_html($domain); ?></div>
                            </div>
                        </div>
                    </div>

                    <!-- Instagram Preview -->
                    <div class="tam-social-preview-card">
                        <div class="tam-preview-header">
                            <svg width="18" height="18" viewBox="0 0 24 24" fill="url(#instagram-gradient)">
                                <defs>
                                    <linearGradient id="instagram-gradient" x1="0%" y1="100%" x2="100%" y2="0%">
                                        <stop offset="0%" style="stop-color:#FFDC80" />
                                        <stop offset="25%" style="stop-color:#FCAF45" />
                                        <stop offset="50%" style="stop-color:#F77737" />
                                        <stop offset="75%" style="stop-color:#C13584" />
                                        <stop offset="100%" style="stop-color:#833AB4" />
                                    </linearGradient>
                                </defs>
                                <path
                                    d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z" />
                            </svg>
                            <span class="tam-preview-header__label tam-preview-header__label--instagram">Instagram</span>
                        </div>
                        <div class="tam-preview-body tam-instagram-preview">
                            <div class="tam-preview-image tam-instagram-image" id="ig-preview-image">
                                <?php if (!empty($featured_image_url)): ?>
                                    <img src="<?php echo esc_url($featured_image_url); ?>" alt="">
                                <?php else: ?>
                                    <div class="tam-no-image">
                                        <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#cbd5e1"
                                            stroke-width="1.5">
                                            <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
                                            <circle cx="8.5" cy="8.5" r="1.5"></circle>
                                            <polyline points="21 15 16 10 5 21"></polyline>
                                        </svg>
                                    </div>
                                <?php endif; ?>
                            </div>
                            <div class="tam-instagram-caption">
                                <span class="tam-instagram-username"><?php echo esc_html(sanitize_title($site_name)); ?></span>
                                <span class="tam-instagram-text"
                                    id="ig-preview-caption"><?php echo esc_html(wp_trim_words($display_description, 10, '...')); ?></span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>


        <?php ob_start(); ?>
            jQuery(document).ready(function ($) {
                // Default values for fallback
                var defaultTitle = <?php echo wp_json_encode($display_title, JSON_HEX_TAG | JSON_HEX_AMP); ?>;
                var defaultDesc = <?php echo wp_json_encode($display_description, JSON_HEX_TAG | JSON_HEX_AMP); ?>;
                var featuredImageUrl = <?php echo wp_json_encode($featured_image_url, JSON_HEX_TAG | JSON_HEX_AMP); ?>;

                // Update previews on input change
                function updateSocialPreviews() {
                    var title = $('#_tam_rank_social_title').val() || defaultTitle;
                    var desc = $('#_tam_rank_social_description').val() || defaultDesc;

                    // Update all preview titles
                    $('#fb-preview-title, #x-preview-title, #li-preview-title').text(title);

                    // Update descriptions (with different truncation)
                    $('#fb-preview-desc').text(truncateText(desc, 100));
                    $('#x-preview-desc').text(truncateText(desc, 70));
                    $('#ig-preview-caption').text(truncateText(desc, 50));
                }

                function truncateText(text, maxLength) {
                    if (text.length <= maxLength) return text;
                    return text.substring(0, maxLength).trim() + '...';
                }

                // Update live previews on input (char counters handled by main admin.js)
                $('#_tam_rank_social_title').on('input', function () {
                    updateSocialPreviews();
                });

                $('#_tam_rank_social_description').on('input', function () {
                    updateSocialPreviews();
                });

                // Image upload
                var mediaUploader;
                $('#upload-social-image').on('click', function (e) {
                    e.preventDefault();

                    if (mediaUploader) {
                        mediaUploader.open();
                        return;
                    }

                    mediaUploader = wp.media({
                        title: '<?php echo esc_js(tamrank__('select_social_image', 'Select Social Image')); ?>',
                        button: { text: '<?php echo esc_js(tamrank__('metabox_use_this_image', 'Use this image')); ?>' },
                        multiple: false,
                        library: { type: 'image' }
                    });

                    mediaUploader.on('select', function () {
                        var attachment = mediaUploader.state().get('selection').first().toJSON();
                        var imageUrl = attachment.sizes.large ? attachment.sizes.large.url : attachment.url;

                        $('#_tam_rank_social_image').val(imageUrl);
                        updateImagePreviews(imageUrl);
                    });

                    mediaUploader.open();
                });

                // Remove image
                $(document).on('click', '.tam-remove-image', function (e) {
                    e.preventDefault();
                    $('#_tam_rank_social_image').val('');

                    // Use featured image as fallback or show placeholder
                    if (featuredImageUrl) {
                        updateImagePreviews(featuredImageUrl);
                    } else {
                        updateImagePreviews('');
                    }
                });

                function updateImagePreviews(imageUrl) {
                    var $preview = $('#social-image-preview');
                    var previewIds = ['#fb-preview-image', '#x-preview-image', '#li-preview-image', '#ig-preview-image'];

                    if (imageUrl) {
                        // Update main preview
                        $preview.html('<img src="' + imageUrl + '" alt="<?php echo esc_attr(tamrank__('social_preview', 'Social preview')); ?>"><button type="button" class="tam-remove-image" data-tr-tooltip="<?php echo esc_attr(tamrank__('remove_image', 'Remove image')); ?>">&times;</button>').show();

                        // Update all card previews
                        previewIds.forEach(function (id) {
                            $(id).html('<img src="' + imageUrl + '" alt="">');
                        });
                    } else {
                        // Hide main preview
                        $preview.hide().empty();

                        // Show placeholder in card previews
                        var placeholder = '<div class="tam-no-image"><svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#cbd5e1" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline></svg></div>';
                        previewIds.forEach(function (id) {
                            $(id).html(placeholder);
                        });
                    }
                }

                // Initial preview update
                updateSocialPreviews();
            });
        <?php wp_add_inline_script('tam-rank-meta-box', ob_get_clean()); ?>
        <?php
    }

    /**
     * Render the Content tab for content analysis
     */
    private function render_content_tab($post)
    {
        // The Content Tab class is already loaded in tam-rank.php init_admin()
        if (class_exists('TamRank_Content_Tab')) {
            $content_tab = TamRank_Content_Tab::get_instance();
            $content_tab->render($post);
        }
    }

    /**
     * Guards save_meta_boxes() against re-entering itself.
     *
     * The slug branch below writes through wp_update_post(), which fires
     * save_post again with the very same $_POST still in place. Every handler
     * on that hook then runs a second time on data it has already processed —
     * scores recalculated, schema re-detected — for no gain at all.
     *
     * @var bool
     */
    private static $saving = false;

    public function save_meta_boxes($post_id)
    {
        if (self::$saving) {
            return;
        }

        // Check if this is an autosave
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return;
        }

        // A revision carries the same $_POST - nonce included - as the save it
        // was cut from, so without this guard every field below is written to
        // the revision as well. The slug branch is the one that hurts: it reads
        // the revision's own post_name ("123-revision-v1"), sees it differ from
        // the submitted slug and files an automatic redirect for a URL that has
        // never existed. Meta belongs on the parent post; the revision is a
        // snapshot, not an edit target.
        if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) {
            return;
        }

        // Check nonce
        if (!isset($_POST['tam_rank_meta_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['tam_rank_meta_nonce'])), 'tam_rank_meta_nonce')) {
            return;
        }

        // Check user permissions
        if (!current_user_can('edit_post', $post_id)) {
            return;
        }

        // Save meta title
        if (isset($_POST['_tam_rank_meta_title'])) {
            update_post_meta($post_id, '_tam_rank_meta_title', sanitize_text_field(wp_unslash($_POST['_tam_rank_meta_title'])));
        }

        // Save meta description
        if (isset($_POST['_tam_rank_meta_description'])) {
            update_post_meta($post_id, '_tam_rank_meta_description', sanitize_textarea_field(wp_unslash($_POST['_tam_rank_meta_description'])));
        }

        // Save focus keyword
        if (isset($_POST['_tam_rank_focus_keyword'])) {
            $primary_keyword = sanitize_text_field(wp_unslash($_POST['_tam_rank_focus_keyword']));
            update_post_meta($post_id, '_tam_rank_focus_keyword', $primary_keyword);

            // Save secondary keywords enabled status (FREE since 19 apr 2026)
            $secondary_enabled = isset($_POST['_tamrank_secondary_keywords_enabled']) ? '1' : '0';
            update_post_meta($post_id, '_tamrank_secondary_keywords_enabled', $secondary_enabled);

            // Save secondary keywords only if enabled
            if ($secondary_enabled === '1' && isset($_POST['_tamrank_secondary_keywords'])) {
                $secondary = array_map('sanitize_text_field', wp_unslash((array) $_POST['_tamrank_secondary_keywords']));
                TamRank_Keywords::save_keywords($post_id, $primary_keyword, $secondary);
            } elseif ($secondary_enabled === '0') {
                // Clear secondary keywords when disabled
                TamRank_Keywords::save_keywords($post_id, $primary_keyword, []);
            }
        }

        // Save and apply custom slug with validation
        if (isset($_POST['_tam_rank_custom_slug'])) {
            $new_slug = sanitize_title(wp_unslash($_POST['_tam_rank_custom_slug']));
            $current_post = get_post($post_id);
            $old_slug = $current_post->post_name;

            // Only update if slug is different and not empty
            if (!empty($new_slug) && $new_slug !== $old_slug) {
                // Check if slug is unique
                $slug_check = get_page_by_path($new_slug, OBJECT, $current_post->post_type);

                // If slug exists and it's not the current post, make it unique
                if ($slug_check && $slug_check->ID !== $post_id) {
                    $new_slug = wp_unique_post_slug($new_slug, $post_id, $current_post->post_status, $current_post->post_type, $current_post->post_parent);
                }

                // Uniqueness can hand back exactly the slug the post already
                // carries: type "diensten" into the field while another page
                // owns /diensten/ and this post is already on "diensten-2", and
                // wp_unique_post_slug() answers "diensten-2".
                //
                // Saving that through wp_update_post() would be a no-op write
                // that still fires save_post, and the nested pass compares the
                // SAME submitted "diensten" against the stored "diensten-2"
                // again — the two can never converge, so the request recurses
                // until it runs out of memory and the editor gets a 500 with no
                // explanation. Recording the resolved slug and stopping is what
                // ends it: the field now agrees with reality, and the next save
                // finds nothing left to change.
                if ($new_slug === $old_slug) {
                    update_post_meta($post_id, '_tam_rank_custom_slug', $new_slug);
                } else {
                    // Store old URL for redirect
                    $old_url = get_permalink($post_id);

                    // Update post slug
                    self::$saving = true;
                    wp_update_post(array(
                        'ID' => $post_id,
                        'post_name' => $new_slug
                    ));
                    self::$saving = false;

                    // Save to meta for tracking
                    update_post_meta($post_id, '_tam_rank_custom_slug', $new_slug);

                    // Create automatic redirect from old URL to new URL
                    if (!empty($old_slug)) {
                        $this->create_automatic_redirect($old_slug, $new_slug, $post_id);
                    }
                }
            }
        }

        // Save canonical URL
        if (isset($_POST['_tam_rank_canonical'])) {
            update_post_meta($post_id, '_tam_rank_canonical', sanitize_url(wp_unslash($_POST['_tam_rank_canonical'])));
        }

        // Save noindex
        if (isset($_POST['_tam_rank_noindex'])) {
            update_post_meta($post_id, '_tam_rank_noindex', 1);
        } else {
            delete_post_meta($post_id, '_tam_rank_noindex');
        }

        // Save nofollow
        if (isset($_POST['_tam_rank_nofollow'])) {
            update_post_meta($post_id, '_tam_rank_nofollow', 1);
        } else {
            delete_post_meta($post_id, '_tam_rank_nofollow');
        }

        // Save advanced robots directives (noarchive, nosnippet, max-snippet, ...).
        // Nonce and capability were verified at the top of this method; the helper
        // sanitizes every value per directive type before writing.
        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified at the top of save_meta_boxes(); values are sanitized per directive inside the helper.
        tamrank_save_robots_directives($post_id, wp_unslash($_POST), 'post');

        // Save Schema settings (if schema nonce is present)
        if (isset($_POST['tamrank_schema_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['tamrank_schema_nonce'])), 'tamrank_schema_meta_box')) {
            // Save enabled status
            $enabled = isset($_POST['tamrank_schema_enabled']) ? '1' : '0';
            update_post_meta($post_id, 'tamrank_schema_enabled', $enabled);

            // Save schema bron (source)
            if (isset($_POST['tamrank_schema_bron'])) {
                $bron = sanitize_text_field(wp_unslash($_POST['tamrank_schema_bron']));
                // Validate bron value
                $valid_bron_values = array('automatisch', 'template', 'geen');
                if (in_array($bron, $valid_bron_values, true)) {
                    update_post_meta($post_id, 'tamrank_schema_bron', $bron);
                }
            }

            // Save template ID
            if (isset($_POST['tamrank_schema_template_id'])) {
                update_post_meta($post_id, 'tamrank_schema_template_id', sanitize_text_field(wp_unslash($_POST['tamrank_schema_template_id'])));
            }

            // Save overrides
            if (isset($_POST['tamrank_schema_overrides']) && is_array($_POST['tamrank_schema_overrides'])) {
                $overrides = array_map('sanitize_text_field', wp_unslash((array) $_POST['tamrank_schema_overrides']));
                // Remove empty values
                $overrides = array_filter($overrides, function ($value) {
                    return !empty($value);
                });
                update_post_meta($post_id, 'tamrank_schema_overrides', $overrides);
            }
        }

        // Save Social settings
        if (isset($_POST['_tam_rank_social_title'])) {
            update_post_meta($post_id, '_tam_rank_social_title', sanitize_text_field(wp_unslash($_POST['_tam_rank_social_title'])));
        }

        if (isset($_POST['_tam_rank_social_description'])) {
            update_post_meta($post_id, '_tam_rank_social_description', sanitize_textarea_field(wp_unslash($_POST['_tam_rank_social_description'])));
        }

        if (isset($_POST['_tam_rank_social_image'])) {
            update_post_meta($post_id, '_tam_rank_social_image', sanitize_url(wp_unslash($_POST['_tam_rank_social_image'])));
        }

    }

    // Obsolete calculate_live_score method removed (logic moved to TamRank_Meta_Calculator)


    /**
     * Get score class for styling
     * Drempels: 80+ Uitstekend, 60-79 Goed, 40-59 Aandacht nodig, 0-39 Verbeteren
     */
    private function get_score_class($score)
    {
        if ($score >= 80)
            return 'tam-score-excellent';
        if ($score >= 60)
            return 'tam-score-good';
        if ($score >= 40)
            return 'tam-score-average';
        return 'tam-score-poor';
    }

    /**
     * Get score color
     * Drempels: 80+ Groen, 60-79 Blauw, 40-59 Oranje, 0-39 Roze
     */
    private function get_score_color($score)
    {
        if ($score >= 80)
            return 'var(--tr-color-status-excellent)'; // Groen - Uitstekend
        if ($score >= 60)
            return 'var(--tr-color-status-good)'; // Teal - Goed
        if ($score >= 40)
            return 'var(--tr-color-status-attention)'; // Oranje - Aandacht nodig
        return 'var(--tr-color-error)'; // Rood - Verbeteren
    }

    /**
     * Create automatic redirect when URL changes
     */
    private function create_automatic_redirect($old_slug, $new_slug, $post_id)
    {
        // Get the post to construct full paths
        $post = get_post($post_id);

        // Build old path (relative)
        $old_path = '/' . $old_slug;

        // For hierarchical post types, include parent path
        if (is_post_type_hierarchical($post->post_type) && $post->post_parent) {
            $parent = get_post($post->post_parent);
            if ($parent) {
                $parent_path = str_replace(home_url(), '', get_permalink($parent->ID));
                $parent_path = trim(wp_parse_url($parent_path, PHP_URL_PATH), '/');
                $old_path = '/' . $parent_path . '/' . $old_slug;
            }
        }

        // Get the new full URL (post already has the new slug at this point)
        $new_url = get_permalink($post_id);

        // Use the redirect manager to create the redirect in the database
        global $tam_rank_redirect_manager;

        if (isset($tam_rank_redirect_manager) && method_exists($tam_rank_redirect_manager, 'create_redirect')) {
            // The redirect manager handles duplicate checking
            // Pass true for auto_generated parameter to mark as automatically created by Tam Rank
            $tam_rank_redirect_manager->create_redirect($old_path, $new_url, '301', true);
        }
    }

    /**
     * Render variable insertion buttons for meta fields
     *
     * @param string $target_field_id The ID of the target input field
     */
    private function render_variable_buttons($target_field_id)
    {
        if (!function_exists('tamrank_get_available_variables')) {
            return;
        }

        $variables = tamrank_get_available_variables();
        $unique_id = 'tamrank-vars-' . esc_attr($target_field_id);
        ?>
        <div class="tamrank-variable-wrapper" data-target="<?php echo esc_attr($target_field_id); ?>">
            <button type="button" class="tamrank-vars-toggle" data-toggle="<?php echo esc_attr($unique_id); ?>">
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
                    stroke-linecap="round" stroke-linejoin="round">
                    <polyline points="4 7 4 4 20 4 20 7"></polyline>
                    <line x1="9" y1="20" x2="15" y2="20"></line>
                    <line x1="12" y1="4" x2="12" y2="20"></line>
                </svg>
                <span><?php tamrank_e('insert_variables', 'Insert variables'); ?></span>
            </button>

            <div id="<?php echo esc_attr($unique_id); ?>" class="tamrank-vars-container">
                <div class="tamrank-vars-grid">
                    <?php foreach ($variables as $var => $label): ?>
                        <button type="button" class="tamrank-var-btn" data-var="<?php echo esc_attr($var); ?>"
                            data-tr-tooltip="<?php echo esc_attr($label); ?>">
                            <?php echo esc_html($var); ?>
                        </button>
                    <?php endforeach; ?>
                </div>
            </div>
        </div>
        <?php ob_start(); ?>
            (function () {
                var wrapper = document.querySelector('.tamrank-variable-wrapper[data-target="<?php echo esc_js($target_field_id); ?>"]');
                if (!wrapper) return;

                var toggle = wrapper.querySelector('.tamrank-vars-toggle');
                var container = wrapper.querySelector('.tamrank-vars-container');
                var buttons = wrapper.querySelectorAll('.tamrank-var-btn');

                // Toggle click
                toggle.addEventListener('click', function (e) {
                    e.preventDefault();
                    container.classList.toggle('tamrank-vars-container--open');
                });

                // Variable buttons
                buttons.forEach(function (btn) {
                    btn.addEventListener('click', function (e) {
                        e.preventDefault();
                        var varText = this.getAttribute('data-var');
                        var targetId = wrapper.getAttribute('data-target');
                        var targetField = document.getElementById(targetId);

                        if (targetField) {
                            var start = targetField.selectionStart;
                            var end = targetField.selectionEnd;
                            var text = targetField.value;
                            targetField.value = text.substring(0, start) + varText + text.substring(end);
                            targetField.focus();
                            targetField.selectionStart = targetField.selectionEnd = start + varText.length;

                            // Trigger input event for character counter update
                            var event = new Event('input', { bubbles: true });
                            targetField.dispatchEvent(event);
                        }
                    });
                });
            })();
        <?php wp_add_inline_script('tam-rank-meta-box', ob_get_clean()); ?>
        <?php
    }

    /**
     * Render floating widget globally for all post edit screens
     * This ensures it works in Divi, Gutenberg, Classic Editor, etc.
     */
    public function render_floating_widget()
    {
        // Only show on post edit screens — never on media attachments (their
        // SEO meta box is excluded too; the attachment edit screen has base
        // 'post' in WP 7.0, so gate on post_type, not just base).
        $screen = get_current_screen();
        if (!$screen
            || !in_array($screen->base, array('post', 'page'), true)
            || (isset($screen->post_type) && $screen->post_type === 'attachment')) {
            return;
        }

        $general_settings = tam_rank_cached_option('tam_rank_general_settings', array());

        // Only show if enabled in settings
        if (isset($general_settings['enable_meta_boxes']) && !$general_settings['enable_meta_boxes']) {
            return;
        }
        ?>
        <!-- Floating SEO Widget -->
        <div id="tam-rank-floating-widget" class="tam-rank-floating-widget" style="display: none;">
            <div class="tam-widget-header">
                <div style="display: flex; align-items: center; gap: 6px;">
                    <svg width="20" height="20" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <rect x="4" y="4" width="32" height="32" rx="8" fill="#1e293b"/>
                        <rect x="10" y="10" width="20" height="5" rx="2" fill="#10b981"/>
                        <rect x="15" y="10" width="5" height="20" rx="2" fill="#10b981"/>
                        <rect x="22" y="18" width="5" height="12" rx="2" fill="#10b981" opacity="0.5"/>
                    </svg>
                    <strong>TamRank SEO</strong>
                </div>
                <div style="display: flex; align-items: center; gap: 8px;">
                    <span id="floating-score-badge" class="score-badge">0%</span>
                    <button type="button" id="tam-widget-toggle" class="tam-widget-toggle" aria-label="<?php echo esc_attr(tamrank__('toggle_widget', 'Toggle widget')); ?>">
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                            <polyline points="6 9 12 15 18 9"></polyline>
                        </svg>
                    </button>
                </div>
            </div>

            <div class="tam-widget-body" id="tam-widget-body">
                <div style="padding: 15px;">
                    <!-- Meta Score (30%) -->
                    <div class="tam-floating-subscore" style="margin-bottom: 12px;">
                        <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 6px;">
                            <div
                                style="width: 24px; height: 24px; background: var(--tr-color-slate-100); border-radius: 4px; display: flex; align-items: center; justify-content: center;">
                                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--tr-color-slate-500)" stroke-width="2">
                                    <circle cx="11" cy="11" r="8" />
                                    <path d="M21 21L16.65 16.65" />
                                </svg>
                            </div>
                            <span
                                style="font-size: 12px; font-weight: 600; color: var(--tr-color-slate-800);"><?php tamrank_e('meta_short', 'Meta'); ?></span>
                            <span style="font-size: 10px; color: var(--tr-color-slate-400);">(30%)</span>
                            <span id="floating-meta-score"
                                style="margin-left: auto; font-size: 13px; font-weight: 700;">0%</span>
                        </div>
                        <div style="height: 5px; background: var(--tr-color-slate-200); border-radius: 3px; overflow: hidden;">
                            <div id="floating-meta-bar"
                                style="height: 100%; width: 0%; background: var(--tr-color-error); transition: all 0.3s ease;"></div>
                        </div>
                    </div>

                    <!-- Content Score (70%) -->
                    <div class="tam-floating-subscore" style="margin-bottom: 12px;">
                        <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 6px;">
                            <div
                                style="width: 24px; height: 24px; background: var(--tr-color-slate-100); border-radius: 4px; display: flex; align-items: center; justify-content: center;">
                                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--tr-color-slate-500)" stroke-width="2">
                                    <path
                                        d="M14 2H6C5.46957 2 4.96086 2.21071 4.58579 2.58579C4.21071 2.96086 4 3.46957 4 4V20C4 20.5304 4.21071 21.0391 4.58579 21.4142C4.96086 21.7893 5.46957 22 6 22H18C18.5304 22 19.0391 21.7893 19.4142 21.4142C19.7893 21.0391 20 20.5304 20 20V8L14 2Z" />
                                    <polyline points="14 2 14 8 20 8" />
                                </svg>
                            </div>
                            <span
                                style="font-size: 12px; font-weight: 600; color: var(--tr-color-slate-800);"><?php tamrank_e('content_short', 'Content'); ?></span>
                            <span style="font-size: 10px; color: var(--tr-color-slate-400);">(70%)</span>
                            <span id="floating-content-score"
                                style="margin-left: auto; font-size: 13px; font-weight: 700;">0%</span>
                        </div>
                        <div style="height: 5px; background: var(--tr-color-slate-200); border-radius: 3px; overflow: hidden;">
                            <div id="floating-content-bar"
                                style="height: 100%; width: 0%; background: var(--tr-color-error); transition: all 0.3s ease;"></div>
                        </div>
                    </div>

                    <!-- Schema Status (geen score) -->
                    <div class="tam-floating-schema"
                        style="background: linear-gradient(135deg, var(--tr-color-warning-light) 0%, var(--tr-color-warning-bg) 100%); border: 1px solid var(--tr-color-warning); border-radius: 6px; padding: 10px 12px; margin-bottom: 12px;">
                        <div style="display: flex; align-items: center; gap: 8px;">
                            <div
                                style="width: 24px; height: 24px; background: rgba(255,255,255,0.6); border-radius: 4px; display: flex; align-items: center; justify-content: center;">
                                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--tr-color-slate-500)" stroke-width="2">
                                    <path d="M12 2L2 7L12 12L22 7L12 2Z" />
                                    <path d="M2 17L12 22L22 17" />
                                    <path d="M2 12L12 17L22 12" />
                                </svg>
                            </div>
                            <span
                                style="font-size: 12px; font-weight: 600; color: var(--tr-color-slate-800);"><?php tamrank_e('schema_short', 'Schema'); ?></span>
                            <span id="floating-schema-status"
                                style="margin-left: auto; display: flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; color: var(--tr-color-warning);">
                                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                                    stroke-width="2">
                                    <path
                                        d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" />
                                    <line x1="12" y1="9" x2="12" y2="13" />
                                    <line x1="12" y1="17" x2="12.01" y2="17" />
                                </svg>
                                <?php tamrank_e('schema_none', 'No schema'); ?>
                            </span>
                        </div>
                    </div>

                    <!-- View Full Analysis Button -->
                    <button type="button" id="tam-view-full-analysis"
                        style="width: 100%; padding: 10px 12px; background: var(--tr-color-primary); color: var(--tr-color-white); border: none; border-radius: var(--tr-radius-md); font-size: 12px; font-weight: 600; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 6px; transition: all var(--tr-transition-base);">
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
                            stroke-linecap="round" stroke-linejoin="round">
                            <polyline points="6 9 12 15 18 9"></polyline>
                        </svg>
                        <?php tamrank_e('view_full_analysis', 'View full analysis'); ?>
                    </button>
                </div>
            </div>
        </div>


        <?php ob_start(); ?>
            jQuery(document).ready(function ($) {
                // Simple approach: Show widget on ALL post edit pages
                // Widget will appear over Divi iframe due to high z-index
                function showFloatingWidget() {
                    // Check if we're on a post/page edit screen
                    const isEditScreen = $('#post').length > 0 ||
                        $('body').hasClass('post-php') ||
                        $('body').hasClass('post-new-php') ||
                        $('body').hasClass('et-db') ||
                        $('body').hasClass('et_divi_builder');

                    if (isEditScreen) {
                        $('#tam-rank-floating-widget').fadeIn();
                        return true;
                    }

                    return false;
                }

                // Try to show widget immediately - always start expanded (not collapsed)
                if (!showFloatingWidget()) {
                    // If not detected immediately, try again
                    setTimeout(showFloatingWidget, 500);
                    setTimeout(showFloatingWidget, 1500);
                }

                // Ensure widget starts expanded (remove any collapsed class)
                $('#tam-rank-floating-widget').removeClass('collapsed');

                // Toggle widget collapse
                $('.tam-widget-header').on('click', function (e) {
                    e.preventDefault();
                    e.stopPropagation();
                    $('#tam-rank-floating-widget').toggleClass('collapsed');
                });

                $('#tam-widget-toggle').on('click', function (e) {
                    e.preventDefault();
                    e.stopPropagation();
                    $('#tam-rank-floating-widget').toggleClass('collapsed');
                });

                // Scroll to full analysis when button clicked
                $(document).on('click', '#tam-view-full-analysis', function (e) {
                    e.preventDefault();
                    e.stopPropagation();

                    // Close the floating widget first
                    $('#tam-rank-floating-widget').addClass('collapsed');

                    // Switch to SEO tab first
                    $('.tam-meta-tab').removeClass('active');
                    $('.tam-meta-tab[data-tab="seo"]').addClass('active');
                    $('.tam-meta-tab-content').removeClass('active');
                    $('#tam-tab-seo').addClass('active');

                    // Check if we're in Divi builder iframe
                    const isDiviBuilder = $('body').hasClass('et-db') || $('body').hasClass('et_divi_builder');

                    if (isDiviBuilder && window.parent !== window) {
                        try {
                            window.parent.scrollTo({ top: 0, behavior: 'smooth' });
                        } catch (err) {
                            // parent-frame scroll unavailable (cross-origin / no parent)
                        }
                        return;
                    }

                    // In the Gutenberg code editor ("text" mode) the classic meta boxes
                    // are not rendered, so scrolling lands on a hidden element. Switch
                    // back to the visual editor first so the meta box re-renders, then
                    // give it extra time before scrolling.
                    let switchedFromCodeEditor = false;
                    try {
                        if (window.wp && wp.data && wp.data.select('core/edit-post')
                            && typeof wp.data.select('core/edit-post').getEditorMode === 'function'
                            && wp.data.select('core/edit-post').getEditorMode() === 'text') {
                            wp.data.dispatch('core/edit-post').switchEditorMode('visual');
                            switchedFromCodeEditor = true;
                        }
                    } catch (err) {
                        // editor-mode detection unavailable
                    }

                    // In the block editor the classic meta boxes live in a
                    // collapsible drawer at the bottom. When that drawer is
                    // collapsed its liner is display:none and the postbox has
                    // zero height, so scrolling lands on nothing. Expand the
                    // drawer first by clicking its toggle (label-independent:
                    // the toggle is the aria-expanded button outside the liner).
                    let expandedMetaBoxDrawer = false;
                    try {
                        const $liner = $('.edit-post-meta-boxes-main__liner, .editor-meta-boxes-area__liner');
                        if ($liner.length && $liner.css('display') === 'none') {
                            const $drawerToggle = $('.edit-post-meta-boxes-main, .editor-meta-boxes-area')
                                .find('button[aria-expanded="false"]')
                                .filter(function () {
                                    return $(this).closest('.edit-post-meta-boxes-main__liner, .editor-meta-boxes-area__liner').length === 0;
                                }).first();
                            if ($drawerToggle.length) {
                                $drawerToggle.trigger('click');
                                expandedMetaBoxDrawer = true;
                            }
                        }
                    } catch (err) {
                        // meta-box drawer toggle unavailable
                    }

                    const scrollDelay = (switchedFromCodeEditor || expandedMetaBoxDrawer) ? 800 : 300;

                    // Find the postbox (WordPress meta box container)
                    let postbox = $('#tam-rank-seo').closest('.postbox');

                    if (!postbox.length) {
                        postbox = $('.tam-rank-meta-box').closest('.postbox');
                    }

                    if (postbox.length) {

                        // Check if postbox is closed
                        if (postbox.hasClass('closed')) {

                            // Open the postbox by clicking the toggle button
                            const toggleButton = postbox.find('.handlediv, .handle-order-higher, .handle-order-lower').first();

                            // Remove closed class and trigger click
                            postbox.removeClass('closed');

                            // If toggle button exists, click it
                            if (toggleButton.length) {
                                toggleButton.trigger('click');
                            }

                            // Show the inside content
                            postbox.find('.inside').show();
                        }

                        // Wait for postbox to open, then scroll
                        setTimeout(function () {

                            // Scroll to the postbox
                            postbox[0].scrollIntoView({
                                behavior: 'smooth',
                                block: 'start'
                            });

                            // Add visual highlight after scroll
                            setTimeout(function () {
                                postbox.css({
                                    'box-shadow': '0 0 20px rgba(37, 172, 117, 0.5)',
                                    'transition': 'box-shadow 0.3s ease'
                                });

                                setTimeout(function () {
                                    postbox.css('box-shadow', '');
                                }, 2000);
                            }, 500);
                        }, scrollDelay);
                    } else {
                        // Fallback: try to find element directly
                        const target = $('#tam-rank-seo')[0] || $('.tam-rank-meta-box')[0];

                        if (target) {
                            target.scrollIntoView({
                                behavior: 'smooth',
                                block: 'start'
                            });
                        } else {
                            // Last resort: scroll to top
                            window.scrollTo({ top: 0, behavior: 'smooth' });
                        }
                    }
                });

                // Score color helper
                function getScoreColor(score) {
                    const style = getComputedStyle(document.documentElement);
                    if (score >= 80) return style.getPropertyValue('--tr-color-status-excellent').trim();
                    if (score >= 60) return style.getPropertyValue('--tr-color-status-good').trim();
                    if (score >= 40) return style.getPropertyValue('--tr-color-status-attention').trim();
                    return style.getPropertyValue('--tr-color-error').trim();
                }

                // Score class helper
                function getScoreClass(score) {
                    if (score >= 80) return 'excellent';
                    if (score >= 60) return 'good';
                    if (score >= 40) return 'average';
                    return 'poor';
                }

                // Store content score (updated by content-tab.js event)
                let currentContentScore = 0;

                // Listen for content score updates
                $(document).on('tamrank:contentScoreUpdated', function (e, data) {
                    if (data && typeof data.score !== 'undefined') {
                        currentContentScore = parseInt(data.score) || 0;
                        updateFloatingWidget();
                    }
                });

                // Update floating widget when scores change
                function updateFloatingWidget() {
                    // Get Meta Score from SEO tab
                    const metaScoreText = $('#live-score-value-main').text();
                    const metaScore = parseInt(metaScoreText) || 0;
                    const metaColor = getScoreColor(metaScore);

                    // Content Score (from content-tab.js or stored value)
                    let contentScore = currentContentScore;
                    // Also try to get from Content tab if available
                    const contentScoreText = $('#content-score-value').text();
                    if (contentScoreText) {
                        contentScore = parseInt(contentScoreText) || contentScore;
                    }
                    const contentColor = getScoreColor(contentScore);

                    // Calculate Total Score: Meta (30%) + Content (70%)
                    const totalScore = Math.round(metaScore * 0.30 + contentScore * 0.70);
                    const totalColor = getScoreColor(totalScore);
                    const totalClass = getScoreClass(totalScore);

                    // Update Total Score badge in header
                    $('#floating-score-badge')
                        .text(totalScore + '%')
                        .removeClass('excellent good average poor')
                        .addClass(totalClass);

                    // Update Meta Score display
                    $('#floating-meta-score').text(metaScore + '%').css('color', metaColor);
                    $('#floating-meta-bar').css({
                        'width': metaScore + '%',
                        'background': metaColor
                    });

                    // Update Content Score display
                    $('#floating-content-score').text(contentScore + '%').css('color', contentColor);
                    $('#floating-content-bar').css({
                        'width': contentScore + '%',
                        'background': contentColor
                    });

                    // Update Schema Status
                    updateSchemaStatus();
                }

                // Update schema status in floating widget
                function updateSchemaStatus() {
                    // Get schema bron from hidden field or radio button
                    let schemaBron = $('#tamrank_schema_bron').val();
                    if (!schemaBron) {
                        const checkedRadio = $('input[name="tamrank_schema_bron_keuze"]:checked');
                        schemaBron = checkedRadio.length ? checkedRadio.val() : 'geen';
                    }

                    const $schemaContainer = $('.tam-floating-schema');
                    const $schemaStatus = $('#floating-schema-status');

                    // Check for detected schemas (from tamrankDetectieData if available)
                    let hasDetectedSchema = false;
                    let detectedSchemaName = '';
                    if (typeof tamrankDetectieData !== 'undefined' && tamrankDetectieData.hoofdSchema) {
                        hasDetectedSchema = true;
                        detectedSchemaName = tamrankDetectieData.hoofdSchema;
                        if (tamrankDetectieData.extraSchemas && tamrankDetectieData.extraSchemas.length > 0) {
                            detectedSchemaName += ' + ' + tamrankDetectieData.extraSchemas.length;
                        }
                    }

                    // Determine status based on bron
                    if (schemaBron === 'geen') {
                        // Geen schema - warning yellow
                        $schemaContainer
                            .removeClass('schema-active schema-auto')
                            .css({
                                'background': 'linear-gradient(135deg, var(--tr-color-warning-light) 0%, var(--tr-color-warning-bg) 100%)',
                                'border-color': 'var(--tr-color-warning)'
                            });
                        $schemaStatus.html(
                            '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
                            '<path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/>' +
                            '<line x1="12" y1="9" x2="12" y2="13"/>' +
                            '<line x1="12" y1="17" x2="12.01" y2="17"/>' +
                            '</svg> <?php echo esc_js(tamrank__('schema_none', 'No schema')); ?>'
                        ).css('color', 'var(--tr-color-warning)');
                    } else if (schemaBron === 'automatisch' && hasDetectedSchema) {
                        // Automatisch met gedetecteerd schema - green active
                        $schemaContainer
                            .addClass('schema-active')
                            .removeClass('schema-auto')
                            .css({
                                'background': 'linear-gradient(135deg, var(--tr-color-success-light) 0%, var(--tr-color-success-bg) 100%)',
                                'border-color': 'var(--tr-color-primary)'
                            });
                        $schemaStatus.html(
                            '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
                            '<polyline points="20 6 9 17 4 12"/>' +
                            '</svg> ' + detectedSchemaName
                        ).css('color', 'var(--tr-color-primary)');
                    } else if (schemaBron === 'automatisch' && !hasDetectedSchema) {
                        // Automatisch maar geen detectie - blue auto
                        $schemaContainer
                            .addClass('schema-auto')
                            .removeClass('schema-active')
                            .css({
                                'background': 'linear-gradient(135deg, var(--tr-color-primary-light) 0%, var(--tr-color-success-bg) 100%)',
                                'border-color': 'var(--tr-color-primary)'
                            });
                        $schemaStatus.html(
                            '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
                            '<path d="M12 3l1.912 5.813a2 2 0 001.272 1.272L21 12l-5.816 1.915a2 2 0 00-1.272 1.272L12 21l-1.912-5.813a2 2 0 00-1.272-1.272L3 12l5.816-1.915a2 2 0 001.272-1.272L12 3z"/>' +
                            '</svg> <?php echo esc_js(tamrank__('schema_auto', 'Auto-detection')); ?>'
                        ).css('color', 'var(--tr-color-primary)');
                    } else if (schemaBron === 'template') {
                        // Template schema - green active
                        const templateName = $('#tamrank_schema_template_id option:selected').text() || '<?php echo esc_js(tamrank__('metabox_schema_theme_fallback', 'Schema theme')); ?>';
                        $schemaContainer
                            .addClass('schema-active')
                            .removeClass('schema-auto')
                            .css({
                                'background': 'linear-gradient(135deg, var(--tr-color-success-light) 0%, var(--tr-color-success-bg) 100%)',
                                'border-color': 'var(--tr-color-primary)'
                            });
                        $schemaStatus.html(
                            '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
                            '<polyline points="20 6 9 17 4 12"/>' +
                            '</svg> <?php echo esc_js(tamrank__('schema_active', 'Schema active')); ?>'
                        ).css('color', 'var(--tr-color-primary)');
                    } else {
                        // Fallback - geen schema
                        $schemaContainer
                            .removeClass('schema-active schema-auto')
                            .css({
                                'background': 'linear-gradient(135deg, var(--tr-color-warning-light) 0%, var(--tr-color-warning-bg) 100%)',
                                'border-color': 'var(--tr-color-warning)'
                            });
                        $schemaStatus.html(
                            '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
                            '<path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/>' +
                            '<line x1="12" y1="9" x2="12" y2="13"/>' +
                            '<line x1="12" y1="17" x2="12.01" y2="17"/>' +
                            '</svg> <?php echo esc_js(tamrank__('schema_none', 'No schema')); ?>'
                        ).css('color', 'var(--tr-color-warning)');
                    }
                }

                // Listen for schema bron changes
                $(document).on('change', 'input[name="tamrank_schema_bron_keuze"]', function () {
                    updateSchemaStatus();
                });

                // Watch for changes to update floating widget
                const observer = new MutationObserver(updateFloatingWidget);
                const targetNode = document.getElementById('live-score-value-main');
                if (targetNode) {
                    observer.observe(targetNode, { childList: true, characterData: true, subtree: true });
                }

                // Initial update
                setTimeout(updateFloatingWidget, 500);

                // Auto-collapse floating widget when user scrolls to meta box
                // Using Intersection Observer for reliable detection
                function setupMetaBoxObserver() {
                    const $widget = $('#tam-rank-floating-widget');
                    if (!$widget.length) return;

                    // Find meta box element
                    let metaBox = document.getElementById('tam-rank-seo');
                    if (!metaBox) {
                        metaBox = document.querySelector('.tam-rank-meta-box');
                    }
                    if (!metaBox) {
                        metaBox = document.querySelector('.postbox[id*="tam-rank"]');
                    }
                    if (!metaBox) return;

                    // Create observer - triggers when element is significantly visible
                    const observer = new IntersectionObserver(function (entries) {
                        entries.forEach(function (entry) {
                            if (entry.isIntersecting) {
                                // Meta box is visible, collapse the floating widget
                                $widget.addClass('collapsed');
                            }
                        });
                    }, {
                        root: null, // viewport
                        rootMargin: '-100px 0px 0px 0px', // Require 100px scroll into viewport before triggering
                        threshold: 0.5 // trigger when 50% visible (was 10%)
                    });

                    observer.observe(metaBox);
                }

                // Initialize observer after DOM is ready and widget has been shown
                // Delay longer to ensure widget is visible first before auto-collapsing
                setTimeout(setupMetaBoxObserver, 1000);

                // Watch for body class changes (for late-loading editors)
                const bodyObserver = new MutationObserver(function (mutations) {
                    mutations.forEach(function (mutation) {
                        if (mutation.attributeName === 'class') {
                            showFloatingWidget();
                        }
                    });
                });

                bodyObserver.observe(document.body, {
                    attributes: true,
                    attributeFilter: ['class']
                });
            });
        <?php
        wp_add_inline_script('tam-rank-meta-box', ob_get_clean());
    }
}
