<?php
/**
 * Name: Custom Post Meta Display
 * Description: View, edit, and delete post metadata on edit pages with organized display by source including core, plugins, and custom fields for development
 * Category: Content
 * Icon: -
 * UseCases: [
 *   {
 *     "title": "Debug Custom Fields",
 *     "description": "Quickly inspect and modify custom field values for posts without using database queries or external plugins."
 *   },
 *   {
 *     "title": "Troubleshoot Plugin Conflicts",
 *     "description": "View all meta fields added by plugins (ACF, Yoast, etc.) to identify conflicts or incorrect data."
 *   },
 *   {
 *     "title": "Bulk Meta Management",
 *     "description": "Copy, edit, or delete post meta fields directly from the post editor for faster content management."
 *   }
 * ]
 * Tags: post, meta, metadata, custom fields, cpt, admin, edit, delete, gutenberg
 * Added: 2025-10-21
 * WhereToFind: {
 *   "location": "Post Editor (Below Content)",
 *   "url": "post.php",
 *   "instructions": "Scroll down to see 'Post Metadata' section with all meta fields",
 *   "newTab": false
 * }
 */

// Prevent direct access
if (!defined('ABSPATH')) exit;

class SwitchboardCustomPostMetaDisplay {

    private $enabled_post_types = [];

    public function __construct() {
        // Load settings
        $settings = get_option('switchboard_custom-post-meta-display_settings', []);
        $enabled = isset($settings['enabled_post_types']) ? $settings['enabled_post_types'] : '';
        // Handle both comma-separated string and array formats
        if (is_string($enabled) && !empty($enabled)) {
            $this->enabled_post_types = array_map('trim', explode(',', $enabled));
        } elseif (is_array($enabled)) {
            $this->enabled_post_types = $enabled;
        } else {
            $this->enabled_post_types = [];
        }

        // Only hook if we have enabled post types
        if (!empty($this->enabled_post_types)) {
            // AJAX handlers
            add_action('wp_ajax_switchboard_update_post_meta', [$this, 'ajax_update_post_meta']);
            add_action('wp_ajax_switchboard_delete_post_meta', [$this, 'ajax_delete_post_meta']);

            // Add meta box to enabled post types
            add_action('add_meta_boxes', [$this, 'add_meta_box']);

            // Enqueue assets for post editor
            add_action('admin_enqueue_scripts', [$this, 'enqueue_assets']);
        }
    }

