<?php

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

class SEO_Fury_Post_Meta_Schema {

    private $schema_types = array(
        'none' => 'None',
        'article' => 'Article',
        'product' => 'Product',
        'review' => 'Review',
        'recipe' => 'Recipe',
        'faq' => 'FAQ Page',
        'how_to' => 'How To',
        'breadcrumb' => 'BreadcrumbList',
        'table' => 'Table',
        'service' => 'Service',
        'job_posting' => 'Job Posting',
        'course' => 'Course',
        'event' => 'Event',
        'local_business' => 'Local Business',
        'organization' => 'Organization',
        'person' => 'Person',
        'video' => 'Video Object',
        'book' => 'Book',
        'software' => 'Software Application',
    );

    private $schema_types_translated = null;

    private $schema_icons = array(
        'article' => 'dashicons-media-document',
        'product' => 'dashicons-cart',
        'review' => 'dashicons-star-filled',
        'recipe' => 'dashicons-carrot',
        'faq' => 'dashicons-editor-help',
        'how_to' => 'dashicons-welcome-learn-more',
        'breadcrumb' => 'dashicons-menu',
        'table' => 'dashicons-editor-table',
        'service' => 'dashicons-hammer',
        'job_posting' => 'dashicons-id-alt',
        'course' => 'dashicons-welcome-learn-more',
        'event' => 'dashicons-calendar-alt',
        'local_business' => 'dashicons-location',
        'organization' => 'dashicons-building',
        'person' => 'dashicons-admin-users',
        'video' => 'dashicons-video-alt3',
        'book' => 'dashicons-book-alt',
        'software' => 'dashicons-desktop',
        'custom' => 'dashicons-media-code',
    );

    public function __construct() {
        add_action('wp_ajax_seo_fury_get_schema_preview', array($this, 'ajax_get_schema_preview'));
        add_action('wp_ajax_seo_fury_generator_to_json', array($this, 'ajax_generator_to_json'));
    }

    public function get_schema_types() {
        if ($this->schema_types_translated === null) {
            $this->schema_types_translated = array(
                'none'           => __('None', 'seo-fury'),
                'article'        => __('Article', 'seo-fury'),
                'product'        => __('Product', 'seo-fury'),
                'review'         => __('Review', 'seo-fury'),
                'recipe'         => __('Recipe', 'seo-fury'),
                'faq'            => __('FAQ Page', 'seo-fury'),
                'how_to'         => __('How To', 'seo-fury'),
                'breadcrumb'     => __('BreadcrumbList', 'seo-fury'),
                'table'          => __('Table', 'seo-fury'),
                'service'        => __('Service', 'seo-fury'),
                'job_posting'    => __('Job Posting', 'seo-fury'),
                'course'         => __('Course', 'seo-fury'),
                'event'          => __('Event', 'seo-fury'),
                'local_business' => __('Local Business', 'seo-fury'),
                'organization'   => __('Organization', 'seo-fury'),
                'person'         => __('Person', 'seo-fury'),
                'video'          => __('Video Object', 'seo-fury'),
                'book'           => __('Book', 'seo-fury'),
                'software'       => __('Software Application', 'seo-fury'),
            );
        }
        return apply_filters('seo_fury_schema_types', $this->schema_types_translated);
    }

    private function get_schema_icon_class($type, $mode = 'generator') {
        if ($mode === 'custom') {
            return $this->schema_icons['custom'];
        }
        return $this->schema_icons[$type] ?? 'dashicons-tag';
    }

    private function render_shortcode_dropdown() {
        SEO_Fury_Shortcode_Variables::render_dropdown();
    }

    public function render_schema_tab($post, $meta_data) {
        $schema_type = get_post_meta($post->ID, '_seo_fury_schema_type', true) ?: 'none';
        $schema_data = get_post_meta($post->ID, '_seo_fury_schema_data', true) ?: array();
        $schema_mode = get_post_meta($post->ID, '_seo_fury_schema_mode', true) ?: 'generator';
        $custom_schema = get_post_meta($post->ID, '_seo_fury_schema_custom', true) ?: '';

        $schema_items = get_post_meta($post->ID, '_seo_fury_schema_items', true);
        if (!is_array($schema_items)) {
            $schema_items = array();
            if (!empty($custom_schema)) {
                $schema_items[] = array(
                    'id' => uniqid('schema_', true),
                    'type' => 'custom',
                    'mode' => 'custom',
                    'data' => array(),
                    'custom' => $custom_schema,
                );
            } elseif (!empty($schema_type) && $schema_type !== 'none') {
                $schema_items[] = array(
                    'id' => uniqid('schema_', true),
                    'type' => $schema_type,
                    'mode' => 'generator',
                    'data' => $schema_data,
                    'custom' => '',
                );
            }
        }

        if (empty($schema_items)) {
            $default_schema_type = get_option('seo_fury_default_schema_' . $post->post_type, '');
            if (!empty($default_schema_type) && $default_schema_type !== 'none') {
                $pt = $post->post_type;
                $default_data = array();

                $default_author = '';
                if (!empty($post->post_author)) {
                    $author_user = get_userdata($post->post_author);
                    $default_author = $author_user ? $author_user->display_name : '';
                }

                if ($default_schema_type === 'article') {
                    $article_sub_type = get_option('seo_fury_schema_article_type_' . $pt, 'article');
                    $article_type_map = array(
                        'article' => 'Article',
                        'blog_posting' => 'BlogPosting',
                        'news_article' => 'NewsArticle',
                    );
                    $default_data['article_type'] = $article_type_map[$article_sub_type] ?? 'Article';
                    $author_source = get_option('seo_fury_schema_author_source_' . $pt, 'auto');
                    if ($author_source === 'custom') {
                        $custom_author = get_option('seo_fury_schema_author_custom_' . $pt, '');
                        if (!empty($custom_author)) {
                            $default_data['author'] = $this->apply_schema_template($custom_author, $post);
                        }
                    } else {
                        $default_data['author'] = $default_author;
                    }
                    $headline_tpl = get_option('seo_fury_schema_headline_' . $pt, '%title%');
                    if (!empty($headline_tpl)) {
                        $default_data['headline'] = $this->apply_schema_template($headline_tpl, $post);
                    }
                    $desc_tpl = get_option('seo_fury_schema_description_' . $pt, '%excerpt%');
                    if (!empty($desc_tpl)) {
                        $default_data['description'] = $this->apply_schema_template($desc_tpl, $post);
                    }
                    $default_data['publisher'] = get_bloginfo('name');
                    if (has_post_thumbnail($post->ID)) {
                        $default_data['image'] = get_the_post_thumbnail_url($post->ID, 'full');
                    }
                } else {
                    $headline_tpl = get_option('seo_fury_schema_headline_' . $pt, '%title%');
                    if (!empty($headline_tpl)) {
                        $default_data['headline'] = $this->apply_schema_template($headline_tpl, $post);
                    }
                    $desc_tpl = get_option('seo_fury_schema_description_' . $pt, '%excerpt%');
                    if (!empty($desc_tpl)) {
                        $default_data['description'] = $this->apply_schema_template($desc_tpl, $post);
                    }
                }

                $type_label = $this->get_schema_types()[$default_schema_type] ?? $default_schema_type;
                $schema_items[] = array(
                    'id' => uniqid('schema_default_', true),
                    'type' => $default_schema_type,
                    'mode' => 'generator',
                    'label' => $type_label,
                    'is_default' => true,
                    'data' => $default_data,
                    'custom' => '',
                );
            }
        }

        $schema_active = get_post_meta($post->ID, '_seo_fury_schema_active', true);
        if (empty($schema_active) && !empty($schema_items)) {
            $schema_active = $schema_items[0]['id'];
        }

        $active_item = null;
        foreach ($schema_items as $item) {
            if (isset($item['id']) && $item['id'] === $schema_active) {
                $active_item = $item;
                break;
            }
        }

        if (!$active_item && !empty($schema_items)) {
            $active_item = $schema_items[0];
            $schema_active = $active_item['id'];
        }

        if ($active_item) {
            $schema_mode = $active_item['mode'] ?? $schema_mode;
            $schema_type = $active_item['type'] ?? $schema_type;
            $schema_data = $active_item['data'] ?? $schema_data;
            $custom_schema = $active_item['custom'] ?? $custom_schema;
        }

        if ($schema_mode === 'custom') {
            $schema_type = 'none';
        }
        ?>
        <div class="seo-fury-tab-content" id="tab-schema">
            <div class="seo-fury-section seo-fury-schema-used">
                <h4><?php esc_html_e('Used Schema', 'seo-fury'); ?></h4>
                <input type="hidden" id="seo_fury_schema_items" name="seo_fury_schema_items" value="<?php echo esc_attr(wp_json_encode($schema_items)); ?>">
                <input type="hidden" id="seo_fury_schema_active" name="seo_fury_schema_active" value="<?php echo esc_attr($schema_active); ?>">
                <div class="seo-fury-schema-list">
                    <?php if (!empty($schema_items)) : ?>
                        <?php foreach ($schema_items as $item) : ?>
                            <?php
                            $item_id = $item['id'] ?? '';
                            $item_mode = $item['mode'] ?? 'generator';
                            $item_type = $item['type'] ?? 'none';
                            $item_label = ($item_mode === 'custom' || $item_mode === 'custom_builder') ? ($item['label'] ?? __('Custom JSON-LD', 'seo-fury')) : ($item['label'] ?? ($this->get_schema_types()[$item_type] ?? $item_type));
                            ?>
                            <div class="seo-fury-schema-card <?php echo esc_attr( $item_id === $schema_active ? 'is-active' : '' ); ?>" data-schema-id="<?php echo esc_attr($item_id); ?>" data-schema-mode="<?php echo esc_attr($item_mode); ?>">
                                <div class="seo-fury-schema-label">
                                    <span class="seo-fury-schema-icon dashicons <?php echo esc_attr($this->get_schema_icon_class($item_type, $item_mode)); ?>" aria-hidden="true"></span>
                                    <div class="seo-fury-schema-label-text">
                                        <span class="seo-fury-schema-badge"><?php echo esc_html($item_label); ?></span>
                                        <span class="seo-fury-schema-name seo-fury-sr-only"><?php echo esc_html($item_label); ?></span>
                                    </div>
                                </div>
                                <div class="seo-fury-schema-actions">
                                    <a href="#" class="seo-fury-icon-link seo-fury-schema-edit" data-schema-id="<?php echo esc_attr($item_id); ?>" title="<?php echo esc_attr__('Edit', 'seo-fury'); ?>" aria-label="<?php echo esc_attr__('Edit', 'seo-fury'); ?>">
                                        <span class="dashicons dashicons-edit"></span>
                                    </a>
                                    <a href="#" class="seo-fury-icon-link seo-fury-schema-preview" data-schema-id="<?php echo esc_attr($item_id); ?>" title="<?php echo esc_attr__('Preview', 'seo-fury'); ?>" aria-label="<?php echo esc_attr__('Preview', 'seo-fury'); ?>">
                                        <span class="dashicons dashicons-visibility"></span>
                                    </a>
                                    <a href="#" class="seo-fury-icon-link seo-fury-schema-remove" data-schema-id="<?php echo esc_attr($item_id); ?>" title="<?php echo esc_attr__('Remove', 'seo-fury'); ?>" aria-label="<?php echo esc_attr__('Remove', 'seo-fury'); ?>">
                                        <span class="dashicons dashicons-trash"></span>
                                    </a>
                                </div>
                            </div>
                        <?php endforeach; ?>
                    <?php else : ?>
                        <p class="description"><?php esc_html_e('No schema selected yet. Use Schema Generator to apply.', 'seo-fury'); ?></p>
                    <?php endif; ?>
                </div>

                <button type="button" class="button button-primary seo-fury-open-schema-modal"><?php esc_html_e('Schema Generator', 'seo-fury'); ?></button>
            </div>

            <?php
            $permalink = get_permalink($post->ID);
            $encoded_permalink = urlencode($permalink ?: '');
            ?>
            <div class="seo-fury-section seo-fury-schema-validators" id="seo-fury-schema-validators"
                 style="<?php echo esc_attr( ($post->post_status === 'publish' && !empty($permalink)) ? '' : 'display:none;' ); ?>">
                <h4><?php esc_html_e('Validate Markup', 'seo-fury'); ?></h4>
                <div class="seo-fury-validator-links">
                    <a href="<?php echo esc_url('https://search.google.com/test/rich-results?url=' . $encoded_permalink); ?>"
                       target="_blank" rel="noopener noreferrer" class="button seo-fury-validator-link" data-validator="google">
                        <span class="dashicons dashicons-google" aria-hidden="true"></span>
                        <?php esc_html_e('Google Rich Results', 'seo-fury'); ?>
                    </a>
                    <a href="<?php echo esc_url('https://webmaster.yandex.ru/tools/microtest/?url=' . $encoded_permalink); ?>"
                       target="_blank" rel="noopener noreferrer" class="button seo-fury-validator-link" data-validator="yandex">
                        <span class="dashicons dashicons-search" aria-hidden="true"></span>
                        <?php esc_html_e('Yandex Validator', 'seo-fury'); ?>
                    </a>
                    <a href="<?php echo esc_url('https://validator.schema.org/#url=' . $encoded_permalink); ?>"
                       target="_blank" rel="noopener noreferrer" class="button seo-fury-validator-link" data-validator="schema">
                        <span class="dashicons dashicons-editor-code" aria-hidden="true"></span>
                        <?php esc_html_e('Schema.org Validator', 'seo-fury'); ?>
                    </a>
                </div>
                <p class="description"><?php esc_html_e('Links will open in a new tab. Save and publish the post first so validators can see the markup.', 'seo-fury'); ?></p>
            </div>
        </div>

        <div id="seo-fury-schema-modal" class="seo-fury-modal" style="display: none;">
            <div class="seo-fury-modal-overlay"></div>
            <div class="seo-fury-modal-content">
                <div class="seo-fury-modal-header">
                    <h2><?php esc_html_e('Schema Generator', 'seo-fury'); ?></h2>
                    <button type="button" class="seo-fury-modal-close seo-fury-schema-modal-close">
                        <span class="dashicons dashicons-no"></span>
                    </button>
                </div>

                <div class="seo-fury-modal-body">
                    <div class="seo-fury-schema-modal-tabs">
                        <button type="button" class="seo-fury-schema-modal-tab active" data-schema-tab="templates"><?php esc_html_e('Templates', 'seo-fury'); ?></button>
                        <button type="button" class="seo-fury-schema-modal-tab" data-schema-tab="builder"><?php esc_html_e('Constructor', 'seo-fury'); ?></button>
                        <button type="button" class="seo-fury-schema-modal-tab" data-schema-tab="import"><?php esc_html_e('Import', 'seo-fury'); ?></button>
                        <button type="button" class="seo-fury-schema-modal-tab" data-schema-tab="saved"><?php esc_html_e('Saved Templates', 'seo-fury'); ?></button>
                    </div>

                    <div class="seo-fury-schema-modal-panels">
                        <div class="seo-fury-schema-modal-panel active" data-schema-panel="templates">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e('Used Schema', 'seo-fury'); ?></h4>
                                <div class="seo-fury-schema-list">
                                    <?php if (!empty($schema_items)) : ?>
                                        <?php foreach ($schema_items as $item) : ?>
                                            <?php
                                            $item_id = $item['id'] ?? '';
                                            $item_mode = $item['mode'] ?? 'generator';
                                            $item_type = $item['type'] ?? 'none';
                                            $item_label = ($item_mode === 'custom' || $item_mode === 'custom_builder') ? ($item['label'] ?? __('Custom JSON-LD', 'seo-fury')) : ($item['label'] ?? ($this->get_schema_types()[$item_type] ?? $item_type));
                                            ?>
                                            <div class="seo-fury-schema-card <?php echo esc_attr( $item_id === $schema_active ? 'is-active' : '' ); ?>" data-schema-id="<?php echo esc_attr($item_id); ?>" data-schema-mode="<?php echo esc_attr($item_mode); ?>">
                                                <div class="seo-fury-schema-label">
                                                    <span class="seo-fury-schema-icon dashicons <?php echo esc_attr($this->get_schema_icon_class($item_type, $item_mode)); ?>" aria-hidden="true"></span>
                                                    <span class="seo-fury-schema-badge"><?php echo esc_html($item_label); ?></span>
                                                    <span class="seo-fury-schema-name seo-fury-sr-only"><?php echo esc_html($item_label); ?></span>
                                                </div>
                                                <div class="seo-fury-schema-actions">
                                                    <a href="#" class="seo-fury-icon-link seo-fury-schema-edit" data-schema-id="<?php echo esc_attr($item_id); ?>" title="<?php echo esc_attr__('Edit', 'seo-fury'); ?>" aria-label="<?php echo esc_attr__('Edit', 'seo-fury'); ?>">
                                                        <span class="dashicons dashicons-edit"></span>
                                                    </a>
                                                    <a href="#" class="seo-fury-icon-link seo-fury-schema-preview" data-schema-id="<?php echo esc_attr($item_id); ?>" title="<?php echo esc_attr__('Preview', 'seo-fury'); ?>" aria-label="<?php echo esc_attr__('Preview', 'seo-fury'); ?>">
                                                        <span class="dashicons dashicons-visibility"></span>
                                                    </a>
                                                    <a href="#" class="seo-fury-icon-link seo-fury-schema-remove" data-schema-id="<?php echo esc_attr($item_id); ?>" title="<?php echo esc_attr__('Remove', 'seo-fury'); ?>" aria-label="<?php echo esc_attr__('Remove', 'seo-fury'); ?>">
                                                        <span class="dashicons dashicons-trash"></span>
                                                    </a>
                                                </div>
                                            </div>
                                        <?php endforeach; ?>
                                    <?php else : ?>
                                        <p class="description"><?php esc_html_e('No schema selected. Choose a template or import JSON-LD.', 'seo-fury'); ?></p>
                                    <?php endif; ?>
                                </div>
                            </div>

                            <div class="seo-fury-section">
                                <h4><?php esc_html_e('Available Schema Types', 'seo-fury'); ?></h4>
                                <div class="seo-fury-schema-type-grid">
                                    <?php foreach ($this->get_schema_types() as $key => $label): ?>
                                        <?php if ($key === 'none') continue; ?>
                                        <div class="seo-fury-schema-type-card <?php echo esc_attr( $schema_type === $key ? 'is-active' : '' ); ?>" data-schema-type="<?php echo esc_attr($key); ?>">
                                            <span class="seo-fury-schema-type-name"><?php echo esc_html($label); ?></span>
                                            <button type="button" class="button seo-fury-schema-apply" data-schema-type="<?php echo esc_attr($key); ?>"><?php esc_html_e('Apply', 'seo-fury'); ?></button>
                                        </div>
                                    <?php endforeach; ?>
                                </div>
                            </div>

                            <!-- Hidden Schema Settings - fields kept for JavaScript cloning -->
                            <div class="seo-fury-section" id="seo-fury-schema-settings" style="display: none;">
                                <input type="hidden" id="seo_fury_schema_mode" name="seo_fury_schema_mode" value="<?php echo esc_attr($schema_mode); ?>">
                                <select id="seo_fury_schema_type" name="seo_fury_schema_type" class="seo-fury-hidden">
                                    <?php foreach ($this->get_schema_types() as $key => $label): ?>
                                        <option value="<?php echo esc_attr($key); ?>" <?php selected($schema_type, $key); ?>>
                                            <?php echo esc_html($label); ?>
                                        </option>
                                    <?php endforeach; ?>
                                </select>

                                <div class="seo-fury-schema-fields-wrap">
                                    <?php foreach ($this->get_schema_types() as $key => $label): ?>
                                        <?php if ($key === 'none') continue; ?>
                                        <div class="seo-fury-schema-fields" data-schema-type="<?php echo esc_attr($key); ?>" style="<?php echo esc_attr( $schema_type === $key ? '' : 'display:none;' ); ?>">
                                            <?php $this->render_schema_fields($key, $schema_data, $post); ?>
                                        </div>
                                    <?php endforeach; ?>
                                </div>
                            </div>
                        </div>

                        <div class="seo-fury-schema-modal-panel" data-schema-panel="builder">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e('Custom Markup Constructor', 'seo-fury'); ?></h4>
                                <p class="description" style="margin-bottom: 12px;"><?php esc_html_e('Create your own Schema.org markup by adding properties and property groups.', 'seo-fury'); ?></p>

                                <div class="schema-builder-type-wrap">
                                    <label for="schema-builder-type"><?php esc_html_e('@type (Schema type)', 'seo-fury'); ?></label>
                                    <div class="schema-builder-type-input-wrap">
                                        <input type="text" id="schema-builder-type" class="schema-builder-type-input"
                                               placeholder="<?php echo esc_attr__('e.g. Article, Product, Person...', 'seo-fury'); ?>">
                                        <!-- Schema types dropdown is injected by schema-builder.js -->
                                    </div>
                                </div>

                                <div id="schema-builder-properties">
                                    <!-- Dynamic property rows are added via JS -->
                                </div>

                                <div class="schema-builder-actions">
                                    <button type="button" class="button schema-builder-add-prop" id="schema-builder-add-prop">
                                        <span class="dashicons dashicons-plus-alt" style="margin-top: 3px;"></span>
                                        <?php esc_html_e('Add Property', 'seo-fury'); ?>
                                    </button>
                                    <button type="button" class="button schema-builder-add-group" id="schema-builder-add-group">
                                        <span class="dashicons dashicons-screenoptions" style="margin-top: 3px;"></span>
                                        <?php esc_html_e('Add Group', 'seo-fury'); ?>
                                    </button>
                                    <button type="button" class="button button-primary schema-builder-apply" id="schema-builder-apply">
                                        <?php esc_html_e('Apply Markup', 'seo-fury'); ?>
                                    </button>
                                </div>
                            </div>

                            <div class="seo-fury-section schema-builder-preview" id="schema-builder-preview-section">
                                <h4><?php esc_html_e('JSON-LD Preview', 'seo-fury'); ?></h4>
                                <div class="schema-json-preview">
                                    <pre id="schema-builder-json-output"></pre>
                                </div>
                            </div>
                        </div>

                        <div class="seo-fury-schema-modal-panel" data-schema-panel="import">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e('Import JSON-LD', 'seo-fury'); ?></h4>
                                <div class="seo-fury-field">
                                    <label for="seo_fury_schema_custom"><?php esc_html_e('Paste JSON-LD', 'seo-fury'); ?></label>
                                    <textarea id="seo_fury_schema_custom" name="seo_fury_schema_custom" rows="8" placeholder='{"@context":"https://schema.org","@type":"Article"}'><?php echo esc_textarea($custom_schema); ?></textarea>
                                    <p class="description"><?php
                                        printf(
                                            /* translators: %s: <script> HTML tag */
                                            esc_html__('Paste valid JSON-LD without the %s tag', 'seo-fury'),
                                            '<code>&lt;script&gt;</code>'
                                        );
                                    ?></p>
                                </div>
                                <button type="button" class="button button-primary seo-fury-schema-import-apply"><?php esc_html_e('Apply JSON-LD', 'seo-fury'); ?></button>
                            </div>

                            <div class="seo-fury-section" id="schema-custom-preview-section" style="<?php echo esc_attr( $schema_mode === 'custom' ? '' : 'display:none;' ); ?>">
                                <h4><?php esc_html_e('Custom JSON-LD Preview', 'seo-fury'); ?></h4>
                                <p class="description seo-fury-schema-error" id="seo-fury-schema-error" style="display:none;"></p>
                                <div class="schema-json-preview">
                                    <pre id="schema-custom-json-output"><?php echo esc_html($this->get_custom_schema_preview($custom_schema)); ?></pre>
                                </div>
                            </div>
                        </div>

                        <!-- Saved Templates Panel -->
                        <div class="seo-fury-schema-modal-panel" data-schema-panel="saved">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e('Saved Schema Templates', 'seo-fury'); ?></h4>
                                <p class="description" style="margin-bottom: 12px;"><?php esc_html_e('Apply a previously saved schema to this page. Templates are saved from the Schema Editor.', 'seo-fury'); ?></p>
                                <div id="seo-fury-saved-templates-list">
                                    <p class="description"><?php esc_html_e('Loading...', 'seo-fury'); ?></p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="seo-fury-modal-footer">
                    <button type="button" class="button button-primary seo-fury-schema-modal-close"><?php esc_html_e('Done', 'seo-fury'); ?></button>
                </div>
            </div>
        </div>

        <!-- Schema Editor Modal -->
        <div id="seo-fury-schema-editor-modal" class="seo-fury-modal" style="display: none;">
            <div class="seo-fury-modal-overlay"></div>
            <div class="seo-fury-modal-content" style="max-width: 1000px;">
                <div class="seo-fury-modal-header">
                    <h2><?php esc_html_e('Schema Editor', 'seo-fury'); ?></h2>
                    <button type="button" class="seo-fury-modal-close schema-editor-modal-close">
                        <span class="dashicons dashicons-no"></span>
                    </button>
                </div>
                <div class="seo-fury-modal-body">
                    <div class="seo-fury-modal-tabs">
                        <button type="button" class="seo-fury-modal-tab active" data-editor-tab="editor">
                            <?php esc_html_e('Editor', 'seo-fury'); ?>
                        </button>
                        <button type="button" class="seo-fury-modal-tab" data-editor-tab="preview">
                            <?php esc_html_e('Preview', 'seo-fury'); ?>
                        </button>
                        <button type="button" class="seo-fury-modal-tab" data-editor-tab="advanced">
                            <?php esc_html_e('Расширенное редактирование', 'seo-fury'); ?>
                        </button>
                    </div>
                    <div class="seo-fury-modal-panels">
                        <div class="seo-fury-modal-panel active" data-editor-panel="editor">
                            <div id="schema-editor-fields-container"></div>
                        </div>
                        <div class="seo-fury-modal-panel" data-editor-panel="preview">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e('Resolved JSON-LD Preview', 'seo-fury'); ?></h4>
                                <div class="schema-json-preview">
                                    <pre id="schema-editor-preview-output"></pre>
                                </div>
                            </div>
                        </div>
                        <div class="seo-fury-modal-panel" data-editor-panel="advanced">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e('Конструктор разметки', 'seo-fury'); ?></h4>
                                <p class="description" style="margin-bottom: 12px;"><?php esc_html_e('Редактируйте свойства и группы свойств схемы. Изменения применяются при сохранении.', 'seo-fury'); ?></p>

                                <div class="schema-builder-type-wrap">
                                    <label for="schema-editor-builder-type"><?php esc_html_e('@type (тип схемы)', 'seo-fury'); ?></label>
                                    <div class="schema-builder-type-input-wrap" id="schema-editor-builder-type-wrap">
                                        <input type="text" id="schema-editor-builder-type" class="schema-builder-type-input"
                                               placeholder="<?php echo esc_attr__('напр. Article, Product, Person...', 'seo-fury'); ?>">
                                        <!-- Schema types dropdown is injected by JS -->
                                    </div>
                                </div>

                                <div id="schema-editor-builder-properties">
                                    <!-- Dynamic property rows are added via JS -->
                                </div>

                                <div class="schema-builder-actions">
                                    <button type="button" class="button" id="schema-editor-builder-add-prop">
                                        <span class="dashicons dashicons-plus-alt" style="margin-top: 3px;"></span>
                                        <?php esc_html_e('Добавить свойство', 'seo-fury'); ?>
                                    </button>
                                    <button type="button" class="button" id="schema-editor-builder-add-group">
                                        <span class="dashicons dashicons-screenoptions" style="margin-top: 3px;"></span>
                                        <?php esc_html_e('Добавить группу', 'seo-fury'); ?>
                                    </button>
                                </div>
                            </div>

                            <div class="seo-fury-section schema-builder-preview" id="schema-editor-builder-preview-section" style="display:none;">
                                <h4><?php esc_html_e('Предпросмотр JSON-LD', 'seo-fury'); ?></h4>
                                <div class="schema-json-preview">
                                    <pre id="schema-editor-builder-json-output"></pre>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="seo-fury-modal-footer">
                    <button type="button" class="button schema-editor-save-template" style="margin-right: auto;">
                        <span class="dashicons dashicons-saved" style="margin-top:3px;"></span>
                        <?php esc_html_e('Save as Template', 'seo-fury'); ?>
                    </button>
                    <button type="button" class="button schema-editor-cancel">
                        <?php esc_html_e('Cancel', 'seo-fury'); ?>
                    </button>
                    <button type="button" class="button button-primary schema-editor-save">
                        <?php esc_html_e('Save Changes', 'seo-fury'); ?>
                    </button>
                </div>
            </div>
        </div>
        <?php
    }