    public function render_settings($settings = []) {
        // Handle both comma-separated string and array formats
        $enabled = isset($settings['enabled_post_types']) ? $settings['enabled_post_types'] : '';
        if (is_string($enabled) && !empty($enabled)) {
            $enabled_post_types = array_map('trim', explode(',', $enabled));
        } elseif (is_array($enabled)) {
            $enabled_post_types = $enabled;
        } else {
            $enabled_post_types = [];
        }
        $show_hidden = isset($settings['show_hidden']) ? $settings['show_hidden'] : '0';

        // Get all public post types excluding media
        $all_post_types = get_post_types(['public' => true], 'objects');
        $exclude_types = ['attachment', 'wp_block', 'wp_template', 'wp_template_part', 'wp_navigation'];
        $all_post_types = array_diff_key($all_post_types, array_flip($exclude_types));
        ?>
        <input type="hidden" name="module" value="custom-post-meta-display">
        <input type="hidden" name="setting_enabled_post_types" id="setting_enabled_post_types" value="<?php echo esc_attr(implode(',', $enabled_post_types)); ?>">

        <div class="sb-sp-alert sb-sp-alert-info">
            <div class="sb-sp-alert-title"><?php esc_html_e('Custom Post Meta Display', 'wpswitchboard'); ?></div>
            <div class="sb-sp-alert-text">
                <?php esc_html_e('View, edit, and delete post metadata directly from the post edit screen. Select which post types should display the meta box below.', 'wpswitchboard'); ?>
            </div>
        </div>

        <div class="sb-sp-group">
            <label class="sb-sp-label"><?php esc_html_e('Enable for Post Types', 'wpswitchboard'); ?></label>
            <div class="switchboard-tag-selector" data-input-id="setting_enabled_post_types">
                <div class="switchboard-selected-tags" id="selected-post-types">
                    <?php foreach ($enabled_post_types as $pt_slug):
                        if (isset($all_post_types[$pt_slug])): ?>
                            <span class="switchboard-tag" data-value="<?php echo esc_attr($pt_slug); ?>">
                                <?php echo esc_html($all_post_types[$pt_slug]->label); ?>
                                <span class="remove-tag">×</span>
                            </span>
                        <?php endif;
                    endforeach; ?>
                </div>
                <div class="switchboard-available-tags">
                    <?php foreach ($all_post_types as $pt_slug => $pt_obj):
                        $is_selected = in_array($pt_slug, $enabled_post_types) ? 'selected' : ''; ?>
                        <span class="switchboard-tag-option <?php echo esc_attr($is_selected); ?>" data-value="<?php echo esc_attr($pt_slug); ?>">
                            <?php echo esc_html($pt_obj->label); ?>
                        </span>
                    <?php endforeach; ?>
                </div>
            </div>
            <p class="sb-sp-description"><?php esc_html_e('Select which post types should display the meta box. The meta box will appear at the bottom of the post editor.', 'wpswitchboard'); ?></p>
        </div>

        <div class="sb-sp-alert sb-sp-alert-warning">
            <div class="sb-sp-alert-text">
                <strong>Tip:</strong> Select post types that you frequently work with custom fields. The meta box can be collapsed if not needed.
            </div>
        </div>

        <div class="sb-module-option-item sb-module-toggle-item">
            <div class="sb-module-option-content">
                <div class="sb-module-toggle-header">
                    <strong class="sb-module-option-title"><?php esc_html_e('Show Hidden Meta by Default', 'wpswitchboard'); ?></strong>
                    <label class="sb-module-toggle">
                        <input type="checkbox"
                               name="setting_show_hidden"
                               value="1"
                               <?php checked($show_hidden, '1'); ?>>
                        <span class="sb-module-toggle-slider"></span>
                    </label>
                </div>
                <p class="sb-module-option-text"><?php esc_html_e('Meta keys starting with underscore (_) are considered "hidden". Enable this to display them by default.', 'wpswitchboard'); ?></p>
            </div>
        </div>

        <div class="sb-sp-card sb-sp-p-4">
            <h4 class="sb-sp-heading-sm sb-sp-mb-3">Features</h4>
            <ul class="sb-sp-list">
                <li class="sb-sp-list-item"><strong>Categorized Display:</strong> Meta fields are grouped into WordPress Core, Plugins, and Custom categories</li>
                <li class="sb-sp-list-item"><strong>Inline Editing:</strong> Click the edit button to modify meta values directly</li>
                <li class="sb-sp-list-item"><strong>Search & Filter:</strong> Quickly find specific meta keys or values using the search box</li>
                <li class="sb-sp-list-item"><strong>Copy to Clipboard:</strong> One-click copy functionality for meta values</li>
                <li class="sb-sp-list-item"><strong>Protected Fields:</strong> Core WordPress meta fields are protected from deletion</li>
                <li class="sb-sp-list-item"><strong>Gutenberg Compatible:</strong> Works seamlessly with both Classic and Block editors</li>
            </ul>
        </div>
        <?php
    }

    /**
     * Enqueue assets only on post edit screens
     */
    public function enqueue_assets($hook) {
        // Only load on post.php and post-new.php
        if (!in_array($hook, ['post.php', 'post-new.php'])) {
            return;
        }

        // Check if current post type is enabled
        global $post;
        if (!$post || !in_array($post->post_type, $this->enabled_post_types)) {
            return;
        }

        // Add inline styles
        add_action('admin_head', [$this, 'add_inline_styles']);
    }

    /**
     * AJAX handler to update post meta
     */
    public function ajax_update_post_meta() {
        check_ajax_referer('switchboard_post_meta', 'nonce');

        if (!current_user_can('edit_posts')) {
            wp_send_json_error(['message' => esc_html__('Unauthorized', 'wpswitchboard')]);
        }

        $post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
        $meta_key = isset($_POST['meta_key']) ? sanitize_text_field(wp_unslash($_POST['meta_key'])) : '';
        $meta_value = isset($_POST['meta_value']) ? sanitize_text_field(wp_unslash($_POST['meta_value'])) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized via sanitize_text_field

        if (!$post_id || !$meta_key) {
            wp_send_json_error(['message' => esc_html__('Invalid parameters', 'wpswitchboard')]);
        }

        // Check if post exists
        if (!get_post($post_id)) {
            wp_send_json_error(['message' => 'Post not found']);
        }

        // Check permission to edit this post
        if (!current_user_can('edit_post', $post_id)) {
            wp_send_json_error(['message' => 'Unauthorized to edit this post']);
        }

        // Try to detect if the value should be unserialized/JSON
        $decoded = json_decode($meta_value, true);
        if (json_last_error() === JSON_ERROR_NONE) {
            $meta_value = $decoded;
        }

        update_post_meta($post_id, $meta_key, $meta_value);

        wp_send_json_success(['message' => esc_html__('Meta updated successfully', 'wpswitchboard')]);
    }

    /**
     * AJAX handler to delete post meta
     */
    public function ajax_delete_post_meta() {
        check_ajax_referer('switchboard_post_meta', 'nonce');

        if (!current_user_can('edit_posts')) {
            wp_send_json_error(['message' => esc_html__('Unauthorized', 'wpswitchboard')]);
        }

        $post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
        $meta_key = isset($_POST['meta_key']) ? sanitize_text_field(wp_unslash($_POST['meta_key'])) : '';

        if (!$post_id || !$meta_key) {
            wp_send_json_error(['message' => esc_html__('Invalid parameters', 'wpswitchboard')]);
        }

        // Check permission to edit this post
        if (!current_user_can('edit_post', $post_id)) {
            wp_send_json_error(['message' => 'Unauthorized to edit this post']);
        }

        // Prevent deletion of critical meta keys
        $protected_keys = $this->get_protected_meta_keys();

        if (in_array($meta_key, $protected_keys)) {
            wp_send_json_error(['message' => esc_html__('Cannot delete protected meta key', 'wpswitchboard')]);
        }

        delete_post_meta($post_id, $meta_key);

        wp_send_json_success(['message' => esc_html__('Meta deleted successfully', 'wpswitchboard')]);
    }

    /**
     * Add meta box to enabled post types
     */
    public function add_meta_box() {
        foreach ($this->enabled_post_types as $post_type) {
            add_meta_box(
                'switchboard_post_meta_display',
                'Post Metadata <span class="switchboard-badge">SWITCHBOARD</span>',
                [$this, 'render_meta_box'],
                $post_type,
                'normal',
                'low'
            );
        }
    }