    /**
     * Render the full Schema Generator + Editor modals for the template editor admin page.
     * Shows the generator modal (without Saved Templates tab) so the user can pick a schema
     * type, edit it, use the constructor / import tabs, preview, and save as a template.
     *
     * @param array $schema_item The current template schema item.
     */
    public function render_template_generator_html( $schema_item = array() ) {
        $dummy_post                = new stdClass();
        $dummy_post->ID            = 0;
        $dummy_post->post_type     = 'post';
        $dummy_post->post_title    = '';
        $dummy_post->post_author   = 0;
        $dummy_post->post_status   = 'publish';
        $dummy_post->post_date     = '';
        $dummy_post->post_modified = '';

        $schema_type   = $schema_item['type']   ?? 'none';
        $schema_mode   = $schema_item['mode']   ?? 'generator';
        $schema_data   = $schema_item['data']   ?? array();
        $custom_schema = $schema_item['custom'] ?? '';
        ?>
        <!-- Schema Generator Modal (template editor version — no Saved Templates tab) -->
        <div id="seo-fury-schema-modal" class="seo-fury-modal" style="display: none;">
            <div class="seo-fury-modal-overlay"></div>
            <div class="seo-fury-modal-content">
                <div class="seo-fury-modal-header">
                    <h2><?php esc_html_e( 'Schema Generator', 'seo-fury' ); ?></h2>
                    <button type="button" class="seo-fury-modal-close seo-fury-schema-modal-close">
                        <span class="dashicons dashicons-no"></span>
                    </button>
                </div>

                <div class="seo-fury-modal-body">
                    <div class="seo-fury-schema-modal-tabs">
                        <button type="button" class="seo-fury-schema-modal-tab active" data-schema-tab="templates"><?php esc_html_e( 'Templates', 'seo-fury' ); ?></button>
                        <button type="button" class="seo-fury-schema-modal-tab" data-schema-tab="builder"><?php esc_html_e( 'Constructor', 'seo-fury' ); ?></button>
                        <button type="button" class="seo-fury-schema-modal-tab" data-schema-tab="import"><?php esc_html_e( 'Import', 'seo-fury' ); ?></button>
                    </div>

                    <div class="seo-fury-schema-modal-panels">
                        <!-- Templates Panel -->
                        <div class="seo-fury-schema-modal-panel active" data-schema-panel="templates">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e( 'Used Schema', 'seo-fury' ); ?></h4>
                                <div class="seo-fury-schema-list">
                                    <p class="description"><?php esc_html_e( 'No schema selected. Choose a schema type below to get started.', 'seo-fury' ); ?></p>
                                </div>
                            </div>

                            <div class="seo-fury-section">
                                <h4><?php esc_html_e( 'Available Schema Types', 'seo-fury' ); ?></h4>
                                <div class="seo-fury-schema-type-grid">
                                    <?php foreach ( $this->get_schema_types() as $key => $label ) : ?>
                                        <?php if ( $key === 'none' ) continue; ?>
                                        <div class="seo-fury-schema-type-card <?php echo esc_attr( $schema_type === $key ? 'is-active' : '' ); ?>" data-schema-type="<?php echo esc_attr( $key ); ?>">
                                            <span class="seo-fury-schema-type-name"><?php echo esc_html( $label ); ?></span>
                                            <button type="button" class="button seo-fury-schema-apply" data-schema-type="<?php echo esc_attr( $key ); ?>"><?php esc_html_e( 'Apply', 'seo-fury' ); ?></button>
                                        </div>
                                    <?php endforeach; ?>
                                </div>
                            </div>

                            <!-- Hidden Schema Settings: mode/type selectors + all schema form fields -->
                            <div class="seo-fury-section" id="seo-fury-schema-settings" style="display: none;">
                                <input type="hidden" id="seo_fury_schema_mode" name="seo_fury_schema_mode" value="<?php echo esc_attr( $schema_mode ); ?>">
                                <select id="seo_fury_schema_type" name="seo_fury_schema_type" class="seo-fury-hidden">
                                    <?php foreach ( $this->get_schema_types() as $key => $label ) : ?>
                                        <option value="<?php echo esc_attr( $key ); ?>" <?php selected( $schema_type, $key ); ?>>
                                            <?php echo esc_html( $label ); ?>
                                        </option>
                                    <?php endforeach; ?>
                                </select>

                                <div class="seo-fury-schema-fields-wrap">
                                    <?php foreach ( $this->get_schema_types() as $key => $label ) : ?>
                                        <?php if ( $key === 'none' ) continue; ?>
                                        <div class="seo-fury-schema-fields" data-schema-type="<?php echo esc_attr( $key ); ?>" style="display:none;">
                                            <?php $this->render_schema_fields( $key, array(), $dummy_post ); ?>
                                        </div>
                                    <?php endforeach; ?>
                                </div>
                            </div>
                        </div><!-- /templates panel -->

                        <!-- Constructor Panel -->
                        <div class="seo-fury-schema-modal-panel" data-schema-panel="builder">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e( 'Custom Markup Constructor', 'seo-fury' ); ?></h4>
                                <p class="description" style="margin-bottom: 12px;"><?php esc_html_e( 'Create your own Schema.org markup by adding properties and property groups.', 'seo-fury' ); ?></p>

                                <div class="schema-builder-type-wrap">
                                    <label for="schema-builder-type"><?php esc_html_e( '@type (Schema type)', 'seo-fury' ); ?></label>
                                    <div class="schema-builder-type-input-wrap">
                                        <input type="text" id="schema-builder-type" class="schema-builder-type-input"
                                               placeholder="<?php echo esc_attr__( 'e.g. Article, Product, Person...', 'seo-fury' ); ?>">
                                    </div>
                                </div>

                                <div id="schema-builder-properties"></div>

                                <div class="schema-builder-actions">
                                    <button type="button" class="button schema-builder-add-prop" id="schema-builder-add-prop">
                                        <span class="dashicons dashicons-plus-alt" style="margin-top: 3px;"></span>
                                        <?php esc_html_e( 'Add Property', 'seo-fury' ); ?>
                                    </button>
                                    <button type="button" class="button schema-builder-add-group" id="schema-builder-add-group">
                                        <span class="dashicons dashicons-screenoptions" style="margin-top: 3px;"></span>
                                        <?php esc_html_e( 'Add Group', 'seo-fury' ); ?>
                                    </button>
                                    <button type="button" class="button button-primary schema-builder-apply" id="schema-builder-apply">
                                        <?php esc_html_e( 'Apply Markup', 'seo-fury' ); ?>
                                    </button>
                                </div>
                            </div>

                            <div class="seo-fury-section schema-builder-preview" id="schema-builder-preview-section">
                                <h4><?php esc_html_e( 'JSON-LD Preview', 'seo-fury' ); ?></h4>
                                <div class="schema-json-preview">
                                    <pre id="schema-builder-json-output"></pre>
                                </div>
                            </div>
                        </div><!-- /builder panel -->

                        <!-- Import Panel -->
                        <div class="seo-fury-schema-modal-panel" data-schema-panel="import">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e( 'Import JSON-LD', 'seo-fury' ); ?></h4>
                                <div class="seo-fury-field">
                                    <label for="seo_fury_schema_custom"><?php esc_html_e( 'Paste JSON-LD', 'seo-fury' ); ?></label>
                                    <textarea id="seo_fury_schema_custom" name="seo_fury_schema_custom" rows="8" placeholder='{"@context":"https://schema.org","@type":"Article"}'><?php echo esc_textarea( $custom_schema ); ?></textarea>
                                    <p class="description"><?php
                                        printf(
                                            /* translators: %s: <script> HTML tag */
                                            esc_html__( 'Paste valid JSON-LD without the %s tag', 'seo-fury' ),
                                            '<code>&lt;script&gt;</code>'
                                        );
                                    ?></p>
                                </div>
                                <button type="button" class="button button-primary seo-fury-schema-import-apply"><?php esc_html_e( 'Apply JSON-LD', 'seo-fury' ); ?></button>
                            </div>

                            <div class="seo-fury-section" id="schema-custom-preview-section" style="<?php echo esc_attr( $schema_mode === 'custom' ? '' : 'display:none;' ); ?>">
                                <h4><?php esc_html_e( 'Custom JSON-LD Preview', 'seo-fury' ); ?></h4>
                                <p class="description seo-fury-schema-error" id="seo-fury-schema-error" style="display:none;"></p>
                                <div class="schema-json-preview">
                                    <pre id="schema-custom-json-output"><?php echo esc_html( $this->get_custom_schema_preview( $custom_schema ) ); ?></pre>
                                </div>
                            </div>
                        </div><!-- /import panel -->
                    </div><!-- /panels -->
                </div><!-- /modal-body -->

                <div class="seo-fury-modal-footer" style="gap:8px; flex-wrap:wrap;">
                    <input type="text" id="sf-tpl-name-modal-input" class="regular-text"
                           placeholder="<?php echo esc_attr__( 'Template name...', 'seo-fury' ); ?>"
                           style="flex:1; min-width:160px; margin-right:auto;">
                    <button type="button" class="button seo-fury-schema-modal-close sf-tpl-cancel-btn">
                        <?php esc_html_e( 'Cancel', 'seo-fury' ); ?>
                    </button>
                    <button type="button" class="button button-primary sf-tpl-save-btn">
                        <span class="dashicons dashicons-saved" style="margin-top:3px;"></span>
                        <?php esc_html_e( 'Save Template', 'seo-fury' ); ?>
                    </button>
                </div>
            </div><!-- /modal-content -->
        </div><!-- #seo-fury-schema-modal -->

        <!-- Schema Editor Modal (sub-modal for editing schema items) -->
        <div id="seo-fury-schema-editor-modal" class="seo-fury-modal" style="display:none;">
            <div class="seo-fury-modal-overlay"></div>
            <div class="seo-fury-modal-content" style="max-width:1000px;">
                <div class="seo-fury-modal-header">
                    <h2><?php esc_html_e( 'Schema Editor', 'seo-fury' ); ?></h2>
                    <button type="button" class="seo-fury-modal-close schema-editor-modal-close">
                        <span class="dashicons dashicons-no"></span>
                    </button>
                </div>
                <div class="seo-fury-modal-body">
                    <div class="seo-fury-modal-tabs">
                        <button type="button" class="seo-fury-modal-tab active" data-editor-tab="editor">
                            <?php esc_html_e( 'Editor', 'seo-fury' ); ?>
                        </button>
                        <button type="button" class="seo-fury-modal-tab" data-editor-tab="preview">
                            <?php esc_html_e( 'Preview', 'seo-fury' ); ?>
                        </button>
                        <button type="button" class="seo-fury-modal-tab" data-editor-tab="advanced">
                            <?php esc_html_e( 'Расширенное редактирование', 'seo-fury' ); ?>
                        </button>
                    </div>
                    <div class="seo-fury-modal-panels">
                        <div class="seo-fury-modal-panel active" data-editor-panel="editor">
                            <div id="schema-editor-fields-container"></div>
                        </div>
                        <div class="seo-fury-modal-panel" data-editor-panel="preview">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e( 'Resolved JSON-LD Preview', 'seo-fury' ); ?></h4>
                                <div class="schema-json-preview">
                                    <pre id="schema-editor-preview-output"></pre>
                                </div>
                            </div>
                        </div>
                        <div class="seo-fury-modal-panel" data-editor-panel="advanced">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e( 'Конструктор разметки', 'seo-fury' ); ?></h4>
                                <p class="description" style="margin-bottom:12px;"><?php esc_html_e( 'Редактируйте свойства и группы свойств схемы. Изменения применяются при сохранении.', 'seo-fury' ); ?></p>
                                <div class="schema-builder-type-wrap">
                                    <label for="schema-editor-builder-type"><?php esc_html_e( '@type (тип схемы)', 'seo-fury' ); ?></label>
                                    <div class="schema-builder-type-input-wrap" id="schema-editor-builder-type-wrap">
                                        <input type="text" id="schema-editor-builder-type" class="schema-builder-type-input"
                                               placeholder="<?php echo esc_attr__( 'e.g. Article, Product, Person...', 'seo-fury' ); ?>">
                                    </div>
                                </div>
                                <div id="schema-editor-builder-properties"></div>
                                <div class="schema-builder-actions">
                                    <button type="button" class="button" id="schema-editor-builder-add-prop">
                                        <span class="dashicons dashicons-plus-alt" style="margin-top:3px;"></span>
                                        <?php esc_html_e( 'Add Property', 'seo-fury' ); ?>
                                    </button>
                                    <button type="button" class="button" id="schema-editor-builder-add-group">
                                        <span class="dashicons dashicons-screenoptions" style="margin-top:3px;"></span>
                                        <?php esc_html_e( 'Add Group', 'seo-fury' ); ?>
                                    </button>
                                </div>
                            </div>
                            <div class="seo-fury-section schema-builder-preview" id="schema-editor-builder-preview-section" style="display:none;">
                                <h4><?php esc_html_e( 'JSON-LD Preview', 'seo-fury' ); ?></h4>
                                <div class="schema-json-preview">
                                    <pre id="schema-editor-builder-json-output"></pre>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="seo-fury-modal-footer">
                    <button type="button" class="button schema-editor-cancel">
                        <?php esc_html_e( 'Cancel', 'seo-fury' ); ?>
                    </button>
                    <button type="button" class="button button-primary schema-editor-save">
                        <?php esc_html_e( 'Save Changes', 'seo-fury' ); ?>
                    </button>
                </div>
            </div>
        </div><!-- #seo-fury-schema-editor-modal -->
        <?php
    }

    /**
     * Render the schema editor modal HTML + hidden schema type fields.
     * Used by the Schema Template editor admin page.
     */
    public function render_editor_modal_html() {
        $dummy_post = new stdClass();
        $dummy_post->ID          = 0;
        $dummy_post->post_type   = 'post';
        $dummy_post->post_title  = '';
        $dummy_post->post_author = 0;
        $dummy_post->post_status = 'publish';
        $dummy_post->post_date   = '';
        $dummy_post->post_modified = '';
        ?>
        <div class="seo-fury-schema-fields-wrap" style="display:none;" aria-hidden="true">
            <?php foreach ( $this->get_schema_types() as $key => $label ) : ?>
                <?php if ( $key === 'none' ) continue; ?>
                <div class="seo-fury-schema-fields" data-schema-type="<?php echo esc_attr( $key ); ?>" style="display:none;">
                    <?php $this->render_schema_fields( $key, array(), $dummy_post ); ?>
                </div>
            <?php endforeach; ?>
        </div>

        <div id="seo-fury-schema-editor-modal" class="seo-fury-modal" style="display:none;">
            <div class="seo-fury-modal-overlay"></div>
            <div class="seo-fury-modal-content" style="max-width:1000px;">
                <div class="seo-fury-modal-header">
                    <h2><?php esc_html_e( 'Schema Editor', 'seo-fury' ); ?></h2>
                    <button type="button" class="seo-fury-modal-close schema-editor-modal-close">
                        <span class="dashicons dashicons-no"></span>
                    </button>
                </div>
                <div class="seo-fury-modal-body">
                    <div class="seo-fury-modal-tabs">
                        <button type="button" class="seo-fury-modal-tab active" data-editor-tab="editor">
                            <?php esc_html_e( 'Editor', 'seo-fury' ); ?>
                        </button>
                        <button type="button" class="seo-fury-modal-tab" data-editor-tab="preview">
                            <?php esc_html_e( 'Preview', 'seo-fury' ); ?>
                        </button>
                        <button type="button" class="seo-fury-modal-tab" data-editor-tab="advanced">
                            <?php esc_html_e( 'Расширенное редактирование', 'seo-fury' ); ?>
                        </button>
                    </div>
                    <div class="seo-fury-modal-panels">
                        <div class="seo-fury-modal-panel active" data-editor-panel="editor">
                            <div id="schema-editor-fields-container"></div>
                        </div>
                        <div class="seo-fury-modal-panel" data-editor-panel="preview">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e( 'Resolved JSON-LD Preview', 'seo-fury' ); ?></h4>
                                <div class="schema-json-preview">
                                    <pre id="schema-editor-preview-output"></pre>
                                </div>
                            </div>
                        </div>
                        <div class="seo-fury-modal-panel" data-editor-panel="advanced">
                            <div class="seo-fury-section">
                                <h4><?php esc_html_e( 'Конструктор разметки', 'seo-fury' ); ?></h4>
                                <p class="description" style="margin-bottom:12px;"><?php esc_html_e( 'Редактируйте свойства и группы свойств схемы. Изменения применяются при сохранении.', 'seo-fury' ); ?></p>
                                <div class="schema-builder-type-wrap">
                                    <label for="schema-editor-builder-type"><?php esc_html_e( '@type (тип схемы)', 'seo-fury' ); ?></label>
                                    <div class="schema-builder-type-input-wrap" id="schema-editor-builder-type-wrap">
                                        <input type="text" id="schema-editor-builder-type" class="schema-builder-type-input"
                                               placeholder="<?php echo esc_attr__( 'напр. Article, Product, Person...', 'seo-fury' ); ?>">
                                    </div>
                                </div>
                                <div id="schema-editor-builder-properties"></div>
                                <div class="schema-builder-actions">
                                    <button type="button" class="button" id="schema-editor-builder-add-prop">
                                        <span class="dashicons dashicons-plus-alt" style="margin-top:3px;"></span>
                                        <?php esc_html_e( 'Добавить свойство', 'seo-fury' ); ?>
                                    </button>
                                    <button type="button" class="button" id="schema-editor-builder-add-group">
                                        <span class="dashicons dashicons-screenoptions" style="margin-top:3px;"></span>
                                        <?php esc_html_e( 'Добавить группу', 'seo-fury' ); ?>
                                    </button>
                                </div>
                            </div>
                            <div class="seo-fury-section schema-builder-preview" id="schema-editor-builder-preview-section" style="display:none;">
                                <h4><?php esc_html_e( 'Предпросмотр JSON-LD', 'seo-fury' ); ?></h4>
                                <div class="schema-json-preview">
                                    <pre id="schema-editor-builder-json-output"></pre>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="seo-fury-modal-footer">
                    <button type="button" class="button schema-editor-cancel">
                        <?php esc_html_e( 'Cancel', 'seo-fury' ); ?>
                    </button>
                    <button type="button" class="button button-primary schema-editor-save">
                        <?php esc_html_e( 'Save Changes', 'seo-fury' ); ?>
                    </button>
                </div>
            </div>
        </div>
        <?php
    }

    private function render_schema_fields($schema_type, $schema_data, $post) {
        if ($schema_type === 'none') {
            return;
        }

        echo '<div id="schema-fields-container">';

        switch ($schema_type) {
            case 'article':
                $this->render_article_fields($schema_data, $post);
                break;

            case 'product':
                $this->render_product_fields($schema_data, $post);
                break;

            case 'review':
                $this->render_review_fields($schema_data, $post);
                break;

            case 'recipe':
                $this->render_recipe_fields($schema_data, $post);
                break;

            case 'faq':
                $this->render_faq_fields($schema_data, $post);
                break;

            case 'how_to':
                $this->render_howto_fields($schema_data, $post);
                break;

            case 'event':
                $this->render_event_fields($schema_data, $post);
                break;

            case 'video':
                $this->render_video_fields($schema_data, $post);
                break;

            case 'breadcrumb':
                $this->render_breadcrumb_fields($schema_data, $post);
                break;

            case 'table':
                $this->render_table_fields($schema_data, $post);
                break;

            case 'service':
                $this->render_service_fields($schema_data, $post);
                break;

            case 'job_posting':
                $this->render_jobposting_fields($schema_data, $post);
                break;

            case 'person':
                $this->render_person_fields($schema_data, $post);
                break;

            case 'organization':
                $this->render_organization_fields($schema_data, $post);
                break;

            case 'course':
                $this->render_course_fields($schema_data, $post);
                break;

            case 'book':
                $this->render_book_fields($schema_data, $post);
                break;

            case 'software':
                $this->render_software_fields($schema_data, $post);
                break;

            case 'local_business':
                $this->render_localbusiness_fields($schema_data, $post);
                break;

            default:
                echo '<div class="seo-fury-section">';
                echo '<p class="description">' . esc_html__('Schema fields for this type will be available soon. You can manually add schema using the JSON-LD editor above.', 'seo-fury') . '</p>';
                echo '</div>';
                break;
        }

        echo '</div>';
    }

    private function render_schema_id_field($data, $default_fragment) {
        $placeholder = '%url%' . $default_fragment;
        ?>
        <div class="seo-fury-field" style="grid-column: span 2">
            <label>@id</label>
            <div class="input-with-dropdown">
                <input type="text" name="schema_data[id]"
                       value="<?php echo esc_attr($data['id'] ?? ''); ?>"
                       placeholder="<?php echo esc_attr($placeholder); ?>">
                <?php $this->render_shortcode_dropdown(); ?>
            </div>
            <p class="description"><?php esc_html_e('Schema @id URI. Leave empty to use default:', 'seo-fury'); ?> <code><?php echo esc_html($placeholder); ?></code></p>
        </div>
        <?php
    }