    /**
     * Render the meta box content
     */
    public function render_meta_box($post) {
        if (!current_user_can('edit_posts')) {
            return;
        }

        // Get all post meta
        global $wpdb;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Need all meta keys for display
        $meta_data = $wpdb->get_results($wpdb->prepare(
            "SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id = %d ORDER BY meta_key ASC",
            $post->ID
        ), ARRAY_A);

        if (empty($meta_data)) {
            echo '<p>No metadata found for this post.</p>';
            return;
        }

        // Categorize meta fields
        $categorized = $this->categorize_meta_fields($meta_data);

        $settings = get_option('switchboard_custom-post-meta-display_settings', []);
        $show_hidden = isset($settings['show_hidden']) && $settings['show_hidden'] === '1';

        ?>
        <div class="switchboard-post-meta-wrapper">
            <div class="switchboard-meta-search-box">
                <input type="text" id="post-meta-search" placeholder="Search meta keys or values..." class="sb-sp-input">
                <button type="button" class="button" id="toggle-hidden-meta">
                    <?php echo $show_hidden ? 'Hide' : 'Show'; ?> Hidden Meta
                </button>
                <button type="button" class="button button-primary" id="add-new-meta-btn">
                    + Add New Meta Field
                </button>
            </div>

            <!-- Add New Meta Form (initially hidden) -->
            <div id="add-meta-form" class="add-meta-form" style="display: none;">
                <h4 class="sb-sp-heading-sm">Add New Meta Field</h4>
                <div class="add-meta-fields">
                    <div class="add-meta-field">
                        <label for="new-meta-key">Meta Key *</label>
                        <input type="text" id="new-meta-key" placeholder="my_custom_field" class="sb-sp-input">
                    </div>
                    <div class="add-meta-field">
                        <label for="new-meta-value">Meta Value</label>
                        <textarea id="new-meta-value" placeholder="Enter meta value..." rows="3" class="sb-sp-textarea"></textarea>
                        <p class="sb-sp-description">For arrays/objects, use JSON format</p>
                    </div>
                </div>
                <div class="add-meta-actions">
                    <button type="button" class="button button-primary" id="save-new-meta-btn">Save Meta Field</button>
                    <button type="button" class="button" id="cancel-new-meta-btn">Cancel</button>
                </div>
            </div>

            <div class="switchboard-meta-categories">
                <?php foreach ($categorized as $category => $fields): ?>
                    <?php if (!empty($fields)): ?>
                        <div class="meta-category" data-category="<?php echo esc_attr($category); ?>">
                            <h4 class="meta-category-header">
                                <span class="category-toggle">▼</span>
                                <span class="category-name"><?php echo esc_html($category); ?></span>
                                <span class="category-count">(<?php echo count($fields); ?> fields)</span>
                            </h4>
                            <div class="meta-category-content">
                                <?php foreach ($fields as $meta): ?>
                                    <?php
                                    $key = $meta['meta_key'];
                                    $is_hidden = strpos($key, '_') === 0;
                                    $value = maybe_unserialize($meta['meta_value']);

                                    // Format value
                                    if (is_array($value) || is_object($value)) {
                                        $display_value = json_encode($value, JSON_PRETTY_PRINT);
                                        $value_class = 'meta-value-complex';
                                    } else {
                                        $display_value = esc_html($value);
                                        $value_class = 'meta-value-simple';
                                    }

                                    $row_class = $is_hidden ? 'meta-row meta-hidden' : 'meta-row';
                                    $protected_keys = $this->get_protected_meta_keys();
                                    $is_protected = in_array($key, $protected_keys);
                                    ?>
                                    <div class="<?php echo esc_attr($row_class); ?>"
                                         data-key="<?php echo esc_attr($key); ?>"
                                         data-value="<?php echo esc_attr($value); ?>"
                                         data-post-id="<?php echo esc_attr($post->ID); ?>"
                                         data-category="<?php echo esc_attr($category); ?>">
                                        <div class="meta-key">
                                            <?php if ($is_hidden): ?>
                                                <span class="meta-hidden-badge">Hidden</span>
                                            <?php endif; ?>
                                            <?php if ($is_protected): ?>
                                                <span class="meta-protected-badge">Protected</span>
                                            <?php endif; ?>
                                            <code><?php echo esc_html($key); ?></code>
                                        </div>
                                        <div class="meta-value <?php echo esc_attr($value_class); ?>">
                                            <pre class="meta-display"><?php echo esc_html($display_value); ?></pre>
                                            <div class="meta-edit-wrapper" style="display: none;">
                                                <textarea class="meta-edit"><?php echo esc_textarea(is_array($value) || is_object($value) ? json_encode($value, JSON_PRETTY_PRINT) : $value); ?></textarea>
                                                <span class="meta-edit-hint">Press <kbd>Esc</kbd> to cancel, <kbd>Ctrl/Cmd+Enter</kbd> to save</span>
                                            </div>
                                            <div class="meta-actions">
                                                <button type="button" class="button button-small copy-meta-btn"
                                                        data-value="<?php echo esc_attr(is_array($value) || is_object($value) ? json_encode($value) : $value); ?>"
                                                        title="Copy value">
                                                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                                        <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
                                                        <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
                                                    </svg>
                                                </button>
                                                <button type="button" class="button button-small edit-meta-btn" title="Edit">
                                                    Edit
                                                </button>
                                                <?php if (!$is_protected): ?>
                                                <button type="button" class="button button-small delete-meta-btn" title="Delete">
                                                    Delete
                                                </button>
                                                <?php endif; ?>
                                            </div>
                                        </div>
                                    </div>
                                <?php endforeach; ?>
                            </div>
                        </div>
                    <?php endif; ?>
                <?php endforeach; ?>
            </div>

            <div class="meta-stats">
                <span>Core: <strong><?php echo count($categorized['WordPress Core']); ?></strong></span>
                <span>Plugins: <strong><?php echo count($categorized['Plugins']); ?></strong></span>
                <span>Custom: <strong><?php echo count($categorized['Custom']); ?></strong></span>
                <span>Total: <strong><?php echo count($meta_data); ?></strong></span>
            </div>
        </div>

        <script>
        jQuery(document).ready(function($) {
            const nonce = '<?php echo esc_attr(wp_create_nonce('switchboard_post_meta')); ?>';

            // Category toggle
            $('.meta-category-header').on('click', function() {
                const $category = $(this).closest('.meta-category');
                const $content = $category.find('.meta-category-content');
                const $toggle = $(this).find('.category-toggle');

                $content.slideToggle(200, function() {
                    // Update arrow after animation completes
                    $toggle.text($content.is(':visible') ? '▼' : '▶');
                });
            });

            // Search functionality
            $('#post-meta-search').on('keyup', function() {
                var searchTerm = $(this).val().toLowerCase();

                if (searchTerm === '') {
                    $('.meta-row').show();
                    $('.meta-category').show();
                    return;
                }

                $('.meta-row').each(function() {
                    var key = $(this).data('key').toLowerCase();
                    var value = $(this).data('value').toString().toLowerCase();

                    if (key.includes(searchTerm) || value.includes(searchTerm)) {
                        $(this).show();
                    } else {
                        $(this).hide();
                    }
                });

                // Hide empty categories
                $('.meta-category').each(function() {
                    var visibleRows = $(this).find('.meta-row:visible').length;
                    if (visibleRows === 0) {
                        $(this).hide();
                    } else {
                        $(this).show();
                    }
                });
            });

            // Copy meta value
            $('.copy-meta-btn').on('click', function() {
                var value = $(this).data('value');
                var textarea = document.createElement('textarea');
                textarea.value = value;
                document.body.appendChild(textarea);
                textarea.select();
                document.execCommand('copy');
                document.body.removeChild(textarea);

                var btn = $(this);
                var originalIcon = btn.html();
                btn.html('<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"></polyline></svg>');
                btn.css('color', '#16a34a');
                setTimeout(function() {
                    btn.html(originalIcon);
                    btn.css('color', '');
                }, 1500);
            });

            // Edit meta value
            $('.edit-meta-btn').on('click', function() {
                var $row = $(this).closest('.meta-row');
                var $display = $row.find('.meta-display');
                var $editWrapper = $row.find('.meta-edit-wrapper');
                var $edit = $row.find('.meta-edit');
                var $btn = $(this);

                if ($editWrapper.is(':visible')) {
                    // Save mode
                    saveMetaEdit($row);
                } else {
                    // Edit mode - store original value
                    $row.data('original-value', $edit.val());
                    $display.hide();
                    $editWrapper.show();
                    $edit.focus();
                    $btn.html('Save').attr('title', 'Save');
                }
            });

            // Handle ESC and Enter keys in edit mode
            $(document).on('keydown', '.meta-edit', function(e) {
                var $edit = $(this);
                var $row = $edit.closest('.meta-row');
                var $display = $row.find('.meta-display');
                var $editWrapper = $row.find('.meta-edit-wrapper');
                var $btn = $row.find('.edit-meta-btn');

                if (e.key === 'Escape') {
                    // Cancel edit - revert to original value
                    e.preventDefault();
                    var originalValue = $row.data('original-value');
                    $edit.val(originalValue);
                    $editWrapper.hide();
                    $display.show();
                    $btn.html('Edit').attr('title', 'Edit');
                } else if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
                    // Save with Ctrl/Cmd + Enter
                    e.preventDefault();
                    saveMetaEdit($row);
                }
            });

            // Save meta edit function
            function saveMetaEdit($row) {
                var $display = $row.find('.meta-display');
                var $editWrapper = $row.find('.meta-edit-wrapper');
                var $edit = $row.find('.meta-edit');
                var $btn = $row.find('.edit-meta-btn');
                var postId = $row.data('post-id');
                var metaKey = $row.data('key');
                var metaValue = $edit.val();

                $btn.prop('disabled', true).html('...');

                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'switchboard_update_post_meta',
                        nonce: nonce,
                        post_id: postId,
                        meta_key: metaKey,
                        meta_value: metaValue
                    },
                    success: function(response) {
                        if (response.success) {
                            $display.text(metaValue).show();
                            $editWrapper.hide();
                            $btn.html('Edit').attr('title', 'Edit').prop('disabled', false);
                            showNotice('Meta updated successfully', 'success');
                        } else {
                            alert('Error: ' + response.data.message);
                            $btn.html('Save').attr('title', 'Save').prop('disabled', false);
                        }
                    },
                    error: function() {
                        alert('Error updating meta. Please try again.');
                        $btn.html('Save').attr('title', 'Save').prop('disabled', false);
                    }
                });
            }

            // Delete meta value
            $('.delete-meta-btn').on('click', function() {
                var $row = $(this).closest('.meta-row');
                var postId = $row.data('post-id');
                var metaKey = $row.data('key');

                if (!confirm('Are you sure you want to delete the meta key "' + metaKey + '"?')) {
                    return;
                }

                var $btn = $(this);
                $btn.prop('disabled', true).html('...');

                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'switchboard_delete_post_meta',
                        nonce: nonce,
                        post_id: postId,
                        meta_key: metaKey
                    },
                    success: function(response) {
                        if (response.success) {
                            $row.fadeOut(300, function() {
                                $(this).remove();
                                updateCategoryCounts(true); // Hide empty categories after deletion
                            });
                            showNotice('Meta deleted successfully', 'success');
                        } else {
                            alert('Error: ' + response.data.message);
                            $btn.html('Delete').prop('disabled', false);
                        }
                    },
                    error: function() {
                        alert('Error deleting meta. Please try again.');
                        $btn.html('Delete').prop('disabled', false);
                    }
                });
            });

            // Toggle hidden meta
            var hiddenMetaVisible = <?php echo $show_hidden ? 'true' : 'false'; ?>;

            $('#toggle-hidden-meta').on('click', function() {
                var $btn = $(this);
                var $hiddenRows = $('.meta-hidden');

                // Toggle the state
                hiddenMetaVisible = !hiddenMetaVisible;

                // Show or hide based on new state
                if (hiddenMetaVisible) {
                    $hiddenRows.show();
                    $btn.text('Hide Hidden Meta');
                } else {
                    $hiddenRows.hide();
                    $btn.text('Show Hidden Meta');
                }

                updateCategoryCounts(true); // Hide empty categories when toggling
            });

            // Update category counts after deletion or toggle
            function updateCategoryCounts(hideEmptyCategories) {
                hideEmptyCategories = hideEmptyCategories !== undefined ? hideEmptyCategories : false;

                $('.meta-category').each(function() {
                    var count = $(this).find('.meta-row:visible').length;
                    $(this).find('.category-count').text('(' + count + ' fields)');

                    if (hideEmptyCategories) {
                        if (count === 0) {
                            $(this).hide();
                        } else {
                            $(this).show();
                        }
                    }
                });
            }

            // Show notice helper
            function showNotice(message, type) {
                var $notice = $('<div class="notice notice-' + type + ' is-dismissible"><p>' + message + '</p></div>');
                $('.switchboard-post-meta-wrapper').prepend($notice);
                setTimeout(function() {
                    $notice.fadeOut(300, function() {
                        $(this).remove();
                    });
                }, 3000);
            }

            // Add New Meta Field handlers
            $('#add-new-meta-btn').on('click', function() {
                $('#add-meta-form').slideDown(200);
                $('#new-meta-key').focus();
            });

            $('#cancel-new-meta-btn').on('click', function() {
                $('#add-meta-form').slideUp(200);
                $('#new-meta-key').val('');
                $('#new-meta-value').val('');
            });

            $('#save-new-meta-btn').on('click', function() {
                var $btn = $(this);
                var metaKey = $('#new-meta-key').val().trim();
                var metaValue = $('#new-meta-value').val();
                var postId = <?php echo esc_attr($post->ID); ?>;

                if (!metaKey) {
                    alert('Please enter a meta key');
                    return;
                }

                $btn.prop('disabled', true).text('Saving...');

                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'switchboard_update_post_meta',
                        nonce: nonce,
                        post_id: postId,
                        meta_key: metaKey,
                        meta_value: metaValue
                    },
                    success: function(response) {
                        if (response.success) {
                            showNotice('Meta field added successfully! Refreshing...', 'success');
                            setTimeout(function() {
                                location.reload();
                            }, 1000);
                        } else {
                            alert('Error: ' + response.data.message);
                            $btn.prop('disabled', false).text('Save Meta Field');
                        }
                    },
                    error: function() {
                        alert('Error adding meta field. Please try again.');
                        $btn.prop('disabled', false).text('Save Meta Field');
                    }
                });
            });

            // Initialize: Show hidden meta if setting is enabled and update counts
            <?php if ($show_hidden): ?>
            $('.meta-hidden').show();
            <?php endif; ?>
            updateCategoryCounts(false); // Don't hide categories on initial load, just update counts
        });
        </script>
        <?php
    }

    /**
     * Categorize meta fields into Core, Plugins, and Custom
     */
    private function categorize_meta_fields($meta_data) {
        $categories = [
            'WordPress Core' => [],
            'Plugins' => [],
            'Custom' => []
        ];

        // Known WordPress core meta keys patterns
        $core_patterns = [
            '_edit_',
            '_wp_',
            '_thumbnail_id',
            '_encloseme',
            '_pingme',
            '_trackbackme'
        ];

        // Known plugin prefixes
        $plugin_prefixes = [
            '_yoast_',
            '_aioseop_',
            '_rank_math_',
            '_acf_',
            '_wc_',
            '_edd_',
            '_elementor_',
            '_wpb_',
            '_beaver_',
            '_et_pb_',
            '_genesis_',
            '_seopress_',
            '_aioseo_'
        ];

        foreach ($meta_data as $meta) {
            $key = $meta['meta_key'];
            $categorized = false;

            // Check if it's a core meta key
            foreach ($core_patterns as $pattern) {
                if (strpos($key, $pattern) !== false) {
                    $categories['WordPress Core'][] = $meta;
                    $categorized = true;
                    break;
                }
            }

            if ($categorized) continue;

            // Check if it's a plugin meta key
            foreach ($plugin_prefixes as $prefix) {
                if (strpos($key, $prefix) !== false) {
                    $categories['Plugins'][] = $meta;
                    $categorized = true;
                    break;
                }
            }

            if ($categorized) continue;

            // Everything else is custom
            $categories['Custom'][] = $meta;
        }

        return $categories;
    }

    /**
     * Get list of protected meta keys that cannot be deleted
     */
    private function get_protected_meta_keys() {
        return [
            '_edit_lock',
            '_edit_last',
            '_wp_page_template',
            '_thumbnail_id',
            '_wp_attached_file',
            '_wp_attachment_metadata',
            '_menu_item_type',
            '_menu_item_menu_item_parent',
            '_menu_item_object_id',
            '_menu_item_object',
            '_menu_item_target',
            '_menu_item_classes',
            '_menu_item_xfn',
            '_menu_item_url'
        ];
    }

    /**
     * Add inline styles
     */
    public function add_inline_styles() {
        ?>
        <style>
        .switchboard-badge {
            display: inline-block;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            font-size: 10px;
            padding: 3px 8px;
            border-radius: 3px;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.5px;
            margin-left: 8px;
        }

        .switchboard-post-meta-wrapper {
            margin: 16px 0;
        }

        .switchboard-meta-search-box {
            display: flex;
            gap: 10px;
            margin-bottom: 16px;
            align-items: center;
        }

        .switchboard-meta-search-box input {
            flex: 1;
            max-width: 400px;
        }

        .add-meta-form {
            background: var(--primary-50);
            border: 2px solid #2271b1;
            border-radius: 4px;
            padding: 16px;
            margin-bottom: 16px;
        }

        .add-meta-form h4 {
            color: #1d2327;
            font-size: 14px;
            font-weight: 600;
        }

        .add-meta-fields {
            display: flex;
            gap: 16px;
            margin-bottom: 16px;
        }

        .add-meta-field {
            flex: 1;
        }

        .add-meta-field label {
            display: block;
            font-weight: 500;
            margin-bottom: 6px;
            color: #1d2327;
            font-size: 13px;
        }

        .add-meta-field input,
        .add-meta-field textarea {
            width: 100%;
            box-sizing: border-box;
        }

        .add-meta-actions {
            display: flex;
            gap: 8px;
        }

        .switchboard-meta-categories {
            background: #f9f9f9;
            border: 1px solid #ddd;
            border-radius: 4px;
            overflow: hidden;
        }

        .meta-category {
            border-bottom: 1px solid #ddd;
        }

        .meta-category:last-child {
            border-bottom: none;
        }

        .meta-category-header {
            margin: 0;
            padding: 12px 16px;
            background: #fff;
            border-bottom: 1px solid #e5e5e5;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 8px;
            font-size: 14px;
            font-weight: 600;
            color: #1d2327;
            user-select: none;
        }

        .meta-category-header:hover {
            background: var(--primary-50);
        }

        .category-toggle {
            font-size: 12px;
            color: #666;
            transition: transform 0.2s;
        }

        .category-name {
            flex: 1;
        }

        .category-count {
            font-size: 12px;
            font-weight: 400;
            color: #666;
        }

        .meta-category-content {
            background: #fff;
        }

        .meta-row {
            display: flex;
            gap: 20px;
            padding: 12px 16px;
            border-bottom: 1px solid #f0f0f0;
            align-items: flex-start;
        }

        .meta-row:last-child {
            border-bottom: none;
        }

        .meta-row:hover {
            background: #f8fafc;
        }

        .meta-key {
            flex: 0 0 250px;
            font-weight: 500;
            word-break: break-word;
        }

        .meta-key code {
            background: #f3f4f6;
            padding: 4px 8px;
            border-radius: 3px;
            font-size: 12px;
            display: inline-block;
        }

        .meta-hidden-badge {
            display: inline-block;
            background: #fbbf24;
            color: #78350f;
            font-size: 10px;
            padding: 2px 6px;
            border-radius: 3px;
            margin-right: 6px;
            font-weight: 600;
            text-transform: uppercase;
        }

        .meta-protected-badge {
            display: inline-block;
            background: var(--primary-100);
            color: var(--primary-900);
            font-size: 10px;
            padding: 2px 6px;
            border-radius: 3px;
            margin-right: 6px;
            font-weight: 600;
            text-transform: uppercase;
        }

        .meta-value {
            flex: 1;
            position: relative;
            display: flex;
            gap: 10px;
            align-items: flex-start;
        }

        .meta-value pre {
            margin: 0;
            padding: 8px;
            background: #1f2937;
            color: #f9fafb;
            border-radius: 4px;
            font-size: 12px;
            max-width: 100%;
            overflow-x: auto;
            flex: 1;
            max-height: 200px;
            overflow-y: auto;
        }

        .meta-value-simple pre {
            background: transparent;
            color: #374151;
            padding: 0;
            font-family: inherit;
        }

        .meta-edit-wrapper {
            flex: 1;
            display: flex;
            flex-direction: column;
            gap: 8px;
        }

        .meta-value textarea.meta-edit {
            width: 100%;
            min-height: 80px;
            max-height: 300px;
            padding: 8px;
            font-family: monospace;
            font-size: 12px;
            border: 2px solid #2271b1;
            border-radius: 4px;
            resize: vertical;
            box-sizing: border-box;
        }

        .meta-edit-hint {
            font-size: 11px;
            color: #6b7280;
        }

        .meta-edit-hint kbd {
            display: inline-block;
            padding: 2px 6px;
            background: #f3f4f6;
            border: 1px solid #d1d5db;
            border-radius: 3px;
            font-family: monospace;
            font-size: 10px;
            font-weight: 600;
            box-shadow: 0 1px 2px rgba(0,0,0,0.05);
        }

        .meta-actions {
            display: flex;
            gap: 4px;
            flex-shrink: 0;
        }

        .meta-actions .button {
            padding: 4px 8px;
            height: auto;
            line-height: 1.4;
            font-size: 14px;
            min-width: 32px;
            border-radius: 3px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            transition: all 0.2s ease;
        }

        .meta-actions .button svg {
            display: block;
        }

        .meta-actions .copy-meta-btn:hover {
            background: var(--primary-50);
            border-color: #2271b1;
            color: #2271b1;
        }

        .meta-actions .edit-meta-btn:hover {
            background: #fef3c7;
            border-color: #f59e0b;
        }

        .meta-actions .delete-meta-btn:hover {
            background: #fef2f2;
            border-color: #dc2626;
            color: #dc2626;
        }

        .meta-stats {
            display: flex;
            gap: 20px;
            padding: 12px 16px;
            background: #f3f4f6;
            border-radius: 0 0 4px 4px;
            font-size: 13px;
            color: #6b7280;
        }

        .meta-stats strong {
            color: #1f2937;
        }

        .meta-hidden {
            display: none;
        }

        /* Gutenberg-specific adjustments */
        .block-editor-page .switchboard-post-meta-wrapper {
            background: white;
            padding: 16px;
            border-radius: 2px;
        }
        </style>
        <?php
    }

    /**
     * Register data locations for cleanup system
     */
    public function register_data_locations() {
        // This module displays/edits existing post meta, doesn't store its own data
        return [
            'options' => [
                'switchboard_custom-post-meta-display_settings',
            ],
            'option_patterns' => [],
            'tables' => [],
            'post_meta' => [],
            'user_meta' => [],
        ];
    }
}

$switchboard_instance = new SwitchboardCustomPostMetaDisplay();
Switchboard_Data_Registry::get_instance()->auto_register($switchboard_instance, __FILE__);