    private function render_article_fields($data, $post) {
        $default_author = '';
        if (!empty($post->post_author)) {
            $author_user = get_userdata($post->post_author);
            $default_author = $author_user ? $author_user->display_name : '';
        }
        $default_date_pub = (!empty($post->post_date) && $post->post_date !== '0000-00-00 00:00:00') ? wp_date('Y-m-d\TH:i', strtotime($post->post_date)) : '';
        $default_date_mod = (!empty($post->post_modified) && $post->post_modified !== '0000-00-00 00:00:00') ? wp_date('Y-m-d\TH:i', strtotime($post->post_modified)) : '';
        $article_type = $data['article_type'] ?? 'Article';
        $publisher_type = $data['publisher_type'] ?? 'Organization';
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Article Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#article'); ?>
                <div class="seo-fury-field">
                    <label for="schema_article_type"><?php esc_html_e('Article Type', 'seo-fury'); ?></label>
                    <select id="schema_article_type" name="schema_data[article_type]">
                        <option value="Article" <?php selected($article_type, 'Article'); ?>>Article</option>
                        <option value="BlogPosting" <?php selected($article_type, 'BlogPosting'); ?>>BlogPosting</option>
                        <option value="NewsArticle" <?php selected($article_type, 'NewsArticle'); ?>>NewsArticle</option>
                    </select>
                    <p class="description"><?php esc_html_e('Schema.org article type (@type)', 'seo-fury'); ?></p>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_headline"><?php esc_html_e('Headline', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_headline" name="schema_data[headline]"
                               value="<?php echo esc_attr($data['headline'] ?? '%seo_title%'); ?>"
                               placeholder="<?php echo esc_attr($post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                    <p class="description"><?php /* translators: %seo_title% is a shortcode variable, not a placeholder */ esc_html_e('Article headline (defaults to %seo_title%)', 'seo-fury'); ?></p>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_description"><?php esc_html_e('Description', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_description" name="schema_data[description]"
                               value="<?php echo esc_attr($data['description'] ?? '%seo_description%'); ?>"
                               placeholder="%seo_description%">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                    <p class="description"><?php /* translators: %seo_description% is a shortcode variable, not a placeholder */ esc_html_e('Article description (defaults to %seo_description%)', 'seo-fury'); ?></p>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_keywords"><?php esc_html_e('Keywords', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_keywords" name="schema_data[keywords]"
                               value="<?php echo esc_attr($data['keywords'] ?? '%keywords%'); ?>"
                               placeholder="%keywords%">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                    <p class="description"><?php esc_html_e('Article keywords (defaults to %keywords%)', 'seo-fury'); ?></p>
                </div>

                <div class="sf-subgroup-header">
                    <span class="sf-subgroup-title"><?php esc_html_e('Author', 'seo-fury'); ?></span>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_author_type"><?php esc_html_e('Author Type', 'seo-fury'); ?></label>
                    <select id="schema_author_type" name="schema_data[author_type]">
                        <option value="Person" <?php selected($data['author_type'] ?? 'Person', 'Person'); ?>>Person</option>
                        <option value="Organization" <?php selected($data['author_type'] ?? 'Person', 'Organization'); ?>>Organization</option>
                    </select>
                    <p class="description"><?php esc_html_e('Author type (Person or Organization)', 'seo-fury'); ?></p>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_author"><?php esc_html_e('Author Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_author" name="schema_data[author]"
                               value="<?php echo esc_attr($data['author'] ?? '%name%'); ?>"
                               placeholder="%name%">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                    <p class="description"><?php esc_html_e('Author of the article (defaults to %name%)', 'seo-fury'); ?></p>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_author_url"><?php esc_html_e('Author URL', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_author_url" name="schema_data[author_url]"
                               value="<?php echo esc_attr($data['author_url'] ?? ''); ?>"
                               placeholder="https://example.com/author">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                    <p class="description"><?php esc_html_e('Author profile URL', 'seo-fury'); ?></p>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_author_id"><?php esc_html_e('Author @id', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_author_id" name="schema_data[author_id]"
                               value="<?php echo esc_attr($data['author_id'] ?? ''); ?>"
                               placeholder="https://example.com/#author">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                    <p class="description"><?php esc_html_e('Author @id URI for linked data', 'seo-fury'); ?></p>
                </div>

                <!-- Author: sameAs -->
                <div class="seo-fury-field sf-opt-item" style="grid-column: span 2">
                    <div class="sf-opt-header">
                        <button type="button" class="sf-opt-toggle-btn<?php echo esc_attr( !empty($data['author_same_as']) ? ' active' : '' ); ?>">
                            <span class="sf-opt-arrow"></span>
                            <code>sameAs</code>
                        </button>
                        <p class="description"><?php esc_html_e('Links to profiles or official pages of the author in other sources. Helps search engines match the author with external profiles. Strengthens entity identification. Useful for E-E-A-T.', 'seo-fury'); ?></p>
                    </div>
                    <div class="sf-opt-body"<?php echo esc_attr( empty($data['author_same_as']) ? ' style="display:none"' : '' ); ?>>
                        <div class="sf-array-list">
                            <?php foreach (($data['author_same_as'] ?? []) as $val): ?>
                            <div class="sf-array-row">
                                <input type="text" name="schema_data[author_same_as][]" value="<?php echo esc_attr($val); ?>" placeholder="https://...">
                                <button type="button" class="sf-array-remove-btn" title="<?php esc_attr_e('Remove', 'seo-fury'); ?>">&#x2715;</button>
                            </div>
                            <?php endforeach; ?>
                        </div>
                        <button type="button" class="sf-array-add-btn" data-field-name="schema_data[author_same_as][]" data-placeholder="https://..."><?php esc_html_e('+ Add URL', 'seo-fury'); ?></button>
                    </div>
                </div>

                <!-- Author: knowsAbout -->
                <div class="seo-fury-field sf-opt-item" style="grid-column: span 2">
                    <div class="sf-opt-header">
                        <button type="button" class="sf-opt-toggle-btn<?php echo esc_attr( !empty($data['author_knows_about']) ? ' active' : '' ); ?>">
                            <span class="sf-opt-arrow"></span>
                            <code>knowsAbout</code>
                        </button>
                        <p class="description"><?php esc_html_e('Specifies areas of knowledge of the person. Semantically links the author to topics. Can strengthen topical authority. Useful for expert content.', 'seo-fury'); ?></p>
                    </div>
                    <div class="sf-opt-body"<?php echo esc_attr( empty($data['author_knows_about']) ? ' style="display:none"' : '' ); ?>>
                        <div class="sf-array-list">
                            <?php foreach (($data['author_knows_about'] ?? []) as $val): ?>
                            <div class="sf-array-row">
                                <input type="text" name="schema_data[author_knows_about][]" value="<?php echo esc_attr($val); ?>" placeholder="<?php esc_attr_e('e.g. Machine Learning', 'seo-fury'); ?>">
                                <button type="button" class="sf-array-remove-btn" title="<?php esc_attr_e('Remove', 'seo-fury'); ?>">&#x2715;</button>
                            </div>
                            <?php endforeach; ?>
                        </div>
                        <button type="button" class="sf-array-add-btn" data-field-name="schema_data[author_knows_about][]" data-placeholder="<?php esc_attr_e('e.g. Machine Learning', 'seo-fury'); ?>"><?php esc_html_e('+ Add Topic', 'seo-fury'); ?></button>
                    </div>
                </div>

                <!-- Author: alumniOf -->
                <div class="seo-fury-field sf-opt-item" style="grid-column: span 2">
                    <div class="sf-opt-header">
                        <button type="button" class="sf-opt-toggle-btn<?php echo esc_attr( !empty($data['author_alumni_of_name']) ? ' active' : '' ); ?>">
                            <span class="sf-opt-arrow"></span>
                            <code>alumniOf</code>
                        </button>
                        <p class="description"><?php esc_html_e('Educational institution the author graduated from. Only add if education is relevant to the article topic and it\'s a real degree.', 'seo-fury'); ?></p>
                    </div>
                    <div class="sf-opt-body"<?php echo esc_attr( empty($data['author_alumni_of_name']) ? ' style="display:none"' : '' ); ?>>
                        <div class="sf-opt-body-grid">
                            <div class="seo-fury-field">
                                <label for="schema_author_alumni_of_type"><?php esc_html_e('@type', 'seo-fury'); ?></label>
                                <?php $alumni_of_type = $data['author_alumni_of_type'] ?? 'EducationalOrganization'; ?>
                                <select id="schema_author_alumni_of_type" name="schema_data[author_alumni_of_type]">
                                    <option value="EducationalOrganization" <?php selected($alumni_of_type, 'EducationalOrganization'); ?>>EducationalOrganization</option>
                                    <option value="CollegeOrUniversity" <?php selected($alumni_of_type, 'CollegeOrUniversity'); ?>>CollegeOrUniversity</option>
                                    <option value="HighSchool" <?php selected($alumni_of_type, 'HighSchool'); ?>>HighSchool</option>
                                    <option value="ElementarySchool" <?php selected($alumni_of_type, 'ElementarySchool'); ?>>ElementarySchool</option>
                                    <option value="MiddleSchool" <?php selected($alumni_of_type, 'MiddleSchool'); ?>>MiddleSchool</option>
                                    <option value="School" <?php selected($alumni_of_type, 'School'); ?>>School</option>
                                </select>
                            </div>
                            <div class="seo-fury-field">
                                <label for="schema_author_alumni_of_name"><?php esc_html_e('name', 'seo-fury'); ?></label>
                                <input type="text" id="schema_author_alumni_of_name" name="schema_data[author_alumni_of_name]"
                                       value="<?php echo esc_attr($data['author_alumni_of_name'] ?? ''); ?>"
                                       placeholder="MIT">
                            </div>
                        </div>
                    </div>
                </div>

                <!-- Author: hasCredential -->
                <div class="seo-fury-field sf-opt-item" style="grid-column: span 2">
                    <div class="sf-opt-header">
                        <button type="button" class="sf-opt-toggle-btn<?php echo esc_attr( !empty($data['author_credential_name']) ? ' active' : '' ); ?>">
                            <span class="sf-opt-arrow"></span>
                            <code>hasCredential</code>
                        </button>
                        <p class="description"><?php esc_html_e('Indicates professional certificates or licenses. Strengthens expertise. Especially relevant for medicine, finance, construction, and legal fields.', 'seo-fury'); ?></p>
                    </div>
                    <div class="sf-opt-body"<?php echo esc_attr( empty($data['author_credential_name']) ? ' style="display:none"' : '' ); ?>>
                        <div class="sf-opt-fixed-fields">
                            <div class="sf-opt-fixed-field"><code>@type</code>: <span>EducationalOccupationalCredential</span></div>
                            <div class="sf-opt-fixed-field"><code>credentialCategory</code>: <span>Professional License</span></div>
                        </div>
                        <div class="seo-fury-field">
                            <label for="schema_author_credential_name"><?php esc_html_e('name', 'seo-fury'); ?></label>
                            <input type="text" id="schema_author_credential_name" name="schema_data[author_credential_name]"
                                   value="<?php echo esc_attr($data['author_credential_name'] ?? ''); ?>"
                                   placeholder="<?php esc_attr_e('e.g. Certified Financial Planner', 'seo-fury'); ?>">
                        </div>
                    </div>
                </div>

                <div class="sf-subgroup-header">
                    <span class="sf-subgroup-title"><?php esc_html_e('Publisher', 'seo-fury'); ?></span>
                </div>

                <?php $use_org = !isset($data['publisher_use_org']) || (bool)$data['publisher_use_org']; ?>
                <div class="seo-fury-field" style="grid-column: span 2">
                    <input type="hidden" name="schema_data[publisher_use_org]" value="0">
                    <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:600;">
                        <input type="checkbox" id="schema_publisher_use_org" name="schema_data[publisher_use_org]" value="1" <?php checked($use_org); ?>>
                        <?php esc_html_e('Use Organization markup from homepage', 'seo-fury'); ?>
                    </label>
                    <p class="description"><?php esc_html_e('When enabled, publisher will reference your site\'s Organization entity by @id. Disable to configure publisher details manually.', 'seo-fury'); ?></p>
                    <div class="sf-publisher-org-preview" <?php echo esc_attr( !$use_org ? 'style="display:none"' : '' ); ?>>
                        <code class="sf-schema-ref-preview">"publisher": { "@id": "<?php echo esc_html(home_url('/#organization')); ?>" }</code>
                    </div>
                </div>

                <!-- Manual Publisher Fields (hidden when use_org is enabled) -->
                <div id="sf-publisher-manual-fields" class="seo-fury-field" style="grid-column: span 2; padding: 0;<?php echo esc_attr( $use_org ? ' display:none' : '' ); ?>">
                    <div class="seo-fury-fields-grid" style="margin: 0;">
                        <div class="seo-fury-field">
                            <label for="schema_publisher_type"><?php esc_html_e('Publisher Type', 'seo-fury'); ?></label>
                            <select id="schema_publisher_type" name="schema_data[publisher_type]">
                                <option value="Organization" <?php selected($publisher_type, 'Organization'); ?>>Organization</option>
                                <option value="Person" <?php selected($publisher_type, 'Person'); ?>>Person</option>
                            </select>
                            <p class="description"><?php esc_html_e('Publisher type (Organization or Person)', 'seo-fury'); ?></p>
                        </div>

                        <div class="seo-fury-field">
                            <label for="schema_publisher"><?php esc_html_e('Publisher Name', 'seo-fury'); ?></label>
                            <div class="input-with-dropdown">
                                <input type="text" id="schema_publisher" name="schema_data[publisher]"
                                       value="<?php echo esc_attr($data['publisher'] ?? '%org_name%'); ?>"
                                       placeholder="%org_name%">
                                <?php $this->render_shortcode_dropdown(); ?>
                            </div>
                            <p class="description"><?php /* translators: %org_name% is a shortcode variable, not a placeholder */ esc_html_e('Publisher name (defaults to %org_name%)', 'seo-fury'); ?></p>
                        </div>

                        <div class="seo-fury-field">
                            <label for="schema_publisher_logo"><?php esc_html_e('Publisher Logo URL', 'seo-fury'); ?></label>
                            <div class="input-with-dropdown">
                                <input type="url" id="schema_publisher_logo" name="schema_data[publisher_logo]"
                                       value="<?php echo esc_url($data['publisher_logo'] ?? ''); ?>"
                                       placeholder="https://example.com/logo.png">
                                <?php $this->render_shortcode_dropdown(); ?>
                            </div>
                            <p class="description"><?php esc_html_e('URL of publisher\'s logo (recommended: 600x60px)', 'seo-fury'); ?></p>
                        </div>

                        <!-- Publisher: sameAs -->
                        <div class="seo-fury-field sf-opt-item" style="grid-column: span 2">
                            <div class="sf-opt-header">
                                <button type="button" class="sf-opt-toggle-btn<?php echo esc_attr( !empty($data['publisher_same_as']) ? ' active' : '' ); ?>">
                                    <span class="sf-opt-arrow"></span>
                                    <code>sameAs</code>
                                </button>
                                <p class="description"><?php esc_html_e('Links to profiles or official pages of the publisher in other sources.', 'seo-fury'); ?></p>
                            </div>
                            <div class="sf-opt-body"<?php echo esc_attr( empty($data['publisher_same_as']) ? ' style="display:none"' : '' ); ?>>
                                <div class="sf-array-list">
                                    <?php foreach (($data['publisher_same_as'] ?? []) as $val): ?>
                                    <div class="sf-array-row">
                                        <input type="text" name="schema_data[publisher_same_as][]" value="<?php echo esc_attr($val); ?>" placeholder="https://...">
                                        <button type="button" class="sf-array-remove-btn" title="<?php esc_attr_e('Remove', 'seo-fury'); ?>">&#x2715;</button>
                                    </div>
                                    <?php endforeach; ?>
                                </div>
                                <button type="button" class="sf-array-add-btn" data-field-name="schema_data[publisher_same_as][]" data-placeholder="https://..."><?php esc_html_e('+ Add URL', 'seo-fury'); ?></button>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="seo-fury-field" style="grid-column: span 2">
                    <label for="schema_image"><?php esc_html_e('Featured Image URL', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="url" id="schema_image" name="schema_data[image]"
                               value="<?php echo esc_url($data['image'] ?? get_the_post_thumbnail_url($post->ID, 'full')); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                    <p class="description"><?php esc_html_e('Main image for the article (ImageObject)', 'seo-fury'); ?></p>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_image_width"><?php esc_html_e('Image Width (px)', 'seo-fury'); ?></label>
                    <input type="number" id="schema_image_width" name="schema_data[image_width]"
                           value="<?php echo esc_attr($data['image_width'] ?? ''); ?>" placeholder="1200">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_image_height"><?php esc_html_e('Image Height (px)', 'seo-fury'); ?></label>
                    <input type="number" id="schema_image_height" name="schema_data[image_height]"
                           value="<?php echo esc_attr($data['image_height'] ?? ''); ?>" placeholder="630">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_in_language"><?php esc_html_e('Language (inLanguage)', 'seo-fury'); ?></label>
                    <input type="text" id="schema_in_language" name="schema_data[in_language]"
                           value="<?php echo esc_attr($data['in_language'] ?? ''); ?>" placeholder="ru-RU">
                    <p class="description"><?php esc_html_e('e.g. ru-RU, en-US', 'seo-fury'); ?></p>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_date_published"><?php esc_html_e('Date Published', 'seo-fury'); ?></label>
                    <?php $has_custom_pub = isset($data['date_published']) && $data['date_published'] !== ''; ?>
                    <div class="sf-schema-date-field" data-wp-date="<?php echo esc_attr($default_date_pub); ?>">
                        <div class="sf-date-auto-row"<?php echo esc_attr( $has_custom_pub ? ' style="display:none"' : '' ); ?>>
                            <span class="sf-date-wp-value"><?php echo esc_html($default_date_pub ?: __('Not set', 'seo-fury')); ?></span>
                            <span class="sf-date-wp-label"><?php esc_html_e('(from WordPress)', 'seo-fury'); ?></span>
                            <br>
                            <a href="#" class="sf-schema-date-custom-btn"><?php esc_html_e('Set custom date', 'seo-fury'); ?></a>
                        </div>
                        <div class="sf-date-custom-row"<?php echo esc_attr( !$has_custom_pub ? ' style="display:none"' : '' ); ?>>
                            <input type="datetime-local" id="schema_date_published" name="schema_data[date_published]"
                                   value="<?php echo esc_attr($data['date_published'] ?? ''); ?>">
                            <br>
                            <a href="#" class="sf-schema-date-wp-btn"><?php esc_html_e('↺ Use WordPress date', 'seo-fury'); ?></a>
                        </div>
                    </div>
                    <p class="description"><?php esc_html_e('When was this article published?', 'seo-fury'); ?></p>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_date_modified"><?php esc_html_e('Date Modified', 'seo-fury'); ?></label>
                    <?php $has_custom_mod = isset($data['date_modified']) && $data['date_modified'] !== ''; ?>
                    <div class="sf-schema-date-field" data-wp-date="<?php echo esc_attr($default_date_mod); ?>">
                        <div class="sf-date-auto-row"<?php echo esc_attr( $has_custom_mod ? ' style="display:none"' : '' ); ?>>
                            <span class="sf-date-wp-value"><?php echo esc_html($default_date_mod ?: __('Not set', 'seo-fury')); ?></span>
                            <span class="sf-date-wp-label"><?php esc_html_e('(from WordPress)', 'seo-fury'); ?></span>
                            <br>
                            <a href="#" class="sf-schema-date-custom-btn"><?php esc_html_e('Set custom date', 'seo-fury'); ?></a>
                        </div>
                        <div class="sf-date-custom-row"<?php echo esc_attr( !$has_custom_mod ? ' style="display:none"' : '' ); ?>>
                            <input type="datetime-local" id="schema_date_modified" name="schema_data[date_modified]"
                                   value="<?php echo esc_attr($data['date_modified'] ?? ''); ?>">
                            <br>
                            <a href="#" class="sf-schema-date-wp-btn"><?php esc_html_e('↺ Use WordPress date', 'seo-fury'); ?></a>
                        </div>
                    </div>
                    <p class="description"><?php esc_html_e('Last modification date', 'seo-fury'); ?></p>
                </div>
            </div>
        </div>
        <?php
    }

    private function render_product_fields($data, $post) {
        $prod_use_org = !isset($data['seller_use_org']) || (bool) $data['seller_use_org'];
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Product Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#product'); ?>

                <div class="seo-fury-field" style="grid-column: span 2">
                    <label for="schema_product_name"><?php esc_html_e('Product Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_product_name" name="schema_data[name]"
                               value="<?php echo esc_attr($data['name'] ?? $post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field" style="grid-column: span 2">
                    <label for="schema_product_description"><?php esc_html_e('Description', 'seo-fury'); ?></label>
                    <textarea id="schema_product_description" name="schema_data[description]"
                              rows="3"><?php echo esc_textarea($data['description'] ?? ''); ?></textarea>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_product_brand"><?php esc_html_e('Brand', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_product_brand" name="schema_data[brand]"
                               value="<?php echo esc_attr($data['brand'] ?? ''); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_product_sku"><?php esc_html_e('SKU', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_product_sku" name="schema_data[sku]"
                               value="<?php echo esc_attr($data['sku'] ?? ''); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_product_mpn"><?php esc_html_e('MPN (Manufacturer Part Number)', 'seo-fury'); ?></label>
                    <input type="text" id="schema_product_mpn" name="schema_data[mpn]"
                           value="<?php echo esc_attr($data['mpn'] ?? ''); ?>">
                </div>

                <!-- Images -->
                <div class="seo-fury-field sf-opt-item" style="grid-column: span 2">
                    <div class="sf-opt-header">
                        <button type="button" class="sf-opt-toggle-btn<?php echo esc_attr( !empty($data['images']) ? ' active' : '' ); ?>">
                            <span class="sf-opt-arrow"></span>
                            <code>image</code>
                        </button>
                        <p class="description"><?php esc_html_e('Product images (one URL per row)', 'seo-fury'); ?></p>
                    </div>
                    <div class="sf-opt-body"<?php echo esc_attr( empty($data['images']) ? ' style="display:none"' : '' ); ?>>
                        <div class="sf-array-list">
                            <?php foreach (($data['images'] ?? []) as $img_url): ?>
                            <div class="sf-array-row">
                                <input type="url" name="schema_data[images][]" value="<?php echo esc_url($img_url); ?>" placeholder="https://...">
                                <button type="button" class="sf-array-remove-btn" title="<?php esc_attr_e('Remove', 'seo-fury'); ?>">&#x2715;</button>
                            </div>
                            <?php endforeach; ?>
                        </div>
                        <button type="button" class="sf-array-add-btn" data-field-name="schema_data[images][]" data-placeholder="https://..."><?php esc_html_e('+ Add Image URL', 'seo-fury'); ?></button>
                    </div>
                </div>

                <div class="sf-subgroup-header" style="grid-column: span 2">
                    <span class="sf-subgroup-title"><?php esc_html_e('Offer', 'seo-fury'); ?></span>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_product_price"><?php esc_html_e('Price', 'seo-fury'); ?></label>
                    <input type="number" step="0.01" id="schema_product_price" name="schema_data[price]"
                           value="<?php echo esc_attr($data['price'] ?? ''); ?>" placeholder="99.99">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_product_currency"><?php esc_html_e('Currency', 'seo-fury'); ?></label>
                    <input type="text" id="schema_product_currency" name="schema_data[currency]"
                           value="<?php echo esc_attr($data['currency'] ?? 'USD'); ?>" placeholder="USD">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_product_price_valid_until"><?php esc_html_e('Price Valid Until', 'seo-fury'); ?></label>
                    <input type="date" id="schema_product_price_valid_until" name="schema_data[price_valid_until]"
                           value="<?php echo esc_attr($data['price_valid_until'] ?? ''); ?>">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_product_availability"><?php esc_html_e('Availability', 'seo-fury'); ?></label>
                    <select id="schema_product_availability" name="schema_data[availability]">
                        <option value="InStock" <?php selected($data['availability'] ?? 'InStock', 'InStock'); ?>><?php esc_html_e('In Stock', 'seo-fury'); ?></option>
                        <option value="OutOfStock" <?php selected($data['availability'] ?? '', 'OutOfStock'); ?>><?php esc_html_e('Out of Stock', 'seo-fury'); ?></option>
                        <option value="PreOrder" <?php selected($data['availability'] ?? '', 'PreOrder'); ?>><?php esc_html_e('Pre Order', 'seo-fury'); ?></option>
                        <option value="BackOrder" <?php selected($data['availability'] ?? '', 'BackOrder'); ?>><?php esc_html_e('Back Order', 'seo-fury'); ?></option>
                        <option value="Discontinued" <?php selected($data['availability'] ?? '', 'Discontinued'); ?>><?php esc_html_e('Discontinued', 'seo-fury'); ?></option>
                    </select>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_product_item_condition"><?php esc_html_e('Item Condition', 'seo-fury'); ?></label>
                    <select id="schema_product_item_condition" name="schema_data[item_condition]">
                        <option value="NewCondition" <?php selected($data['item_condition'] ?? 'NewCondition', 'NewCondition'); ?>><?php esc_html_e('New', 'seo-fury'); ?></option>
                        <option value="UsedCondition" <?php selected($data['item_condition'] ?? '', 'UsedCondition'); ?>><?php esc_html_e('Used', 'seo-fury'); ?></option>
                        <option value="RefurbishedCondition" <?php selected($data['item_condition'] ?? '', 'RefurbishedCondition'); ?>><?php esc_html_e('Refurbished', 'seo-fury'); ?></option>
                        <option value="DamagedCondition" <?php selected($data['item_condition'] ?? '', 'DamagedCondition'); ?>><?php esc_html_e('Damaged', 'seo-fury'); ?></option>
                    </select>
                </div>

                <!-- Seller -->
                <div class="seo-fury-field" style="grid-column: span 2">
                    <input type="hidden" name="schema_data[seller_use_org]" value="0">
                    <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:600;">
                        <input type="checkbox" id="schema_product_seller_use_org" name="schema_data[seller_use_org]" value="1" <?php checked($prod_use_org); ?>>
                        <?php esc_html_e('Seller = Organization from homepage', 'seo-fury'); ?>
                    </label>
                    <div class="sf-publisher-org-preview" <?php echo esc_attr( !$prod_use_org ? 'style="display:none"' : '' ); ?>>
                        <code class="sf-schema-ref-preview">"seller": { "@id": "<?php echo esc_html(home_url('/#organization')); ?>" }</code>
                    </div>
                </div>

                <div id="sf-product-seller-manual" class="seo-fury-field" style="grid-column: span 2; padding:0;<?php echo esc_attr( $prod_use_org ? ' display:none' : '' ); ?>">
                    <div class="seo-fury-field">
                        <label for="schema_product_seller_name"><?php esc_html_e('Seller Name', 'seo-fury'); ?></label>
                        <input type="text" id="schema_product_seller_name" name="schema_data[seller_name]"
                               value="<?php echo esc_attr($data['seller_name'] ?? get_bloginfo('name')); ?>">
                    </div>
                </div>

                <!-- AggregateRating (optional) -->
                <div class="seo-fury-field sf-opt-item" style="grid-column: span 2">
                    <div class="sf-opt-header">
                        <button type="button" class="sf-opt-toggle-btn<?php echo esc_attr( (!empty($data['rating_value']) || !empty($data['review_count'])) ? ' active' : '' ); ?>">
                            <span class="sf-opt-arrow"></span>
                            <code>aggregateRating</code>
                        </button>
                        <p class="description"><?php esc_html_e('Optional: show aggregate rating if reviews exist on the page', 'seo-fury'); ?></p>
                    </div>
                    <div class="sf-opt-body"<?php echo esc_attr( (empty($data['rating_value']) && empty($data['review_count'])) ? ' style="display:none"' : '' ); ?>>
                        <div class="sf-opt-body-grid">
                            <div class="seo-fury-field">
                                <label for="schema_product_rating_value"><?php esc_html_e('Rating Value', 'seo-fury'); ?></label>
                                <input type="number" min="1" max="5" step="0.1" id="schema_product_rating_value"
                                       name="schema_data[rating_value]"
                                       value="<?php echo esc_attr($data['rating_value'] ?? ''); ?>" placeholder="4.8">
                            </div>
                            <div class="seo-fury-field">
                                <label for="schema_product_review_count"><?php esc_html_e('Review Count', 'seo-fury'); ?></label>
                                <input type="number" min="1" id="schema_product_review_count"
                                       name="schema_data[review_count]"
                                       value="<?php echo esc_attr($data['review_count'] ?? ''); ?>" placeholder="126">
                            </div>
                        </div>
                    </div>
                </div>

            </div>
        </div>
        <?php
    }

    private function render_faq_fields($data, $post) {
        $faqs = $data['faq_items'] ?? array(array('question' => '', 'answer' => ''));
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('FAQ Schema Details', 'seo-fury'); ?></h4>
            <p class="description"><?php esc_html_e('Add frequently asked questions and their answers', 'seo-fury'); ?></p>

            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#faqpage'); ?>
            </div>

            <div id="faq-items-container">
                <?php foreach ($faqs as $index => $faq): ?>
                    <div class="faq-item" data-index="<?php echo esc_attr( $index ); ?>">
                        <div class="seo-fury-field">
                            <label><?php /* translators: %d: question number */ echo esc_html( sprintf( __( 'Question %d', 'seo-fury' ), $index + 1 ) ); ?></label>
                            <input type="text" name="schema_data[faq_items][<?php echo esc_attr( $index ); ?>][question]"
                                   value="<?php echo esc_attr($faq['question'] ?? ''); ?>"
                                   placeholder="<?php echo esc_attr__('What is your question?', 'seo-fury'); ?>">
                        </div>
                        <div class="seo-fury-field">
                            <label><?php esc_html_e('Answer', 'seo-fury'); ?></label>
                            <textarea name="schema_data[faq_items][<?php echo esc_attr( $index ); ?>][answer]"
                                      rows="3" placeholder="<?php echo esc_attr__('Type the answer here...', 'seo-fury'); ?>"><?php echo esc_textarea($faq['answer'] ?? ''); ?></textarea>
                        </div>
                        <button type="button" class="button remove-faq-item"><?php esc_html_e('Remove', 'seo-fury'); ?></button>
                        <hr style="margin: 15px 0;">
                    </div>
                <?php endforeach; ?>
            </div>

            <button type="button" class="button button-secondary" id="add-faq-item">
                <span class="dashicons dashicons-plus-alt" style="margin-top: 3px;"></span>
                <?php esc_html_e('Add FAQ Item', 'seo-fury'); ?>
            </button>
        </div>
        <?php
    }

    private function render_howto_fields($data, $post) {
        $steps = $data['steps'] ?? array(array('name' => '', 'text' => '', 'image' => ''));
        $default_date_pub = (!empty($post->post_date) && $post->post_date !== '0000-00-00 00:00:00') ? wp_date('Y-m-d\TH:i', strtotime($post->post_date)) : '';
        $default_date_mod = (!empty($post->post_modified) && $post->post_modified !== '0000-00-00 00:00:00') ? wp_date('Y-m-d\TH:i', strtotime($post->post_modified)) : '';
        $howto_use_org = !isset($data['publisher_use_org']) || (bool) $data['publisher_use_org'];
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('How-To Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#howto'); ?>

                <div class="seo-fury-field" style="grid-column: span 2">
                    <label for="schema_howto_name"><?php esc_html_e('Guide Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_howto_name" name="schema_data[name]"
                               value="<?php echo esc_attr($data['name'] ?? $post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field" style="grid-column: span 2">
                    <label for="schema_howto_description"><?php esc_html_e('Description', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <textarea id="schema_howto_description" name="schema_data[description]"
                                  rows="3"><?php echo esc_textarea($data['description'] ?? ''); ?></textarea>
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field" style="grid-column: span 2">
                    <label for="schema_howto_image"><?php esc_html_e('Main Image URL', 'seo-fury'); ?></label>
                    <input type="url" id="schema_howto_image" name="schema_data[image]"
                           value="<?php echo esc_url($data['image'] ?? ''); ?>"
                           placeholder="https://example.com/image.jpg">
                    <p class="description"><?php esc_html_e('Main image for the How-To guide (ImageObject)', 'seo-fury'); ?></p>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_howto_image_width"><?php esc_html_e('Image Width (px)', 'seo-fury'); ?></label>
                    <input type="number" id="schema_howto_image_width" name="schema_data[image_width]"
                           value="<?php echo esc_attr($data['image_width'] ?? ''); ?>" placeholder="1200">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_howto_image_height"><?php esc_html_e('Image Height (px)', 'seo-fury'); ?></label>
                    <input type="number" id="schema_howto_image_height" name="schema_data[image_height]"
                           value="<?php echo esc_attr($data['image_height'] ?? ''); ?>" placeholder="630">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_howto_total_time"><?php esc_html_e('Total Time (ISO 8601)', 'seo-fury'); ?></label>
                    <input type="text" id="schema_howto_total_time" name="schema_data[total_time]"
                           value="<?php echo esc_attr($data['total_time'] ?? ''); ?>" placeholder="PT5D">
                    <p class="description"><?php esc_html_e('e.g. PT2H30M (2 hours 30 min), PT5D (5 days)', 'seo-fury'); ?></p>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_howto_cost_currency"><?php esc_html_e('Estimated Cost Currency', 'seo-fury'); ?></label>
                    <input type="text" id="schema_howto_cost_currency" name="schema_data[cost_currency]"
                           value="<?php echo esc_attr($data['cost_currency'] ?? ''); ?>" placeholder="USD">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_howto_cost_value"><?php esc_html_e('Estimated Cost Value', 'seo-fury'); ?></label>
                    <input type="text" id="schema_howto_cost_value" name="schema_data[cost_value]"
                           value="<?php echo esc_attr($data['cost_value'] ?? ''); ?>" placeholder="100-500">
                </div>

                <!-- Supply -->
                <div class="seo-fury-field sf-opt-item" style="grid-column: span 2">
                    <div class="sf-opt-header">
                        <button type="button" class="sf-opt-toggle-btn<?php echo esc_attr( !empty($data['supply']) ? ' active' : '' ); ?>">
                            <span class="sf-opt-arrow"></span>
                            <code>supply</code>
                        </button>
                        <p class="description"><?php esc_html_e('Materials / supplies needed (HowToSupply)', 'seo-fury'); ?></p>
                    </div>
                    <div class="sf-opt-body"<?php echo esc_attr( empty($data['supply']) ? ' style="display:none"' : '' ); ?>>
                        <div class="sf-array-list">
                            <?php foreach (($data['supply'] ?? []) as $val): ?>
                            <div class="sf-array-row">
                                <input type="text" name="schema_data[supply][]" value="<?php echo esc_attr($val); ?>" placeholder="<?php esc_attr_e('e.g. Cement', 'seo-fury'); ?>">
                                <button type="button" class="sf-array-remove-btn" title="<?php esc_attr_e('Remove', 'seo-fury'); ?>">&#x2715;</button>
                            </div>
                            <?php endforeach; ?>
                        </div>
                        <button type="button" class="sf-array-add-btn" data-field-name="schema_data[supply][]" data-placeholder="<?php esc_attr_e('e.g. Cement', 'seo-fury'); ?>"><?php esc_html_e('+ Add Supply', 'seo-fury'); ?></button>
                    </div>
                </div>

                <!-- Tool -->
                <div class="seo-fury-field sf-opt-item" style="grid-column: span 2">
                    <div class="sf-opt-header">
                        <button type="button" class="sf-opt-toggle-btn<?php echo esc_attr( !empty($data['tool']) ? ' active' : '' ); ?>">
                            <span class="sf-opt-arrow"></span>
                            <code>tool</code>
                        </button>
                        <p class="description"><?php esc_html_e('Tools needed to complete the guide (HowToTool)', 'seo-fury'); ?></p>
                    </div>
                    <div class="sf-opt-body"<?php echo esc_attr( empty($data['tool']) ? ' style="display:none"' : '' ); ?>>
                        <div class="sf-array-list">
                            <?php foreach (($data['tool'] ?? []) as $val): ?>
                            <div class="sf-array-row">
                                <input type="text" name="schema_data[tool][]" value="<?php echo esc_attr($val); ?>" placeholder="<?php esc_attr_e('e.g. Hammer', 'seo-fury'); ?>">
                                <button type="button" class="sf-array-remove-btn" title="<?php esc_attr_e('Remove', 'seo-fury'); ?>">&#x2715;</button>
                            </div>
                            <?php endforeach; ?>
                        </div>
                        <button type="button" class="sf-array-add-btn" data-field-name="schema_data[tool][]" data-placeholder="<?php esc_attr_e('e.g. Hammer', 'seo-fury'); ?>"><?php esc_html_e('+ Add Tool', 'seo-fury'); ?></button>
                    </div>
                </div>

                <div class="sf-subgroup-header" style="grid-column: span 2">
                    <span class="sf-subgroup-title"><?php esc_html_e('Author', 'seo-fury'); ?></span>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_howto_author"><?php esc_html_e('Author Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_howto_author" name="schema_data[author]"
                               value="<?php echo esc_attr($data['author'] ?? '%name%'); ?>"
                               placeholder="%name%">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="sf-subgroup-header" style="grid-column: span 2">
                    <span class="sf-subgroup-title"><?php esc_html_e('Publisher', 'seo-fury'); ?></span>
                </div>

                <div class="seo-fury-field" style="grid-column: span 2">
                    <input type="hidden" name="schema_data[publisher_use_org]" value="0">
                    <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:600;">
                        <input type="checkbox" id="schema_howto_publisher_use_org" name="schema_data[publisher_use_org]" value="1" <?php checked($howto_use_org); ?>>
                        <?php esc_html_e('Use Organization markup from homepage', 'seo-fury'); ?>
                    </label>
                    <div class="sf-publisher-org-preview" <?php echo esc_attr( !$howto_use_org ? 'style="display:none"' : '' ); ?>>
                        <code class="sf-schema-ref-preview">"publisher": { "@id": "<?php echo esc_html(home_url('/#organization')); ?>" }</code>
                    </div>
                </div>

                <div id="sf-howto-publisher-manual" class="seo-fury-field" style="grid-column: span 2; padding:0;<?php echo esc_attr( $howto_use_org ? ' display:none' : '' ); ?>">
                    <div class="seo-fury-field">
                        <label for="schema_howto_publisher"><?php esc_html_e('Publisher Name', 'seo-fury'); ?></label>
                        <input type="text" id="schema_howto_publisher" name="schema_data[publisher]"
                               value="<?php echo esc_attr($data['publisher'] ?? get_bloginfo('name')); ?>">
                    </div>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_howto_in_language"><?php esc_html_e('Language (inLanguage)', 'seo-fury'); ?></label>
                    <input type="text" id="schema_howto_in_language" name="schema_data[in_language]"
                           value="<?php echo esc_attr($data['in_language'] ?? ''); ?>" placeholder="ru-RU">
                    <p class="description"><?php esc_html_e('e.g. ru-RU, en-US', 'seo-fury'); ?></p>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_howto_date_published"><?php esc_html_e('Date Published', 'seo-fury'); ?></label>
                    <?php $has_custom_pub = isset($data['date_published']) && $data['date_published'] !== ''; ?>
                    <div class="sf-schema-date-field" data-wp-date="<?php echo esc_attr($default_date_pub); ?>">
                        <div class="sf-date-auto-row"<?php echo esc_attr( $has_custom_pub ? ' style="display:none"' : '' ); ?>>
                            <span class="sf-date-wp-value"><?php echo esc_html($default_date_pub ?: __('Not set', 'seo-fury')); ?></span>
                            <span class="sf-date-wp-label"><?php esc_html_e('(from WordPress)', 'seo-fury'); ?></span><br>
                            <a href="#" class="sf-schema-date-custom-btn"><?php esc_html_e('Set custom date', 'seo-fury'); ?></a>
                        </div>
                        <div class="sf-date-custom-row"<?php echo esc_attr( !$has_custom_pub ? ' style="display:none"' : '' ); ?>>
                            <input type="datetime-local" id="schema_howto_date_published" name="schema_data[date_published]"
                                   value="<?php echo esc_attr($data['date_published'] ?? ''); ?>">
                            <br><a href="#" class="sf-schema-date-wp-btn"><?php esc_html_e('↺ Use WordPress date', 'seo-fury'); ?></a>
                        </div>
                    </div>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_howto_date_modified"><?php esc_html_e('Date Modified', 'seo-fury'); ?></label>
                    <?php $has_custom_mod = isset($data['date_modified']) && $data['date_modified'] !== ''; ?>
                    <div class="sf-schema-date-field" data-wp-date="<?php echo esc_attr($default_date_mod); ?>">
                        <div class="sf-date-auto-row"<?php echo esc_attr( $has_custom_mod ? ' style="display:none"' : '' ); ?>>
                            <span class="sf-date-wp-value"><?php echo esc_html($default_date_mod ?: __('Not set', 'seo-fury')); ?></span>
                            <span class="sf-date-wp-label"><?php esc_html_e('(from WordPress)', 'seo-fury'); ?></span><br>
                            <a href="#" class="sf-schema-date-custom-btn"><?php esc_html_e('Set custom date', 'seo-fury'); ?></a>
                        </div>
                        <div class="sf-date-custom-row"<?php echo esc_attr( !$has_custom_mod ? ' style="display:none"' : '' ); ?>>
                            <input type="datetime-local" id="schema_howto_date_modified" name="schema_data[date_modified]"
                                   value="<?php echo esc_attr($data['date_modified'] ?? ''); ?>">
                            <br><a href="#" class="sf-schema-date-wp-btn"><?php esc_html_e('↺ Use WordPress date', 'seo-fury'); ?></a>
                        </div>
                    </div>
                </div>

            </div><!-- /.seo-fury-fields-grid -->

            <h5 style="margin: 20px 0 10px 0;"><?php esc_html_e('Steps', 'seo-fury'); ?></h5>
            <div id="howto-steps-container">
                <?php foreach ($steps as $index => $step): ?>
                    <div class="howto-step" data-index="<?php echo esc_attr( $index ); ?>">
                        <div class="seo-fury-field">
                            <label><?php /* translators: %d: step number */ echo esc_html( sprintf( __( 'Step %d Name', 'seo-fury' ), $index + 1 ) ); ?></label>
                            <input type="text" name="schema_data[steps][<?php echo esc_attr( $index ); ?>][name]"
                                   value="<?php echo esc_attr($step['name'] ?? ''); ?>">
                        </div>
                        <div class="seo-fury-field">
                            <label><?php esc_html_e('Step Description', 'seo-fury'); ?></label>
                            <textarea name="schema_data[steps][<?php echo esc_attr( $index ); ?>][text]"
                                      rows="2"><?php echo esc_textarea($step['text'] ?? ''); ?></textarea>
                        </div>
                        <div class="seo-fury-field">
                            <label><?php esc_html_e('Step Image URL (optional)', 'seo-fury'); ?></label>
                            <input type="url" name="schema_data[steps][<?php echo esc_attr( $index ); ?>][image]"
                                   value="<?php echo esc_url($step['image'] ?? ''); ?>"
                                   placeholder="https://example.com/step<?php echo esc_attr( $index + 1 ); ?>.jpg">
                        </div>
                        <button type="button" class="button remove-howto-step"><?php esc_html_e('Remove Step', 'seo-fury'); ?></button>
                        <hr style="margin: 15px 0;">
                    </div>
                <?php endforeach; ?>
            </div>

            <button type="button" class="button button-secondary" id="add-howto-step">
                <span class="dashicons dashicons-plus-alt" style="margin-top: 3px;"></span>
                <?php esc_html_e('Add Step', 'seo-fury'); ?>
            </button>
        </div>
        <?php
    }

    private function render_review_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Review Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#review'); ?>
                <div class="seo-fury-field">
                    <label for="schema_review_item"><?php esc_html_e('Item Reviewed', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_review_item" name="schema_data[item_name]"
                               value="<?php echo esc_attr($data['item_name'] ?? ''); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_review_rating"><?php esc_html_e('Rating (1-5)', 'seo-fury'); ?></label>
                    <input type="number" min="1" max="5" step="0.1" id="schema_review_rating"
                           name="schema_data[rating]" value="<?php echo esc_attr($data['rating'] ?? '5'); ?>">
                </div>

                <?php
                $reviewer_name = '';
                if (!empty($post->post_author)) {
                    $reviewer_user = get_userdata($post->post_author);
                    $reviewer_name = $reviewer_user ? $reviewer_user->display_name : '';
                }
                ?>
                <div class="seo-fury-field">
                    <label for="schema_review_author"><?php esc_html_e('Reviewer Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_review_author" name="schema_data[author]"
                               value="<?php echo esc_attr($data['author'] ?? $reviewer_name); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_review_date"><?php esc_html_e('Review Date', 'seo-fury'); ?></label>
                    <input type="date" id="schema_review_date" name="schema_data[review_date]"
                           value="<?php echo esc_attr($data['review_date'] ?? wp_date('Y-m-d')); ?>">
                </div>
            </div>
        </div>
        <?php
    }

    private function render_recipe_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Recipe Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#recipe'); ?>
                <div class="seo-fury-field">
                    <label for="schema_recipe_name"><?php esc_html_e('Recipe Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_recipe_name" name="schema_data[name]"
                               value="<?php echo esc_attr($data['name'] ?? $post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_recipe_prep_time"><?php esc_html_e('Prep Time (minutes)', 'seo-fury'); ?></label>
                    <input type="number" id="schema_recipe_prep_time" name="schema_data[prep_time]"
                           value="<?php echo esc_attr($data['prep_time'] ?? ''); ?>">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_recipe_cook_time"><?php esc_html_e('Cook Time (minutes)', 'seo-fury'); ?></label>
                    <input type="number" id="schema_recipe_cook_time" name="schema_data[cook_time]"
                           value="<?php echo esc_attr($data['cook_time'] ?? ''); ?>">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_recipe_yield"><?php esc_html_e('Servings', 'seo-fury'); ?></label>
                    <input type="text" id="schema_recipe_yield" name="schema_data[recipe_yield]"
                           value="<?php echo esc_attr($data['recipe_yield'] ?? ''); ?>" placeholder="<?php echo esc_attr__('4 servings', 'seo-fury'); ?>">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_recipe_calories"><?php esc_html_e('Calories', 'seo-fury'); ?></label>
                    <input type="number" id="schema_recipe_calories" name="schema_data[calories]"
                           value="<?php echo esc_attr($data['calories'] ?? ''); ?>">
                </div>
            </div>

            <div class="seo-fury-field">
                <label for="schema_recipe_ingredients"><?php esc_html_e('Ingredients (one per line)', 'seo-fury'); ?></label>
                <textarea id="schema_recipe_ingredients" name="schema_data[ingredients]"
                          rows="5"><?php echo esc_textarea($data['ingredients'] ?? ''); ?></textarea>
            </div>

            <div class="seo-fury-field">
                <label for="schema_recipe_instructions"><?php esc_html_e('Instructions', 'seo-fury'); ?></label>
                <textarea id="schema_recipe_instructions" name="schema_data[instructions]"
                          rows="8"><?php echo esc_textarea($data['instructions'] ?? ''); ?></textarea>
            </div>
        </div>
        <?php
    }

    private function render_event_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Event Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#event'); ?>
                <div class="seo-fury-field">
                    <label for="schema_event_name"><?php esc_html_e('Event Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_event_name" name="schema_data[name]"
                               value="<?php echo esc_attr($data['name'] ?? $post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_event_start"><?php esc_html_e('Start Date & Time', 'seo-fury'); ?></label>
                    <input type="datetime-local" id="schema_event_start" name="schema_data[start_date]"
                           value="<?php echo esc_attr($data['start_date'] ?? ''); ?>">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_event_end"><?php esc_html_e('End Date & Time', 'seo-fury'); ?></label>
                    <input type="datetime-local" id="schema_event_end" name="schema_data[end_date]"
                           value="<?php echo esc_attr($data['end_date'] ?? ''); ?>">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_event_location"><?php esc_html_e('Location Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_event_location" name="schema_data[location_name]"
                               value="<?php echo esc_attr($data['location_name'] ?? ''); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_event_address"><?php esc_html_e('Address', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_event_address" name="schema_data[address]"
                               value="<?php echo esc_attr($data['address'] ?? ''); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_event_price"><?php esc_html_e('Price', 'seo-fury'); ?></label>
                    <input type="number" step="0.01" id="schema_event_price" name="schema_data[price]"
                           value="<?php echo esc_attr($data['price'] ?? ''); ?>">
                </div>
            </div>
        </div>
        <?php
    }

    private function render_video_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Video Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#video'); ?>
                <div class="seo-fury-field">
                    <label for="schema_video_name"><?php esc_html_e('Video Title', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_video_name" name="schema_data[name]"
                               value="<?php echo esc_attr($data['name'] ?? $post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_video_description"><?php esc_html_e('Description', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <textarea id="schema_video_description" name="schema_data[description]"
                                  rows="3"><?php echo esc_textarea($data['description'] ?? ''); ?></textarea>
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>

                <div class="seo-fury-field">
                    <label for="schema_video_url"><?php esc_html_e('Video URL', 'seo-fury'); ?></label>
                    <input type="url" id="schema_video_url" name="schema_data[content_url]"
                           value="<?php echo esc_url($data['content_url'] ?? ''); ?>">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_video_thumbnail"><?php esc_html_e('Thumbnail URL', 'seo-fury'); ?></label>
                    <input type="url" id="schema_video_thumbnail" name="schema_data[thumbnail_url]"
                           value="<?php echo esc_url($data['thumbnail_url'] ?? ''); ?>">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_video_upload_date"><?php esc_html_e('Upload Date', 'seo-fury'); ?></label>
                    <input type="date" id="schema_video_upload_date" name="schema_data[upload_date]"
                           value="<?php echo esc_attr($data['upload_date'] ?? wp_date('Y-m-d')); ?>">
                </div>

                <div class="seo-fury-field">
                    <label for="schema_video_duration"><?php esc_html_e('Duration (ISO 8601)', 'seo-fury'); ?></label>
                    <input type="text" id="schema_video_duration" name="schema_data[duration]"
                           value="<?php echo esc_attr($data['duration'] ?? ''); ?>" placeholder="PT1M30S">
                    <p class="description"><?php esc_html_e('Format: PT1H30M (1 hour 30 minutes)', 'seo-fury'); ?></p>
                </div>
            </div>
        </div>
        <?php
    }

    private function render_breadcrumb_fields($data, $post) {
        $items = $data['items'] ?? '';
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('BreadcrumbList Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#breadcrumb'); ?>
            </div>
            <p class="description"><?php esc_html_e('Enter one breadcrumb per line: Label | URL', 'seo-fury'); ?></p>
            <div class="seo-fury-field">
                <textarea id="schema_breadcrumb_items" name="schema_data[items]" rows="4" placeholder="Home | https://example.com&#10;Blog | https://example.com/blog"><?php echo esc_textarea($items); ?></textarea>
            </div>
        </div>
        <?php
    }

    private function render_table_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Table Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#table'); ?>
                <div class="seo-fury-field">
                    <label for="schema_table_name"><?php esc_html_e('Table Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_table_name" name="schema_data[name]" value="<?php echo esc_attr($data['name'] ?? $post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_table_description"><?php esc_html_e('Description', 'seo-fury'); ?></label>
                    <textarea id="schema_table_description" name="schema_data[description]" rows="3"><?php echo esc_textarea($data['description'] ?? ''); ?></textarea>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_table_rows"><?php esc_html_e('Rows', 'seo-fury'); ?></label>
                    <textarea id="schema_table_rows" name="schema_data[rows]" rows="4" placeholder="Header A | Header B&#10;Row 1 A | Row 1 B"><?php echo esc_textarea($data['rows'] ?? ''); ?></textarea>
                    <p class="description"><?php esc_html_e('Use one row per line, columns separated by |', 'seo-fury'); ?></p>
                </div>
            </div>
        </div>
        <?php
    }

    private function render_service_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Service Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#service'); ?>
                <div class="seo-fury-field">
                    <label for="schema_service_name"><?php esc_html_e('Service Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_service_name" name="schema_data[name]" value="<?php echo esc_attr($data['name'] ?? $post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_service_description"><?php esc_html_e('Description', 'seo-fury'); ?></label>
                    <textarea id="schema_service_description" name="schema_data[description]" rows="3"><?php echo esc_textarea($data['description'] ?? ''); ?></textarea>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_service_provider"><?php esc_html_e('Provider Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_service_provider" name="schema_data[provider]" value="<?php echo esc_attr($data['provider'] ?? get_bloginfo('name')); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_service_area"><?php esc_html_e('Area Served', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_service_area" name="schema_data[area_served]" value="<?php echo esc_attr($data['area_served'] ?? ''); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_service_type"><?php esc_html_e('Service Type', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_service_type" name="schema_data[service_type]" value="<?php echo esc_attr($data['service_type'] ?? ''); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
            </div>
        </div>
        <?php
    }

    private function render_jobposting_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Job Posting Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#jobposting'); ?>
                <div class="seo-fury-field">
                    <label for="schema_job_title"><?php esc_html_e('Job Title', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_job_title" name="schema_data[title]" value="<?php echo esc_attr($data['title'] ?? $post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_job_description"><?php esc_html_e('Description', 'seo-fury'); ?></label>
                    <textarea id="schema_job_description" name="schema_data[description]" rows="3"><?php echo esc_textarea($data['description'] ?? ''); ?></textarea>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_job_date_posted"><?php esc_html_e('Date Posted', 'seo-fury'); ?></label>
                    <input type="date" id="schema_job_date_posted" name="schema_data[date_posted]" value="<?php echo esc_attr($data['date_posted'] ?? wp_date('Y-m-d', strtotime($post->post_date))); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_job_valid_through"><?php esc_html_e('Valid Through', 'seo-fury'); ?></label>
                    <input type="date" id="schema_job_valid_through" name="schema_data[valid_through]" value="<?php echo esc_attr($data['valid_through'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_job_employment_type"><?php esc_html_e('Employment Type', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_job_employment_type" name="schema_data[employment_type]" value="<?php echo esc_attr($data['employment_type'] ?? ''); ?>" placeholder="<?php echo esc_attr__('Full-time', 'seo-fury'); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_job_org"><?php esc_html_e('Hiring Organization', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_job_org" name="schema_data[hiring_org]" value="<?php echo esc_attr($data['hiring_org'] ?? get_bloginfo('name')); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_job_location"><?php esc_html_e('Job Location', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_job_location" name="schema_data[job_location]" value="<?php echo esc_attr($data['job_location'] ?? ''); ?>" placeholder="<?php echo esc_attr__('City, Country', 'seo-fury'); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
            </div>
        </div>
        <?php
    }

    private function render_person_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Person Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#person'); ?>
                <div class="seo-fury-field">
                    <label for="schema_person_name"><?php esc_html_e('Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_person_name" name="schema_data[name]" value="<?php echo esc_attr($data['name'] ?? $post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_person_job"><?php esc_html_e('Job Title', 'seo-fury'); ?></label>
                    <input type="text" id="schema_person_job" name="schema_data[job_title]" value="<?php echo esc_attr($data['job_title'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_person_url"><?php esc_html_e('URL', 'seo-fury'); ?></label>
                    <input type="text" id="schema_person_url" name="schema_data[url]" value="<?php echo esc_attr($data['url'] ?? ''); ?>" placeholder="%url%">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_person_image"><?php esc_html_e('Image URL', 'seo-fury'); ?></label>
                    <input type="text" id="schema_person_image" name="schema_data[image]" value="<?php echo esc_attr($data['image'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_person_works_for"><?php esc_html_e('Works For (Organization)', 'seo-fury'); ?></label>
                    <input type="text" id="schema_person_works_for" name="schema_data[works_for]" value="<?php echo esc_attr($data['works_for'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_person_description"><?php esc_html_e('Description', 'seo-fury'); ?></label>
                    <textarea id="schema_person_description" name="schema_data[description]" rows="3"><?php echo esc_textarea($data['description'] ?? ''); ?></textarea>
                </div>
                <div class="seo-fury-field" style="grid-column: span 2">
                    <label for="schema_person_same_as"><?php esc_html_e('Profiles (one URL per line)', 'seo-fury'); ?></label>
                    <textarea id="schema_person_same_as" name="schema_data[same_as]" rows="3" placeholder="https://twitter.com/...&#10;https://linkedin.com/in/..."><?php echo esc_textarea($data['same_as'] ?? ''); ?></textarea>
                </div>
            </div>
        </div>
        <?php
    }

    private function render_organization_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Organization Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#organization'); ?>
                <div class="seo-fury-field">
                    <label for="schema_org_name"><?php esc_html_e('Name', 'seo-fury'); ?></label>
                    <input type="text" id="schema_org_name" name="schema_data[name]" value="<?php echo esc_attr($data['name'] ?? get_bloginfo('name')); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_org_url"><?php esc_html_e('URL', 'seo-fury'); ?></label>
                    <input type="text" id="schema_org_url" name="schema_data[url]" value="<?php echo esc_attr($data['url'] ?? home_url('/')); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_org_logo"><?php esc_html_e('Logo URL', 'seo-fury'); ?></label>
                    <input type="text" id="schema_org_logo" name="schema_data[logo]" value="<?php echo esc_attr($data['logo'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_org_email"><?php esc_html_e('Email', 'seo-fury'); ?></label>
                    <input type="text" id="schema_org_email" name="schema_data[email]" value="<?php echo esc_attr($data['email'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_org_phone"><?php esc_html_e('Telephone', 'seo-fury'); ?></label>
                    <input type="text" id="schema_org_phone" name="schema_data[telephone]" value="<?php echo esc_attr($data['telephone'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_org_description"><?php esc_html_e('Description', 'seo-fury'); ?></label>
                    <textarea id="schema_org_description" name="schema_data[description]" rows="3"><?php echo esc_textarea($data['description'] ?? ''); ?></textarea>
                </div>
                <div class="seo-fury-field" style="grid-column: span 2">
                    <label for="schema_org_same_as"><?php esc_html_e('Profiles (one URL per line)', 'seo-fury'); ?></label>
                    <textarea id="schema_org_same_as" name="schema_data[same_as]" rows="3"><?php echo esc_textarea($data['same_as'] ?? ''); ?></textarea>
                </div>
            </div>
        </div>
        <?php
    }

    private function render_course_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Course Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#course'); ?>
                <div class="seo-fury-field">
                    <label for="schema_course_name"><?php esc_html_e('Course Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_course_name" name="schema_data[name]" value="<?php echo esc_attr($data['name'] ?? $post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_course_provider"><?php esc_html_e('Provider (Organization)', 'seo-fury'); ?></label>
                    <input type="text" id="schema_course_provider" name="schema_data[provider]" value="<?php echo esc_attr($data['provider'] ?? get_bloginfo('name')); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_course_provider_url"><?php esc_html_e('Provider URL', 'seo-fury'); ?></label>
                    <input type="text" id="schema_course_provider_url" name="schema_data[provider_url]" value="<?php echo esc_attr($data['provider_url'] ?? home_url('/')); ?>">
                </div>
                <div class="seo-fury-field" style="grid-column: span 2">
                    <label for="schema_course_description"><?php esc_html_e('Description', 'seo-fury'); ?></label>
                    <textarea id="schema_course_description" name="schema_data[description]" rows="3"><?php echo esc_textarea($data['description'] ?? ''); ?></textarea>
                </div>
            </div>
        </div>
        <?php
    }

    private function render_book_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Book Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#book'); ?>
                <div class="seo-fury-field">
                    <label for="schema_book_name"><?php esc_html_e('Title', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_book_name" name="schema_data[name]" value="<?php echo esc_attr($data['name'] ?? $post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_book_author"><?php esc_html_e('Author', 'seo-fury'); ?></label>
                    <input type="text" id="schema_book_author" name="schema_data[author]" value="<?php echo esc_attr($data['author'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_book_isbn"><?php esc_html_e('ISBN', 'seo-fury'); ?></label>
                    <input type="text" id="schema_book_isbn" name="schema_data[isbn]" value="<?php echo esc_attr($data['isbn'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_book_url"><?php esc_html_e('URL', 'seo-fury'); ?></label>
                    <input type="text" id="schema_book_url" name="schema_data[url]" value="<?php echo esc_attr($data['url'] ?? ''); ?>" placeholder="%url%">
                </div>
                <div class="seo-fury-field" style="grid-column: span 2">
                    <label for="schema_book_description"><?php esc_html_e('Description', 'seo-fury'); ?></label>
                    <textarea id="schema_book_description" name="schema_data[description]" rows="3"><?php echo esc_textarea($data['description'] ?? ''); ?></textarea>
                </div>
            </div>
        </div>
        <?php
    }

    private function render_software_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Software Application Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#software'); ?>
                <div class="seo-fury-field">
                    <label for="schema_software_name"><?php esc_html_e('Name', 'seo-fury'); ?></label>
                    <div class="input-with-dropdown">
                        <input type="text" id="schema_software_name" name="schema_data[name]" value="<?php echo esc_attr($data['name'] ?? $post->post_title); ?>">
                        <?php $this->render_shortcode_dropdown(); ?>
                    </div>
                </div>
                <div class="seo-fury-field">
                    <label for="schema_software_os"><?php esc_html_e('Operating System', 'seo-fury'); ?></label>
                    <input type="text" id="schema_software_os" name="schema_data[operating_system]" value="<?php echo esc_attr($data['operating_system'] ?? ''); ?>" placeholder="Windows, macOS, Android…">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_software_category"><?php esc_html_e('Application Category', 'seo-fury'); ?></label>
                    <input type="text" id="schema_software_category" name="schema_data[application_category]" value="<?php echo esc_attr($data['application_category'] ?? ''); ?>" placeholder="BusinessApplication, GameApplication…">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_software_price"><?php esc_html_e('Price', 'seo-fury'); ?></label>
                    <input type="text" id="schema_software_price" name="schema_data[price]" value="<?php echo esc_attr($data['price'] ?? ''); ?>" placeholder="0">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_software_currency"><?php esc_html_e('Currency', 'seo-fury'); ?></label>
                    <input type="text" id="schema_software_currency" name="schema_data[currency]" value="<?php echo esc_attr($data['currency'] ?? ''); ?>" placeholder="USD">
                </div>
                <div class="seo-fury-field" style="grid-column: span 2">
                    <label for="schema_software_description"><?php esc_html_e('Description', 'seo-fury'); ?></label>
                    <textarea id="schema_software_description" name="schema_data[description]" rows="3"><?php echo esc_textarea($data['description'] ?? ''); ?></textarea>
                </div>
            </div>
        </div>
        <?php
    }

    private function render_localbusiness_fields($data, $post) {
        ?>
        <div class="seo-fury-section">
            <h4><?php esc_html_e('Local Business Schema Details', 'seo-fury'); ?></h4>
            <div class="seo-fury-fields-grid">
                <?php $this->render_schema_id_field($data, '#localbusiness'); ?>
                <div class="seo-fury-field">
                    <label for="schema_lb_type"><?php esc_html_e('Business Type', 'seo-fury'); ?></label>
                    <input type="text" id="schema_lb_type" name="schema_data[business_type]" value="<?php echo esc_attr($data['business_type'] ?? 'LocalBusiness'); ?>" placeholder="Restaurant, Store, LocalBusiness…">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_lb_name"><?php esc_html_e('Name', 'seo-fury'); ?></label>
                    <input type="text" id="schema_lb_name" name="schema_data[name]" value="<?php echo esc_attr($data['name'] ?? get_bloginfo('name')); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_lb_phone"><?php esc_html_e('Telephone', 'seo-fury'); ?></label>
                    <input type="text" id="schema_lb_phone" name="schema_data[telephone]" value="<?php echo esc_attr($data['telephone'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_lb_price_range"><?php esc_html_e('Price Range', 'seo-fury'); ?></label>
                    <input type="text" id="schema_lb_price_range" name="schema_data[price_range]" value="<?php echo esc_attr($data['price_range'] ?? ''); ?>" placeholder="$$">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_lb_image"><?php esc_html_e('Image URL', 'seo-fury'); ?></label>
                    <input type="text" id="schema_lb_image" name="schema_data[image]" value="<?php echo esc_attr($data['image'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_lb_street"><?php esc_html_e('Street Address', 'seo-fury'); ?></label>
                    <input type="text" id="schema_lb_street" name="schema_data[street]" value="<?php echo esc_attr($data['street'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_lb_city"><?php esc_html_e('City', 'seo-fury'); ?></label>
                    <input type="text" id="schema_lb_city" name="schema_data[city]" value="<?php echo esc_attr($data['city'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_lb_region"><?php esc_html_e('Region / State', 'seo-fury'); ?></label>
                    <input type="text" id="schema_lb_region" name="schema_data[region]" value="<?php echo esc_attr($data['region'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_lb_postal"><?php esc_html_e('Postal Code', 'seo-fury'); ?></label>
                    <input type="text" id="schema_lb_postal" name="schema_data[postal]" value="<?php echo esc_attr($data['postal'] ?? ''); ?>">
                </div>
                <div class="seo-fury-field">
                    <label for="schema_lb_country"><?php esc_html_e('Country', 'seo-fury'); ?></label>
                    <input type="text" id="schema_lb_country" name="schema_data[country]" value="<?php echo esc_attr($data['country'] ?? ''); ?>">
                </div>
            </div>
        </div>
        <?php
    }

    private function generate_schema_preview($schema_type, $data, $post) {
        if ($schema_type === 'none') {
            return '';
        }

        $data = SEO_Fury_Shortcode_Variables::resolve_data($data, $post);
        $schema = $this->build_schema_json($schema_type, $data, $post);
        return json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    }

    private function get_custom_schema_preview($custom_schema) {
        $custom_schema = trim((string) $custom_schema);
        if ($custom_schema === '') {
            return '';
        }
        return $custom_schema;
    }

    public function build_schema_json($schema_type, $data, $post) {
        // Legacy: map old blog_posting/news_article types to article with article_type
        if ($schema_type === 'blog_posting') {
            $schema_type = 'article';
            if (empty($data['article_type'])) {
                $data['article_type'] = 'BlogPosting';
            }
        } elseif ($schema_type === 'news_article') {
            $schema_type = 'article';
            if (empty($data['article_type'])) {
                $data['article_type'] = 'NewsArticle';
            }
        }

        // Proper schema.org PascalCase for multi-word types. Without this,
        // types that fall to the default branch (local_business, software, …)
        // emit an invalid @type like "Localbusiness".
        $type_name_map = array(
            'local_business' => 'LocalBusiness',
            'job_posting'    => 'JobPosting',
            'how_to'         => 'HowTo',
            'software'       => 'SoftwareApplication',
            'organization'   => 'Organization',
            'person'         => 'Person',
            'course'         => 'Course',
            'book'           => 'Book',
            'faq'            => 'FAQPage',
            'video'          => 'VideoObject',
            'breadcrumb'     => 'BreadcrumbList',
        );

        $schema = array(
            '@context' => 'https://schema.org',
            '@type' => isset($type_name_map[$schema_type]) ? $type_name_map[$schema_type] : ucfirst(str_replace('_', '', $schema_type))
        );

        switch ($schema_type) {
            case 'article':
                $article_type = !empty($data['article_type']) ? $data['article_type'] : 'Article';
                $schema['@type'] = $article_type;
                $schema['@id'] = !empty($data['id']) ? $data['id'] : (get_permalink($post->ID) . '#article');
                $schema['headline'] = $data['headline'] ?? $post->post_title;
                if (!empty($data['description'])) {
                    $schema['description'] = $data['description'];
                }
                if (!empty($data['keywords'])) {
                    $schema['keywords'] = $data['keywords'];
                }

                $author_name = '';
                if (!empty($data['author'])) {
                    $author_name = $data['author'];
                } elseif (!empty($post->post_author)) {
                    $user = get_userdata($post->post_author);
                    $author_name = $user ? $user->display_name : '';
                }
                $author_type = !empty($data['author_type']) ? $data['author_type'] : 'Person';
                $schema['author'] = array(
                    '@type' => $author_type,
                    'name' => $author_name
                );
                if (!empty($data['author_url'])) {
                    $schema['author']['url'] = $data['author_url'];
                }
                if (!empty($data['author_id'])) {
                    $schema['author']['@id'] = $data['author_id'];
                }
                if (!empty($data['author_same_as']) && is_array($data['author_same_as'])) {
                    $same_as = array_values(array_filter(array_map('trim', $data['author_same_as'])));
                    if (!empty($same_as)) {
                        $schema['author']['sameAs'] = $same_as;
                    }
                }
                if (!empty($data['author_knows_about']) && is_array($data['author_knows_about'])) {
                    $knows_about = array_values(array_filter(array_map('trim', $data['author_knows_about'])));
                    if (!empty($knows_about)) {
                        $schema['author']['knowsAbout'] = $knows_about;
                    }
                }
                if (!empty($data['author_alumni_of_name'])) {
                    $alumni_type = !empty($data['author_alumni_of_type']) ? $data['author_alumni_of_type'] : 'EducationalOrganization';
                    $schema['author']['alumniOf'] = array(
                        '@type' => $alumni_type,
                        'name'  => $data['author_alumni_of_name'],
                    );
                }
                if (!empty($data['author_credential_name'])) {
                    $schema['author']['hasCredential'] = array(
                        '@type'              => 'EducationalOccupationalCredential',
                        'credentialCategory' => 'Professional License',
                        'name'               => $data['author_credential_name'],
                    );
                }

                $schema['mainEntityOfPage'] = array(
                    '@type' => 'WebPage',
                    '@id'   => get_permalink($post->ID),
                );

                $use_org_publisher = !isset($data['publisher_use_org']) || (bool)$data['publisher_use_org'];
                if ($use_org_publisher) {
                    $schema['publisher'] = array(
                        '@id' => home_url('/#organization'),
                    );
                } else {
                    $publisher_type = !empty($data['publisher_type']) ? $data['publisher_type'] : 'Organization';
                    $publisher_name = !empty($data['publisher']) ? $data['publisher'] : get_bloginfo('name');
                    $schema['publisher'] = array(
                        '@type' => $publisher_type,
                        'name'  => $publisher_name,
                    );
                    if (!empty($data['publisher_logo'])) {
                        $schema['publisher']['logo'] = array(
                            '@type' => 'ImageObject',
                            'url'   => $data['publisher_logo'],
                        );
                    }
                    if (!empty($data['publisher_same_as']) && is_array($data['publisher_same_as'])) {
                        $pub_same_as = array_values(array_filter(array_map('trim', $data['publisher_same_as'])));
                        if (!empty($pub_same_as)) {
                            $schema['publisher']['sameAs'] = $pub_same_as;
                        }
                    }
                }

                if (isset($data['date_published']) && !empty($data['date_published'])) {
                    $schema['datePublished'] = wp_date('c', strtotime($data['date_published']));
                } elseif (!empty($post->post_date) && $post->post_date !== '0000-00-00 00:00:00') {
                    $schema['datePublished'] = wp_date('c', strtotime($post->post_date));
                }

                if (isset($data['date_modified']) && !empty($data['date_modified'])) {
                    $schema['dateModified'] = wp_date('c', strtotime($data['date_modified']));
                } elseif (!empty($post->post_modified) && $post->post_modified !== '0000-00-00 00:00:00') {
                    $schema['dateModified'] = wp_date('c', strtotime($post->post_modified));
                }
                $image_url = !empty($data['image']) ? $data['image'] : (has_post_thumbnail($post->ID) ? get_the_post_thumbnail_url($post->ID, 'full') : '');
                if (!empty($image_url)) {
                    $img_obj = array('@type' => 'ImageObject', 'url' => $image_url);
                    if (!empty($data['image_width'])) {
                        $img_obj['width'] = (int) $data['image_width'];
                    }
                    if (!empty($data['image_height'])) {
                        $img_obj['height'] = (int) $data['image_height'];
                    }
                    $schema['image'] = $img_obj;
                }
                if (!empty($data['in_language'])) {
                    $schema['inLanguage'] = $data['in_language'];
                }
                break;

            case 'product':
                $schema['@type'] = 'Product';
                $schema['@id']   = !empty($data['id']) ? $data['id'] : (get_permalink($post->ID) . '#product');
                $schema['name']  = $data['name'] ?? $post->post_title;
                if (!empty($data['description'])) {
                    $schema['description'] = $data['description'];
                }
                if (!empty($data['sku'])) {
                    $schema['sku'] = $data['sku'];
                }
                if (!empty($data['mpn'])) {
                    $schema['mpn'] = $data['mpn'];
                }
                if (!empty($data['brand'])) {
                    $schema['brand'] = array('@type' => 'Brand', 'name' => $data['brand']);
                }
                // image(s)
                if (!empty($data['images']) && is_array($data['images'])) {
                    $prod_images = array_values(array_filter(array_map('trim', $data['images'])));
                    if (!empty($prod_images)) {
                        $schema['image'] = count($prod_images) === 1 ? $prod_images[0] : $prod_images;
                    }
                } elseif (has_post_thumbnail($post->ID)) {
                    $schema['image'] = get_the_post_thumbnail_url($post->ID, 'full');
                }
                // offers
                if (!empty($data['price'])) {
                    $offer = array(
                        '@type'         => 'Offer',
                        'url'           => get_permalink($post->ID),
                        'price'         => $data['price'],
                        'priceCurrency' => $data['currency'] ?? 'USD',
                        'availability'  => 'https://schema.org/' . ($data['availability'] ?? 'InStock'),
                        'itemCondition' => 'https://schema.org/' . ($data['item_condition'] ?? 'NewCondition'),
                    );
                    if (!empty($data['price_valid_until'])) {
                        $offer['priceValidUntil'] = $data['price_valid_until'];
                    }
                    $prod_use_org = !isset($data['seller_use_org']) || (bool) $data['seller_use_org'];
                    if ($prod_use_org) {
                        $offer['seller'] = array('@id' => home_url('/#organization'));
                    } elseif (!empty($data['seller_name'])) {
                        $offer['seller'] = array('@type' => 'Organization', 'name' => $data['seller_name']);
                    }
                    $schema['offers'] = $offer;
                }
                // aggregateRating (optional)
                if (!empty($data['rating_value']) && !empty($data['review_count'])) {
                    $schema['aggregateRating'] = array(
                        '@type'       => 'AggregateRating',
                        'ratingValue' => $data['rating_value'],
                        'reviewCount' => (int) $data['review_count'],
                    );
                }
                break;

            case 'faq':
                $schema['@type'] = 'FAQPage';
                $schema['@id'] = !empty($data['id']) ? $data['id'] : (get_permalink($post->ID) . '#faqpage');
                $schema['mainEntity'] = array();
                if (!empty($data['faq_items'])) {
                    $faq_index = 1;
                    foreach ($data['faq_items'] as $faq) {
                        if (!empty($faq['question']) && !empty($faq['answer'])) {
                            $schema['mainEntity'][] = array(
                                '@type' => 'Question',
                                '@id'   => get_permalink($post->ID) . '#q' . $faq_index,
                                'name'  => $faq['question'],
                                'acceptedAnswer' => array(
                                    '@type' => 'Answer',
                                    'text'  => $faq['answer'],
                                ),
                            );
                            $faq_index++;
                        }
                    }
                }
                break;

            case 'how_to':
                $schema['@type'] = 'HowTo';
                $schema['@id'] = !empty($data['id']) ? $data['id'] : (get_permalink($post->ID) . '#howto');
                $schema['name'] = $data['name'] ?? $post->post_title;
                if (!empty($data['description'])) {
                    $schema['description'] = $data['description'];
                }
                // image
                $howto_img_url = $data['image'] ?? (has_post_thumbnail($post->ID) ? get_the_post_thumbnail_url($post->ID, 'full') : '');
                if (!empty($howto_img_url)) {
                    $howto_img = array('@type' => 'ImageObject', 'url' => $howto_img_url);
                    if (!empty($data['image_width']))  { $howto_img['width']  = (int) $data['image_width']; }
                    if (!empty($data['image_height'])) { $howto_img['height'] = (int) $data['image_height']; }
                    $schema['image'] = $howto_img;
                }
                // totalTime
                if (!empty($data['total_time'])) {
                    $schema['totalTime'] = $data['total_time'];
                }
                // estimatedCost
                if (!empty($data['cost_currency']) || !empty($data['cost_value'])) {
                    $schema['estimatedCost'] = array(
                        '@type'    => 'MonetaryAmount',
                        'currency' => $data['cost_currency'] ?? 'USD',
                        'value'    => $data['cost_value'] ?? '',
                    );
                }
                // supply
                if (!empty($data['supply']) && is_array($data['supply'])) {
                    $supply_items = array();
                    foreach ($data['supply'] as $s) {
                        $s = trim((string) $s);
                        if ($s !== '') {
                            $supply_items[] = array('@type' => 'HowToSupply', 'name' => $s);
                        }
                    }
                    if (!empty($supply_items)) {
                        $schema['supply'] = $supply_items;
                    }
                }
                // tool
                if (!empty($data['tool']) && is_array($data['tool'])) {
                    $tool_items = array();
                    foreach ($data['tool'] as $t) {
                        $t = trim((string) $t);
                        if ($t !== '') {
                            $tool_items[] = array('@type' => 'HowToTool', 'name' => $t);
                        }
                    }
                    if (!empty($tool_items)) {
                        $schema['tool'] = $tool_items;
                    }
                }
                // steps
                $schema['step'] = array();
                if (!empty($data['steps']) && is_array($data['steps'])) {
                    $step_pos = 1;
                    foreach ($data['steps'] as $step) {
                        if (!empty($step['name']) || !empty($step['text'])) {
                            $step_item = array(
                                '@type'    => 'HowToStep',
                                'position' => $step_pos,
                                'name'     => $step['name'] ?? '',
                                'text'     => $step['text'] ?? '',
                            );
                            if (!empty($step['image'])) {
                                $step_item['image'] = $step['image'];
                            }
                            $schema['step'][] = $step_item;
                            $step_pos++;
                        }
                    }
                }
                // author
                $howto_author_name = '';
                if (!empty($data['author'])) {
                    $howto_author_name = $data['author'];
                } elseif (!empty($post->post_author)) {
                    $howto_user = get_userdata($post->post_author);
                    $howto_author_name = $howto_user ? $howto_user->display_name : '';
                }
                if (!empty($howto_author_name)) {
                    $schema['author'] = array('@type' => 'Person', 'name' => $howto_author_name);
                }
                // publisher
                $howto_use_org = !isset($data['publisher_use_org']) || (bool) $data['publisher_use_org'];
                if ($howto_use_org) {
                    $schema['publisher'] = array('@id' => home_url('/#organization'));
                } elseif (!empty($data['publisher'])) {
                    $schema['publisher'] = array('@type' => 'Organization', 'name' => $data['publisher']);
                }
                // dates
                if (!empty($data['date_published'])) {
                    $schema['datePublished'] = wp_date('Y-m-d', strtotime($data['date_published']));
                } elseif (!empty($post->post_date) && $post->post_date !== '0000-00-00 00:00:00') {
                    $schema['datePublished'] = wp_date('Y-m-d', strtotime($post->post_date));
                }
                if (!empty($data['date_modified'])) {
                    $schema['dateModified'] = wp_date('Y-m-d', strtotime($data['date_modified']));
                } elseif (!empty($post->post_modified) && $post->post_modified !== '0000-00-00 00:00:00') {
                    $schema['dateModified'] = wp_date('Y-m-d', strtotime($post->post_modified));
                }
                // inLanguage
                if (!empty($data['in_language'])) {
                    $schema['inLanguage'] = $data['in_language'];
                }
                break;

            case 'review':
                $schema['@type'] = 'Review';
                $schema['@id'] = !empty($data['id']) ? $data['id'] : (get_permalink($post->ID) . '#review');
                $schema['itemReviewed'] = array(
                    '@type' => 'Thing',
                    'name'  => $data['item_name'] ?? '',
                );
                $schema['reviewRating'] = array(
                    '@type'       => 'Rating',
                    'ratingValue' => $data['rating'] ?? '5',
                    'bestRating'  => '5',
                    'worstRating' => '1',
                );
                $schema['author'] = array(
                    '@type' => 'Person',
                    'name'  => $data['author'] ?? '',
                );
                if (!empty($data['review_date'])) {
                    $schema['datePublished'] = $data['review_date'];
                }
                break;

            case 'recipe':
                $schema['@type'] = 'Recipe';
                $schema['@id'] = !empty($data['id']) ? $data['id'] : (get_permalink($post->ID) . '#recipe');
                $schema['name'] = $data['name'] ?? $post->post_title;
                // Google requires an image for Recipe rich results.
                $recipe_image = !empty($data['image']) ? $data['image'] : (has_post_thumbnail($post->ID) ? get_the_post_thumbnail_url($post->ID, 'full') : '');
                if (!empty($recipe_image)) {
                    $schema['image'] = $recipe_image;
                }
                if (!empty($data['prep_time'])) {
                    $schema['prepTime'] = 'PT' . intval($data['prep_time']) . 'M';
                }
                if (!empty($data['cook_time'])) {
                    $schema['cookTime'] = 'PT' . intval($data['cook_time']) . 'M';
                }
                if (!empty($data['recipe_yield'])) {
                    $schema['recipeYield'] = $data['recipe_yield'];
                }
                if (!empty($data['calories'])) {
                    $schema['nutrition'] = array(
                        '@type'    => 'NutritionInformation',
                        'calories' => $data['calories'],
                    );
                }
                if (!empty($data['ingredients'])) {
                    $lines = preg_split('/\r\n|\n|\r/', $data['ingredients']);
                    $schema['recipeIngredient'] = array_values(array_filter(array_map('trim', $lines)));
                }
                if (!empty($data['instructions'])) {
                    // Prefer structured HowToStep[] (better rich result) when the
                    // instructions are given as multiple lines; fall back to the
                    // plain string for a single block of text.
                    $steps = preg_split('/\r\n|\n|\r/', $data['instructions']);
                    $steps = array_values(array_filter(array_map('trim', $steps)));
                    if (count($steps) > 1) {
                        $schema['recipeInstructions'] = array();
                        foreach ($steps as $step) {
                            $schema['recipeInstructions'][] = array(
                                '@type' => 'HowToStep',
                                'text'  => $step,
                            );
                        }
                    } else {
                        $schema['recipeInstructions'] = $data['instructions'];
                    }
                }
                break;

            case 'event':
                $schema['@type'] = 'Event';
                $schema['@id'] = !empty($data['id']) ? $data['id'] : (get_permalink($post->ID) . '#event');
                $schema['name'] = $data['name'] ?? $post->post_title;
                if (!empty($data['start_date'])) {
                    $schema['startDate'] = wp_date('c', strtotime($data['start_date']));
                }
                if (!empty($data['end_date'])) {
                    $schema['endDate'] = wp_date('c', strtotime($data['end_date']));
                }
                if (!empty($data['location_name'])) {
                    $schema['location'] = array(
                        '@type' => 'Place',
                        'name'  => $data['location_name'],
                    );
                    if (!empty($data['address'])) {
                        $schema['location']['address'] = array(
                            '@type'         => 'PostalAddress',
                            'streetAddress' => $data['address'],
                        );
                    }
                }
                if (!empty($data['price'])) {
                    $schema['offers'] = array(
                        '@type'         => 'Offer',
                        'price'         => $data['price'],
                        'priceCurrency' => !empty($data['currency']) ? $data['currency'] : $this->get_default_currency(),
                    );
                    if (!empty($data['url'])) {
                        $schema['offers']['url'] = $data['url'];
                    } else {
                        $schema['offers']['url'] = get_permalink($post->ID);
                    }
                }
                break;

            case 'video':
                $schema['@type'] = 'VideoObject';
                $schema['@id'] = !empty($data['id']) ? $data['id'] : (get_permalink($post->ID) . '#video');
                $schema['name'] = $data['name'] ?? $post->post_title;
                if (!empty($data['description'])) {
                    $schema['description'] = $data['description'];
                }
                if (!empty($data['content_url'])) {
                    $schema['contentUrl'] = $data['content_url'];
                }
                if (!empty($data['thumbnail_url'])) {
                    $schema['thumbnailUrl'] = $data['thumbnail_url'];
                }
                if (!empty($data['upload_date'])) {
                    $schema['uploadDate'] = $data['upload_date'];
                }
                if (!empty($data['duration'])) {
                    $schema['duration'] = $data['duration'];
                }
                break;

            case 'breadcrumb':
                $schema['@type'] = 'BreadcrumbList';
                $schema['@id'] = !empty($data['id']) ? $data['id'] : (get_permalink($post->ID) . '#breadcrumb');
                $schema['itemListElement'] = array();
                if (!empty($data['items'])) {
                    $lines = preg_split("/\r\n|\n|\r/", $data['items']);
                    $position = 1;
                    foreach ($lines as $line) {
                        $parts = array_map('trim', explode('|', $line));
                        if (count($parts) < 2) {
                            continue;
                        }
                        $schema['itemListElement'][] = array(
                            '@type' => 'ListItem',
                            'position' => $position,
                            'name' => $parts[0],
                            'item' => $parts[1],
                        );
                        $position++;
                    }
                    // The last crumb is the current page — per Google's
                    // BreadcrumbList guidance it should omit "item".
                    $last = count($schema['itemListElement']) - 1;
                    if ($last >= 0) {
                        unset($schema['itemListElement'][$last]['item']);
                    }
                } else {
                    $auto_items = $this->build_auto_breadcrumb_items($post);
                    if (!empty($auto_items)) {
                        $schema['itemListElement'] = $this->format_breadcrumb_items($auto_items);
                    }
                }
                break;

            case 'table':
                $schema['@type'] = 'Table';
                $schema['@id'] = !empty($data['id']) ? $data['id'] : (get_permalink($post->ID) . '#table');
                $schema['name'] = $data['name'] ?? $post->post_title;
                if (!empty($data['description'])) {
                    $schema['description'] = $data['description'];
                }
                if (!empty($data['rows'])) {
                    $schema['tableRows'] = preg_split("/\r\n|\n|\r/", $data['rows']);
                }
                break;

            case 'service':
                $schema['@type'] = 'Service';
                $schema['@id'] = !empty($data['id']) ? $data['id'] : (get_permalink($post->ID) . '#service');
                $schema['name'] = $data['name'] ?? $post->post_title;
                if (!empty($data['description'])) {
                    $schema['description'] = $data['description'];
                }
                if (!empty($data['provider'])) {
                    $schema['provider'] = array(
                        '@type' => 'Organization',
                        'name' => $data['provider']
                    );
                }
                if (!empty($data['area_served'])) {
                    $schema['areaServed'] = $data['area_served'];
                }
                if (!empty($data['service_type'])) {
                    $schema['serviceType'] = $data['service_type'];
                }
                break;

            case 'job_posting':
                $schema['@type'] = 'JobPosting';
                $schema['@id'] = !empty($data['id']) ? $data['id'] : (get_permalink($post->ID) . '#jobposting');
                $schema['title'] = $data['title'] ?? $post->post_title;
                if (!empty($data['description'])) {
                    $schema['description'] = $data['description'];
                }
                if (!empty($data['date_posted'])) {
                    $schema['datePosted'] = $data['date_posted'];
                }
                if (!empty($data['valid_through'])) {
                    $schema['validThrough'] = $data['valid_through'];
                }
                if (!empty($data['employment_type'])) {
                    $schema['employmentType'] = $data['employment_type'];
                }
                if (!empty($data['hiring_org'])) {
                    $schema['hiringOrganization'] = array(
                        '@type' => 'Organization',
                        'name' => $data['hiring_org']
                    );
                }
                if (!empty($data['job_location'])) {
                    $schema['jobLocation'] = array(
                        '@type'   => 'Place',
                        'address' => array(
                            '@type'         => 'PostalAddress',
                            'streetAddress' => $data['job_location'],
                        ),
                    );
                }
                break;

            case 'person':
                $schema['@type'] = 'Person';
                $schema['name']  = $data['name'] ?? $post->post_title;
                if (!empty($data['job_title']))   $schema['jobTitle'] = $data['job_title'];
                if (!empty($data['url']))         $schema['url'] = $data['url'];
                if (!empty($data['image']))       $schema['image'] = $data['image'];
                if (!empty($data['works_for']))   $schema['worksFor'] = array('@type' => 'Organization', 'name' => $data['works_for']);
                if (!empty($data['description'])) $schema['description'] = $data['description'];
                $same = $this->schema_lines_to_array($data['same_as'] ?? '');
                if (!empty($same)) $schema['sameAs'] = $same;
                break;

            case 'organization':
                $schema['@type'] = 'Organization';
                $schema['name']  = $data['name'] ?? get_bloginfo('name');
                if (!empty($data['url']))         $schema['url'] = $data['url'];
                if (!empty($data['logo']))        $schema['logo'] = array('@type' => 'ImageObject', 'url' => $data['logo']);
                if (!empty($data['email']))       $schema['email'] = $data['email'];
                if (!empty($data['telephone']))   $schema['telephone'] = $data['telephone'];
                if (!empty($data['description'])) $schema['description'] = $data['description'];
                $same = $this->schema_lines_to_array($data['same_as'] ?? '');
                if (!empty($same)) $schema['sameAs'] = $same;
                break;

            case 'course':
                $schema['@type'] = 'Course';
                $schema['name']  = $data['name'] ?? $post->post_title;
                if (!empty($data['description'])) $schema['description'] = $data['description'];
                $provider = array('@type' => 'Organization', 'name' => !empty($data['provider']) ? $data['provider'] : get_bloginfo('name'));
                if (!empty($data['provider_url'])) $provider['sameAs'] = $data['provider_url'];
                $schema['provider'] = $provider;
                break;

            case 'book':
                $schema['@type'] = 'Book';
                $schema['name']  = $data['name'] ?? $post->post_title;
                if (!empty($data['author']))      $schema['author'] = array('@type' => 'Person', 'name' => $data['author']);
                if (!empty($data['isbn']))        $schema['isbn'] = $data['isbn'];
                if (!empty($data['url']))         $schema['url'] = $data['url'];
                if (!empty($data['description'])) $schema['description'] = $data['description'];
                break;

            case 'software':
                $schema['@type'] = 'SoftwareApplication';
                $schema['name']  = $data['name'] ?? $post->post_title;
                if (!empty($data['operating_system']))     $schema['operatingSystem'] = $data['operating_system'];
                if (!empty($data['application_category'])) $schema['applicationCategory'] = $data['application_category'];
                if (!empty($data['description']))          $schema['description'] = $data['description'];
                if (isset($data['price']) && $data['price'] !== '') {
                    $schema['offers'] = array(
                        '@type'         => 'Offer',
                        'price'         => $data['price'],
                        'priceCurrency' => !empty($data['currency']) ? $data['currency'] : $this->get_default_currency(),
                    );
                }
                break;

            case 'local_business':
                $schema['@type'] = !empty($data['business_type']) ? $data['business_type'] : 'LocalBusiness';
                $schema['name']  = $data['name'] ?? get_bloginfo('name');
                if (!empty($data['description'])) $schema['description'] = $data['description'];
                if (!empty($data['telephone']))   $schema['telephone'] = $data['telephone'];
                if (!empty($data['price_range'])) $schema['priceRange'] = $data['price_range'];
                if (!empty($data['image']))       $schema['image'] = $data['image'];
                if (!empty($data['url']))         $schema['url'] = $data['url'];
                $addr = array();
                if (!empty($data['street']))  $addr['streetAddress']   = $data['street'];
                if (!empty($data['city']))    $addr['addressLocality'] = $data['city'];
                if (!empty($data['region']))  $addr['addressRegion']   = $data['region'];
                if (!empty($data['postal']))  $addr['postalCode']      = $data['postal'];
                if (!empty($data['country'])) $addr['addressCountry']  = $data['country'];
                if (!empty($addr)) {
                    $addr = array_merge(array('@type' => 'PostalAddress'), $addr);
                    $schema['address'] = $addr;
                }
                break;

            default:
                // Types without a dedicated builder (Person, Organization,
                // Course, Book, SoftwareApplication, LocalBusiness): emit at
                // least a valid name/description so the node isn't empty.
                if (!empty($data['name'])) {
                    $schema['name'] = $data['name'];
                } elseif (!empty($post->post_title)) {
                    $schema['name'] = $post->post_title;
                }
                if (!empty($data['description'])) {
                    $schema['description'] = $data['description'];
                }
                if (!empty($data['url'])) {
                    $schema['url'] = $data['url'];
                }
                break;
        }

        return apply_filters('seo_fury_schema_json', $schema, $schema_type, $data, $post);
    }

    private function apply_schema_template($template, $post) {
        return SEO_Fury_Shortcode_Variables::resolve($template, $post);
    }

    /**
     * Best-effort default ISO 4217 currency: WooCommerce store currency if
     * available, otherwise USD. Avoids hardcoding USD into structured data.
     */
    private function get_default_currency() {
        if (function_exists('get_woocommerce_currency')) {
            $cur = get_woocommerce_currency();
            if (!empty($cur)) {
                return $cur;
            }
        }
        return 'USD';
    }

    /**
     * Split a textarea value (newline- or comma-separated) into a clean,
     * de-duplicated list — used for schema sameAs arrays.
     */
    private function schema_lines_to_array($text) {
        if (!is_string($text) || trim($text) === '') {
            return array();
        }
        $parts = preg_split('/[\r\n,]+/', $text);
        $parts = array_values(array_unique(array_filter(array_map('trim', $parts))));
        return $parts;
    }

    private function format_breadcrumb_items($items) {
        $list = array();
        $position = 1;
        foreach ($items as $item) {
            if (empty($item['name']) || empty($item['url'])) {
                continue;
            }
            $list[] = array(
                '@type' => 'ListItem',
                'position' => $position,
                'name' => $item['name'],
                'item' => $item['url'],
            );
            $position++;
        }
        return $list;
    }

    private function normalize_breadcrumb_url($url) {
        return untrailingslashit((string) $url);
    }

    private function build_auto_breadcrumb_items($post) {
        $items = $this->build_breadcrumb_from_menu($post);
        if (!empty($items)) {
            return $items;
        }

        if ($post->post_type === 'page') {
            return $this->build_breadcrumb_from_pages($post);
        }

        if ($post->post_type === 'post') {
            return $this->build_breadcrumb_from_categories($post);
        }

        return array(
            array('name' => __('Home', 'seo-fury'), 'url' => home_url('/')),
            array('name' => get_the_title($post), 'url' => get_permalink($post)),
        );
    }

    private function build_breadcrumb_from_menu($post) {
        $locations = get_nav_menu_locations();
        if (empty($locations)) {
            return array();
        }

        $current_url = $this->normalize_breadcrumb_url(get_permalink($post));
        foreach ($locations as $menu_id) {
            $menu_items = wp_get_nav_menu_items($menu_id);
            if (empty($menu_items)) {
                continue;
            }
            $items_by_id = array();
            $match = null;
            foreach ($menu_items as $menu_item) {
                $items_by_id[$menu_item->ID] = $menu_item;
                if ((int) $menu_item->object_id === (int) $post->ID) {
                    $match = $menu_item;
                } elseif ($this->normalize_breadcrumb_url($menu_item->url) === $current_url) {
                    $match = $menu_item;
                }
            }

            if (!$match) {
                continue;
            }

            $trail = array();
            $node = $match;
            while ($node) {
                array_unshift($trail, $node);
                $parent_id = (int) $node->menu_item_parent;
                if (!$parent_id || !isset($items_by_id[$parent_id])) {
                    break;
                }
                $node = $items_by_id[$parent_id];
            }

            $items = array();
            foreach ($trail as $trail_item) {
                if (empty($trail_item->title) || empty($trail_item->url)) {
                    continue;
                }
                $items[] = array(
                    'name' => wp_strip_all_tags($trail_item->title),
                    'url' => $trail_item->url,
                );
            }
            if (!empty($items)) {
                return $items;
            }
        }

        return array();
    }

    private function build_breadcrumb_from_pages($post) {
        $items = array();
        $items[] = array('name' => __('Home', 'seo-fury'), 'url' => home_url('/'));

        $ancestors = array_reverse(get_post_ancestors($post));
        foreach ($ancestors as $ancestor_id) {
            $items[] = array(
                'name' => get_the_title($ancestor_id),
                'url' => get_permalink($ancestor_id),
            );
        }

        $items[] = array('name' => get_the_title($post), 'url' => get_permalink($post));
        return $items;
    }

    private function build_breadcrumb_from_categories($post) {
        $items = array();
        $items[] = array('name' => __('Home', 'seo-fury'), 'url' => home_url('/'));

        $categories = get_the_category($post->ID);
        if (!empty($categories)) {
            $category = $categories[0];
            $ancestors = array_reverse(get_ancestors($category->term_id, 'category'));
            foreach ($ancestors as $ancestor_id) {
                $ancestor = get_term($ancestor_id, 'category');
                if ($ancestor && !is_wp_error($ancestor)) {
                    $items[] = array(
                        'name' => $ancestor->name,
                        'url' => get_term_link($ancestor),
                    );
                }
            }
            $items[] = array(
                'name' => $category->name,
                'url' => get_term_link($category),
            );
        }

        $items[] = array('name' => get_the_title($post), 'url' => get_permalink($post));
        return $items;
    }

    public function save_meta($post_id) {
        $items = array();
        if (isset($_POST['seo_fury_schema_items'])) {
            $items_json = wp_unslash($_POST['seo_fury_schema_items']);
            $decoded = json_decode($items_json, true);
            if (is_array($decoded)) {
                $items = $decoded;
            }
        }

        $active_id = isset($_POST['seo_fury_schema_active']) ? sanitize_text_field($_POST['seo_fury_schema_active']) : '';
        $mode = isset($_POST['seo_fury_schema_mode']) ? sanitize_text_field($_POST['seo_fury_schema_mode']) : 'generator';
        $type = isset($_POST['seo_fury_schema_type']) ? sanitize_text_field($_POST['seo_fury_schema_type']) : 'none';
        $custom = isset($_POST['seo_fury_schema_custom']) ? wp_kses_post($_POST['seo_fury_schema_custom']) : '';
        $schema_data = isset($_POST['schema_data']) ? $this->sanitize_schema_data($_POST['schema_data']) : array();

        $active_updated = false;
        foreach ($items as &$item) {
            if (!isset($item['id']) || $item['id'] !== $active_id) {
                continue;
            }
            $active_updated = true;
            break;
        }
        unset($item);

        if (!$active_updated && $active_id) {
            $is_custom_mode = ($mode === 'custom' || $mode === 'custom_builder');
            if (($is_custom_mode && !empty($custom)) || (!$is_custom_mode && !empty($type) && $type !== 'none')) {
                $items[] = array(
                    'id' => $active_id,
                    'mode' => $mode,
                    'type' => $is_custom_mode ? 'custom' : $type,
                    'data' => $is_custom_mode ? array() : $schema_data,
                    'custom' => $is_custom_mode ? $custom : '',
                );
            }
        }

        $active_data = $schema_data;
        foreach ($items as $item) {
            if (isset($item['id']) && $item['id'] === $active_id && !empty($item['data'])) {
                $active_data = $this->sanitize_schema_data($item['data']);
                break;
            }
        }

        update_post_meta($post_id, '_seo_fury_schema_items', $items);
        update_post_meta($post_id, '_seo_fury_schema_active', $active_id);
        update_post_meta($post_id, '_seo_fury_schema_mode', $mode);
        update_post_meta($post_id, '_seo_fury_schema_type', $type);
        update_post_meta($post_id, '_seo_fury_schema_custom', $custom);
        update_post_meta($post_id, '_seo_fury_schema_data', $active_data);
    }

    private function sanitize_schema_data($data) {
        $sanitized = array();
        foreach ($data as $key => $value) {
            if (is_array($value)) {
                $sanitized[$key] = $this->sanitize_schema_data($value);
            } else {
                $sanitized[$key] = sanitize_text_field($value);
            }
        }
        return $sanitized;
    }

    public function output_schema($post) {
        $all_nodes = array();

        // ── Step 1: collect page-specific schema nodes ───────────────────────
        $items = get_post_meta($post->ID, '_seo_fury_schema_items', true);
        if (is_array($items) && !empty($items)) {
            foreach ($items as $item) {
                $mode = $item['mode'] ?? 'generator';
                if ($mode === 'custom' || $mode === 'custom_builder') {
                    $custom_schema = trim((string) ($item['custom'] ?? ''));
                    if ($custom_schema === '') {
                        continue;
                    }
                    // Decode first, THEN resolve %variables% into the decoded
                    // structure. Resolving on the raw JSON string would let a
                    // value containing a quote/backslash corrupt the JSON and
                    // silently drop the whole node. resolve_data() fills values
                    // after parsing; json_encode escapes them safely on output.
                    $decoded = json_decode($custom_schema, true);
                    if (json_last_error() !== JSON_ERROR_NONE || empty($decoded)) {
                        continue;
                    }
                    $decoded = SEO_Fury_Shortcode_Variables::resolve_data($decoded, $post);
                    unset($decoded['@context']);
                    $all_nodes[] = $decoded;
                    continue;
                }

                $schema_type = $item['type'] ?? '';
                if (empty($schema_type) || $schema_type === 'none') {
                    continue;
                }
                $schema_data = $item['data'] ?? array();
                $schema_data = SEO_Fury_Shortcode_Variables::resolve_data($schema_data, $post);
                $schema_json = $this->build_schema_json($schema_type, $schema_data, $post);
                if (!empty($schema_json)) {
                    unset($schema_json['@context']);
                    $all_nodes[] = $schema_json;
                }
            }
        } else {
            // Legacy / fallback path (no items array yet)
            $schema_mode = get_post_meta($post->ID, '_seo_fury_schema_mode', true) ?: 'generator';
            if ($schema_mode === 'custom') {
                $custom_schema = get_post_meta($post->ID, '_seo_fury_schema_custom', true);
                $custom_schema = trim((string) $custom_schema);
                if ($custom_schema !== '') {
                    // Decode first, then resolve into the structure (see note above).
                    $decoded = json_decode($custom_schema, true);
                    if (json_last_error() === JSON_ERROR_NONE && !empty($decoded)) {
                        $decoded = SEO_Fury_Shortcode_Variables::resolve_data($decoded, $post);
                        unset($decoded['@context']);
                        $all_nodes[] = $decoded;
                    }
                }
            } else {
                $schema_type = get_post_meta($post->ID, '_seo_fury_schema_type', true);
                $using_defaults = false;

                if (empty($schema_type) || $schema_type === 'none') {
                    $schema_type = get_option('seo_fury_default_schema_' . $post->post_type, '');
                    $using_defaults = true;
                }

                if (!empty($schema_type) && $schema_type !== 'none') {
                    $schema_data = get_post_meta($post->ID, '_seo_fury_schema_data', true) ?: array();
                    $schema_data = SEO_Fury_Shortcode_Variables::resolve_data($schema_data, $post);

                    if ($using_defaults && $schema_type === 'article') {
                        $pt = $post->post_type;
                        $article_sub_type = get_option('seo_fury_schema_article_type_' . $pt, 'article');
                        if (!empty($article_sub_type) && $article_sub_type !== 'article') {
                            $schema_type = $article_sub_type;
                        }
                        $author_source = get_option('seo_fury_schema_author_source_' . $pt, 'auto');
                        if ($author_source === 'custom') {
                            $custom_author = get_option('seo_fury_schema_author_custom_' . $pt, '');
                            if (!empty($custom_author)) {
                                $schema_data['author'] = $this->apply_schema_template($custom_author, $post);
                            }
                        }
                        $headline_tpl = get_option('seo_fury_schema_headline_' . $pt, '%title%');
                        if (!empty($headline_tpl)) {
                            $schema_data['headline'] = $this->apply_schema_template($headline_tpl, $post);
                        }
                        $desc_tpl = get_option('seo_fury_schema_description_' . $pt, '%excerpt%');
                        if (!empty($desc_tpl)) {
                            $schema_data['description'] = $this->apply_schema_template($desc_tpl, $post);
                        }
                    } elseif ($using_defaults) {
                        $pt = $post->post_type;
                        $headline_tpl = get_option('seo_fury_schema_headline_' . $pt, '%title%');
                        if (!empty($headline_tpl)) {
                            $schema_data['headline'] = $this->apply_schema_template($headline_tpl, $post);
                        }
                        $desc_tpl = get_option('seo_fury_schema_description_' . $pt, '%excerpt%');
                        if (!empty($desc_tpl)) {
                            $schema_data['description'] = $this->apply_schema_template($desc_tpl, $post);
                        }
                    }

                    $schema_json = $this->build_schema_json($schema_type, $schema_data, $post);
                    if (!empty($schema_json)) {
                        unset($schema_json['@context']);
                        $all_nodes[] = $schema_json;
                    }
                }
            }
        }

        // ── Step 2: collect Organization / WebSite graph nodes ───────────────
        $graph_nodes = $this->get_schema_graph_nodes($post);
        foreach ($graph_nodes as $node) {
            $all_nodes[] = $node;
        }

        // ── Step 2b: allow external code to inject extra nodes into the graph ─
        // Third-party plugins and custom code can hook here to merge their
        // schema nodes into the single unified @graph block.
        // Example:
        //   add_filter( 'seo_fury_schema_nodes', function( $nodes, $post ) {
        //       $nodes[] = [ '@type' => 'FAQPage', ... ];
        //       return $nodes;
        //   }, 10, 2 );
        $extra_nodes = apply_filters( 'seo_fury_schema_nodes', array(), $post );
        foreach ( $extra_nodes as $node ) {
            if ( is_array( $node ) && ! empty( $node ) ) {
                unset( $node['@context'] );
                $all_nodes[] = $node;
            }
        }

        // ── Step 2c: allow external code to modify the full node list ────────
        // Unlike seo_fury_schema_nodes (which only appends), this filter
        // receives the complete $all_nodes array and may add, remove, or
        // modify any node — including enriching existing ones (e.g. injecting
        // aggregateRating into a Product node).
        // Example:
        //   add_filter( 'seo_fury_schema_all_nodes', function( $nodes, $post ) {
        //       foreach ( $nodes as $i => $node ) {
        //           if ( isset( $node['@type'] ) && $node['@type'] === 'Product' ) {
        //               $nodes[$i]['aggregateRating'] = [ ... ];
        //           }
        //       }
        //       return $nodes;
        //   }, 10, 2 );
        $all_nodes = apply_filters( 'seo_fury_schema_all_nodes', $all_nodes, $post );

        // ── Step 2d: drop duplicate singleton nodes ──────────────────────────
        // A page should carry only one BreadcrumbList / Organization / WebSite.
        // Duplicates happen when e.g. a generator "breadcrumb" item coexists
        // with the breadcrumb shortcode's injected node. Keep the first of each.
        $singleton_types = array('BreadcrumbList', 'Organization', 'WebSite');
        $seen_singletons = array();
        foreach ($all_nodes as $i => $node) {
            $type = isset($node['@type']) && is_string($node['@type']) ? $node['@type'] : '';
            if ($type !== '' && in_array($type, $singleton_types, true)) {
                if (isset($seen_singletons[$type])) {
                    unset($all_nodes[$i]);
                } else {
                    $seen_singletons[$type] = true;
                }
            }
        }
        $all_nodes = array_values($all_nodes);

        // ── Step 3: output everything as a single unified block ──────────────
        if (empty($all_nodes)) {
            return;
        }

        if (count($all_nodes) === 1) {
            $all_nodes[0]['@context'] = 'https://schema.org';
            echo '<script type="application/ld+json">' . "\n";
            // JSON_HEX_TAG | JSON_HEX_AMP prevent a custom JSON-LD string value
            // containing </script> from breaking out of the block (stored XSS).
            echo json_encode($all_nodes[0], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) . "\n";
            echo '</script>' . "\n";
        } else {
            $graph = array(
                '@context' => 'https://schema.org',
                '@graph'   => $all_nodes,
            );
            echo '<script type="application/ld+json">' . "\n";
            echo json_encode($graph, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) . "\n";
            echo '</script>' . "\n";
        }
    }

    /**
     * Return Organization and/or WebSite schema nodes (without @context) for the given post type.
     * Nodes are merged into the unified @graph by output_schema().
     */
    private function get_schema_graph_nodes($post) {
        $nodes = array();
        $pt    = $post->post_type;

        // Organization schema from Local SEO settings
        if (get_option('seo_fury_schema_graph_organization_' . $pt, 0)) {
            $org_name = get_option('seo_fury_local_name', get_bloginfo('name'));
            if (!empty($org_name)) {
                $org = array(
                    '@type' => 'Organization',
                    // @id lets Article/Product publisher/seller references resolve
                    // to this node instead of dangling.
                    '@id'   => home_url('/#organization'),
                    'name'  => $org_name,
                    'url'   => get_option('seo_fury_local_url', home_url('/')),
                );

                $logo = get_option('seo_fury_local_logo', '');
                if (!empty($logo)) {
                    $org['logo'] = $logo;
                }

                $phone = get_option('seo_fury_local_phone', '');
                if (!empty($phone)) {
                    $org['telephone'] = $phone;
                }

                $email = get_option('seo_fury_local_email', '');
                if (!empty($email)) {
                    $org['email'] = $email;
                }

                $street = get_option('seo_fury_local_street', '');
                $city   = get_option('seo_fury_local_city', '');
                if (!empty($street) || !empty($city)) {
                    $org['address'] = array(
                        '@type'           => 'PostalAddress',
                        'streetAddress'   => $street,
                        'addressLocality' => $city,
                        'addressRegion'   => get_option('seo_fury_local_region', ''),
                        'postalCode'      => get_option('seo_fury_local_postal', ''),
                        'addressCountry'  => get_option('seo_fury_local_country', ''),
                    );
                }

                $nodes[] = $org;
            }
        }

        // WebSite schema
        if (get_option('seo_fury_schema_graph_website_' . $pt, 0)) {
            $website = array(
                '@type' => 'WebSite',
                'name'  => get_bloginfo('name'),
                'url'   => home_url('/'),
                'potentialAction' => array(
                    '@type'       => 'SearchAction',
                    'target'      => home_url('/?s={search_term_string}'),
                    'query-input' => 'required name=search_term_string',
                ),
            );

            $description = get_bloginfo('description');
            if (!empty($description)) {
                $website['description'] = $description;
            }

            $nodes[] = $website;
        }

        return $nodes;
    }

    /**
     * AJAX handler: convert generator schema data → raw JSON-LD structure (shortcodes kept as-is)
     */
    public function ajax_generator_to_json() {
        check_ajax_referer('seo_fury_nonce', 'nonce');

        if (!current_user_can('edit_posts')) {
            wp_send_json_error('Unauthorized');
            return;
        }

        $post_id     = intval($_POST['post_id'] ?? 0);
        $schema_type = sanitize_text_field($_POST['schema_type'] ?? 'none');
        $schema_data = is_array($_POST['schema_data'] ?? null) ? map_deep($_POST['schema_data'], 'sanitize_text_field') : array();

        if ($post_id) {
            if (!current_user_can('edit_post', $post_id)) {
                wp_send_json_error('Unauthorized');
                return;
            }
            $post = get_post($post_id);
            if (!$post) {
                wp_send_json_error('Post not found');
                return;
            }
        } else {
            // Template editor context — use a dummy post so schema builds correctly
            $post                = new stdClass();
            $post->ID            = 0;
            $post->post_title    = '';
            $post->post_author   = 0;
            $post->post_status   = 'publish';
            $post->post_date     = current_time('mysql');
            $post->post_modified = current_time('mysql');
            $post->post_type     = 'post';
            $post->post_content  = '';
            $post->post_excerpt  = '';
            $post->post_name     = '';
            $post->guid          = '';
        }

        // Build JSON-LD without resolving shortcodes so %shortcodes% stay visible in the builder
        $schema = $this->build_schema_json($schema_type, $schema_data, $post);
        wp_send_json_success(array('schema' => $schema));
    }

    /**
     * AJAX handler to get resolved schema preview
     */
    public function ajax_get_schema_preview() {
        check_ajax_referer('seo_fury_nonce', 'nonce');

        if (!current_user_can('edit_posts')) {
            wp_send_json_error(__('Unauthorized', 'seo-fury'));
            return;
        }

        $post_id = intval($_POST['post_id'] ?? 0);
        $schema_type = sanitize_text_field($_POST['schema_type'] ?? 'none');
        $schema_data = is_array($_POST['schema_data'] ?? null) ? map_deep($_POST['schema_data'], 'sanitize_text_field') : array();
        $schema_mode = sanitize_text_field($_POST['mode'] ?? 'generator');
        $custom_json = wp_unslash($_POST['custom_json'] ?? '');
        if ($post_id && !current_user_can('edit_post', $post_id)) {
            wp_send_json_error(__('Unauthorized', 'seo-fury'));
            return;
        }

        $post = $post_id ? get_post($post_id) : null;
        if ($post_id && !$post) {
            wp_send_json_error(__('Post not found', 'seo-fury'));
            return;
        }
        if (!$post) {
            // Template editor context — use a dummy post so shortcodes render as empty strings
            $post          = new stdClass();
            $post->ID      = 0;
            $post->post_title    = '';
            $post->post_author   = 0;
            $post->post_status   = 'publish';
            $post->post_date     = current_time('mysql');
            $post->post_modified = current_time('mysql');
            $post->post_type     = 'post';
            $post->post_content  = '';
            $post->post_excerpt  = '';
            $post->post_name     = '';
            $post->guid          = '';
        }

        // Handle custom/builder modes
        if ($schema_mode === 'custom' || $schema_mode === 'custom_builder') {
            $resolved = SEO_Fury_Shortcode_Variables::resolve($custom_json, $post);
            wp_send_json_success(array('preview' => $resolved));
            return;
        }

        // Handle generator mode - resolve shortcodes in data array
        $resolved_data = SEO_Fury_Shortcode_Variables::resolve_data($schema_data, $post);
        $preview = $this->generate_schema_preview($schema_type, $resolved_data, $post);

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