<?php
declare(strict_types=1);

namespace Help4BuilderSuite\Modules\Insights;

use Help4BuilderSuite\Contracts\ModuleContract;
use Help4BuilderSuite\Support\Settings;
use WP_Post;
use WP_REST_Request;
use WP_REST_Response;

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

final class Module implements ModuleContract
{
    private const OPTION_REPORT = 'h4bs_latest_insights_report';
    private const CRON_HOOK = 'h4bs_run_scheduled_insights';

    public function key(): string
    {
        return 'insights';
    }

    public function boot(): void
    {
        add_action('admin_menu', [$this, 'registerAdminPage']);
        add_action('rest_api_init', [$this, 'registerRestRoutes']);
        add_action('wp_ajax_h4bs_insights_run_report', [$this, 'ajaxRunReport']);
        add_action(self::CRON_HOOK, [$this, 'scheduledRun']);

        if (defined('WP_CLI') && WP_CLI && class_exists('\WP_CLI')) {
            \WP_CLI::add_command('h4bs migrate', MigrationRunnerCommand::class);
        }

        if (! wp_next_scheduled(self::CRON_HOOK)) {
            wp_schedule_event(time() + 600, 'hourly', self::CRON_HOOK);
        }
    }

    public function registerAdminPage(): void
    {
        add_submenu_page(
            'h4bs-settings',
            __('Insights and Speed', 'help4-builder-suite'),
            __('Insights and Speed', 'help4-builder-suite'),
            'manage_options',
            'h4bs-insights',
            [$this, 'renderAdminPage']
        );

        add_submenu_page(
            'h4bs-settings',
            __('Shortcode Registry', 'help4-builder-suite'),
            __('Shortcode Registry', 'help4-builder-suite'),
            'manage_options',
            'h4bs-shortcode-registry',
            [$this, 'renderShortcodeRegistryPage']
        );
    }

    public function registerRestRoutes(): void
    {
        register_rest_route(
            'h4bs/v1',
            '/insights/report',
            [
                'methods'             => 'GET',
                'callback'            => [$this, 'reportRoute'],
                'permission_callback' => static fn (): bool => current_user_can('manage_options'),
            ]
        );

        register_rest_route(
            'h4bs/v1',
            '/insights/run',
            [
                'methods'             => 'POST',
                'callback'            => [$this, 'runRoute'],
                'permission_callback' => static fn (): bool => current_user_can('manage_options'),
            ]
        );

        register_rest_route(
            'h4bs/v1',
            '/insights/page-estimate/(?P<id>\d+)',
            [
                'methods'             => 'GET',
                'callback'            => [$this, 'pageEstimateRoute'],
                'permission_callback' => static fn (WP_REST_Request $request): bool => current_user_can('edit_post', (int) $request->get_param('id')),
            ]
        );

        register_rest_route(
            'h4bs/v1',
            '/insights/shortcodes',
            [
                'methods'             => 'GET',
                'callback'            => [$this, 'shortcodeRegistryRoute'],
                'permission_callback' => static fn (): bool => current_user_can('manage_options'),
            ]
        );
    }

    public function reportRoute(): WP_REST_Response
    {
        return new WP_REST_Response($this->latestReport());
    }

    public function runRoute(): WP_REST_Response
    {
        return new WP_REST_Response($this->runFullReport());
    }

    public function pageEstimateRoute(WP_REST_Request $request): WP_REST_Response
    {
        $postId = (int) $request->get_param('id');
        $post = get_post($postId);
        if (! $post instanceof WP_Post) {
            return new WP_REST_Response(['message' => 'Post not found'], 404);
        }
        return new WP_REST_Response($this->estimatePost($post));
    }

    public function shortcodeRegistryRoute(): WP_REST_Response
    {
        return new WP_REST_Response(
            [
                'generated_at' => gmdate('Y-m-d H:i:s') . ' UTC',
                'reserved' => $this->shortcodeRegistryRows(),
                'third_party_h4' => $this->thirdPartyH4Shortcodes(),
            ]
        );
    }

    public function ajaxRunReport(): void
    {
        if (! current_user_can('manage_options')) {
            wp_send_json_error(['message' => 'Unauthorized'], 403);
        }
        check_ajax_referer('h4bs_insights_run', 'nonce');

        $report = $this->runFullReport();
        wp_send_json_success($report);
    }

    public function scheduledRun(): void
    {
        $this->runFullReport();
    }

    public function renderAdminPage(): void
    {
        if (! current_user_can('manage_options')) {
            return;
        }

        $report = $this->latestReport();
        $moduleTests = is_array($report['module_tests'] ?? null) ? $report['module_tests'] : [];
        $pageEstimates = is_array($report['page_estimates'] ?? null) ? $report['page_estimates'] : [];
        $summary = is_array($report['summary'] ?? null) ? $report['summary'] : [];
        $nonce = wp_create_nonce('h4bs_insights_run');
        ?>
        <div class="wrap h4bs-admin-wrap">
            <h1><?php esc_html_e('Help4 Insights and Speed Reports', 'help4-builder-suite'); ?></h1>
            <p><?php esc_html_e('Automatic module tests and estimated load forecasts. Run this after major builder/template changes.', 'help4-builder-suite'); ?></p>
            <p>
                <button id="h4bs-run-report" class="button button-primary"><?php esc_html_e('Run Report Now', 'help4-builder-suite'); ?></button>
                <span id="h4bs-run-status" style="margin-left:8px;"></span>
            </p>

            <h2><?php esc_html_e('Summary', 'help4-builder-suite'); ?></h2>
            <table class="widefat striped">
                <tbody>
                    <tr><th><?php esc_html_e('Generated', 'help4-builder-suite'); ?></th><td><?php echo esc_html((string) ($report['generated_at'] ?? 'Never')); ?></td></tr>
                    <tr><th><?php esc_html_e('Modules Passed', 'help4-builder-suite'); ?></th><td><?php echo esc_html((string) ($summary['modules_passed'] ?? '0')); ?></td></tr>
                    <tr><th><?php esc_html_e('Modules Checked', 'help4-builder-suite'); ?></th><td><?php echo esc_html((string) ($summary['modules_checked'] ?? '0')); ?></td></tr>
                    <tr><th><?php esc_html_e('Pages Estimated', 'help4-builder-suite'); ?></th><td><?php echo esc_html((string) ($summary['pages_estimated'] ?? '0')); ?></td></tr>
                    <tr><th><?php esc_html_e('Average Estimated Load', 'help4-builder-suite'); ?></th><td><?php echo esc_html((string) ($summary['avg_estimated_load_ms'] ?? '0')); ?> ms</td></tr>
                    <tr><th><?php esc_html_e('Slowest Estimated Page', 'help4-builder-suite'); ?></th><td><?php echo esc_html((string) ($summary['slowest_page'] ?? '-')); ?></td></tr>
                </tbody>
            </table>

            <h2><?php esc_html_e('Module Test Results', 'help4-builder-suite'); ?></h2>
            <table class="widefat striped">
                <thead>
                <tr>
                    <th><?php esc_html_e('Module', 'help4-builder-suite'); ?></th>
                    <th><?php esc_html_e('Status', 'help4-builder-suite'); ?></th>
                    <th><?php esc_html_e('Duration (ms)', 'help4-builder-suite'); ?></th>
                    <th><?php esc_html_e('Details', 'help4-builder-suite'); ?></th>
                </tr>
                </thead>
                <tbody>
                <?php foreach ($moduleTests as $row) : ?>
                    <?php if (! is_array($row)) { continue; } ?>
                    <tr>
                        <td><?php echo esc_html((string) ($row['module'] ?? '')); ?></td>
                        <td><?php echo esc_html(strtoupper((string) ($row['status'] ?? 'unknown'))); ?></td>
                        <td><?php echo esc_html((string) ($row['duration_ms'] ?? '0')); ?></td>
                        <td><?php echo esc_html((string) ($row['details'] ?? '')); ?></td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>

            <h2><?php esc_html_e('Estimated Page Loads', 'help4-builder-suite'); ?></h2>
            <table class="widefat striped">
                <thead>
                <tr>
                    <th><?php esc_html_e('Page', 'help4-builder-suite'); ?></th>
                    <th><?php esc_html_e('Estimated Load (ms)', 'help4-builder-suite'); ?></th>
                    <th><?php esc_html_e('Estimated Requests', 'help4-builder-suite'); ?></th>
                    <th><?php esc_html_e('Estimated Transfer (KB)', 'help4-builder-suite'); ?></th>
                    <th><?php esc_html_e('Confidence', 'help4-builder-suite'); ?></th>
                </tr>
                </thead>
                <tbody>
                <?php foreach ($pageEstimates as $row) : ?>
                    <?php if (! is_array($row)) { continue; } ?>
                    <tr>
                        <td>
                            <?php
                            $url = (string) ($row['url'] ?? '');
                            $title = (string) ($row['title'] ?? '');
                            ?>
                            <a href="<?php echo esc_url($url); ?>" target="_blank" rel="noopener"><?php echo esc_html($title); ?></a>
                        </td>
                        <td><?php echo esc_html((string) ($row['estimated_load_ms'] ?? '0')); ?></td>
                        <td><?php echo esc_html((string) ($row['estimated_requests'] ?? '0')); ?></td>
                        <td><?php echo esc_html((string) ($row['estimated_transfer_kb'] ?? '0')); ?></td>
                        <td><?php echo esc_html((string) ($row['confidence'] ?? '')); ?></td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
        </div>
        <script>
            (function () {
                const button = document.getElementById('h4bs-run-report');
                const status = document.getElementById('h4bs-run-status');
                if (!button || !status) return;

                button.addEventListener('click', function () {
                    button.disabled = true;
                    status.textContent = 'Running...';
                    fetch(ajaxurl, {
                        method: 'POST',
                        headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
                        body: new URLSearchParams({
                            action: 'h4bs_insights_run_report',
                            nonce: '<?php echo esc_js($nonce); ?>'
                        }).toString()
                    })
                    .then(function (r) { return r.json(); })
                    .then(function (payload) {
                        if (payload && payload.success) {
                            status.textContent = 'Report updated. Reloading...';
                            window.setTimeout(function () { window.location.reload(); }, 600);
                        } else {
                            status.textContent = 'Run failed.';
                            button.disabled = false;
                        }
                    })
                    .catch(function () {
                        status.textContent = 'Run failed.';
                        button.disabled = false;
                    });
                });
            })();
        </script>
        <?php
    }

    public function renderShortcodeRegistryPage(): void
    {
        if (! current_user_can('manage_options')) {
            return;
        }

        $rows = $this->shortcodeRegistryRows();
        $thirdParty = $this->thirdPartyH4Shortcodes();
        ?>
        <div class="wrap h4bs-admin-wrap">
            <h1><?php esc_html_e('Help4 Reserved Shortcode Registry', 'help4-builder-suite'); ?></h1>
            <p><?php esc_html_e('Use this table to detect missing tags or collisions with third-party plugins before migrations and production cutover.', 'help4-builder-suite'); ?></p>

            <h2><?php esc_html_e('Reserved Help4 Tags', 'help4-builder-suite'); ?></h2>
            <table class="widefat striped">
                <thead>
                    <tr>
                        <th><?php esc_html_e('Tag', 'help4-builder-suite'); ?></th>
                        <th><?php esc_html_e('Status', 'help4-builder-suite'); ?></th>
                        <th><?php esc_html_e('Current Callback Owner', 'help4-builder-suite'); ?></th>
                        <th><?php esc_html_e('Recommended Third-Party Alias', 'help4-builder-suite'); ?></th>
                        <th><?php esc_html_e('Notes', 'help4-builder-suite'); ?></th>
                    </tr>
                </thead>
                <tbody>
                <?php foreach ($rows as $row) : ?>
                    <?php if (! is_array($row)) { continue; } ?>
                    <tr>
                        <td><code><?php echo esc_html((string) ($row['tag'] ?? '')); ?></code></td>
                        <td><?php echo esc_html(strtoupper((string) ($row['status'] ?? 'unknown'))); ?></td>
                        <td><code><?php echo esc_html((string) ($row['owner'] ?? '')); ?></code></td>
                        <td><code><?php echo esc_html((string) ($row['recommended_alias'] ?? '')); ?></code></td>
                        <td><?php echo esc_html((string) ($row['note'] ?? '')); ?></td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>

            <h2><?php esc_html_e('Third-Party h4_* Tags Detected', 'help4-builder-suite'); ?></h2>
            <?php if ($thirdParty === []) : ?>
                <p><?php esc_html_e('No third-party h4_* shortcode tags detected.', 'help4-builder-suite'); ?></p>
            <?php else : ?>
                <table class="widefat striped">
                    <thead>
                        <tr>
                            <th><?php esc_html_e('Tag', 'help4-builder-suite'); ?></th>
                            <th><?php esc_html_e('Owner', 'help4-builder-suite'); ?></th>
                            <th><?php esc_html_e('Recommendation', 'help4-builder-suite'); ?></th>
                        </tr>
                    </thead>
                    <tbody>
                    <?php foreach ($thirdParty as $row) : ?>
                        <?php if (! is_array($row)) { continue; } ?>
                        <tr>
                            <td><code><?php echo esc_html((string) ($row['tag'] ?? '')); ?></code></td>
                            <td><code><?php echo esc_html((string) ($row['owner'] ?? '')); ?></code></td>
                            <td><?php esc_html_e('Rename custom tags to h4bs_* or project-specific prefix to avoid collisions during upgrades.', 'help4-builder-suite'); ?></td>
                        </tr>
                    <?php endforeach; ?>
                    </tbody>
                </table>
            <?php endif; ?>
        </div>
        <?php
    }

    /**
     * @return array<string, mixed>
     */
    private function latestReport(): array
    {
        $report = get_option(self::OPTION_REPORT, []);
        if (! is_array($report) || ! $report) {
            $report = $this->runFullReport();
        }
        return $report;
    }

    /**
     * @return array<string, mixed>
     */
    private function runFullReport(): array
    {
        $start = microtime(true);
        $moduleTests = $this->runModuleTests();
        $pageEstimates = $this->buildPageEstimates();

        $passed = 0;
        foreach ($moduleTests as $row) {
            if (is_array($row) && (($row['status'] ?? '') === 'pass')) {
                $passed++;
            }
        }

        $avgLoad = 0;
        $slowest = '-';
        $slowestMs = 0;
        if ($pageEstimates) {
            $sum = 0;
            foreach ($pageEstimates as $row) {
                if (! is_array($row)) {
                    continue;
                }
                $ms = (int) ($row['estimated_load_ms'] ?? 0);
                $sum += $ms;
                if ($ms > $slowestMs) {
                    $slowestMs = $ms;
                    $slowest = (string) ($row['title'] ?? '-');
                }
            }
            $avgLoad = (int) round($sum / max(1, count($pageEstimates)));
        }

        $report = [
            'generated_at'    => gmdate('Y-m-d H:i:s') . ' UTC',
            'duration_ms'     => (int) round((microtime(true) - $start) * 1000),
            'module_tests'    => $moduleTests,
            'page_estimates'  => $pageEstimates,
            'summary'         => [
                'modules_passed'       => $passed,
                'modules_checked'      => count($moduleTests),
                'pages_estimated'      => count($pageEstimates),
                'avg_estimated_load_ms'=> $avgLoad,
                'slowest_page'         => $slowest,
            ],
        ];

        update_option(self::OPTION_REPORT, $report, false);
        return $report;
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    private function runModuleTests(): array
    {
        global $wpdb;

        $routes = rest_get_server()->get_routes();
        $tests = [];

        $tests[] = $this->runTest(
            'template_library',
            static fn (): bool => post_type_exists('h4_template') && shortcode_exists('h4_template_library') && isset($routes['/h4bs/v1/templates']),
            'Checks CPT, shortcode, and REST templates route.'
        );

        $tests[] = $this->runTest(
            'slider',
            static fn (): bool => post_type_exists('h4_slider') && shortcode_exists('h4_slider'),
            'Checks slider CPT and shortcode registration.'
        );

        $tests[] = $this->runTest(
            'seo',
            static fn (): bool => (bool) get_option(Settings::OPTION_KEY, []),
            'Checks SEO settings option availability.'
        );

        $productsTable = $wpdb->prefix . 'h4_products';
        $tests[] = $this->runTest(
            'commerce',
            static function () use ($wpdb, $productsTable, $routes): bool {
                $cacheKey = 'commerce_table_exists_' . hash('sha256', $productsTable);
                $hasProductsTable = wp_cache_get($cacheKey, 'h4bs_insights');
                if (! is_string($hasProductsTable)) {
                    // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Cached schema guard for the optional native commerce table.
                    $hasProductsTable = (string) $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $productsTable)); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
                    wp_cache_set($cacheKey, $hasProductsTable, 'h4bs_insights', MINUTE_IN_SECONDS * 10);
                    // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
                }

                return is_string($hasProductsTable) && $hasProductsTable !== '' && isset($routes['/h4bs/v1/products']);
            },
            'Checks commerce table and products route.'
        );

        $tests[] = $this->runTest(
            'search',
            static fn (): bool => shortcode_exists('h4_search') && isset($routes['/h4bs/v1/search']),
            'Checks search shortcode and REST route.'
        );

        $tests[] = $this->runTest(
            'fields',
            static fn (): bool => post_type_exists('h4_field_group'),
            'Checks custom field group CPT.'
        );

        $tests[] = $this->runTest(
            'industry',
            static fn (): bool => taxonomy_exists('h4_industry') && isset($routes['/h4bs/v1/industry-packs']),
            'Checks industry taxonomy and packs route.'
        );

        $tests[] = $this->runTest(
            'mega_menu',
            static fn (): bool => has_filter('nav_menu_css_class') !== false,
            'Checks menu class filter registration.'
        );

        $tests[] = $this->runTest(
            'builder',
            static fn (): bool => shortcode_exists('h4_builder') && has_action('admin_action_h4bs_duplicate_post') !== false,
            'Checks builder shortcode and duplicate action.'
        );

        $tests[] = $this->runTest(
            'licensing',
            static fn (): bool => isset($routes['/h4bs/v1/license/status']) && isset($routes['/h4bs/v1/license/activate']),
            'Checks license status and activation routes.'
        );

        $tests[] = $this->runTest(
            'dependency',
            static fn (): bool => Settings::get('required_theme_slug', '') !== '' && Settings::get('required_plugin_basename', '') !== '',
            'Checks dependency target settings.'
        );

        $shortcodeAudit = $this->auditReservedShortcodes();
        $tests[] = [
            'module' => 'shortcode_registry',
            'status' => $shortcodeAudit['status'],
            'duration_ms' => 0,
            'details' => $shortcodeAudit['details'],
        ];

        $tests[] = $this->runTest(
            'security',
            static fn (): bool => has_filter('authenticate') !== false && has_action('send_headers') !== false,
            'Checks authentication/security hooks.'
        );

        $tests[] = $this->runTest(
            'performance',
            static fn (): bool => isset($routes['/h4bs/v1/performance/status']) && has_filter('script_loader_tag') !== false,
            'Checks performance route and defer filter.'
        );

        $tests[] = $this->runTest(
            'image_optimization',
            static fn (): bool => extension_loaded('imagick') && has_filter('wp_generate_attachment_metadata') !== false,
            extension_loaded('imagick')
                ? 'Imagick loaded and optimization hook present.'
                : 'Imagick extension missing (optimization fallback required).',
            extension_loaded('imagick') ? 'pass' : 'warn'
        );

        $tests[] = $this->runTest(
            'insights',
            static fn (): bool => isset($routes['/h4bs/v1/insights/report']),
            'Checks report route registration.'
        );

        return $tests;
    }

    /**
     * @return array{status: string, details: string}
     */
    private function auditReservedShortcodes(): array
    {
        $missing = [];
        $conflicts = [];

        foreach ($this->reservedShortcodeTags() as $tag) {
            if (! shortcode_exists($tag)) {
                $missing[] = $tag;
                continue;
            }
            $owner = $this->shortcodeCallbackOwner($tag);
            if ($owner === '' || ! str_starts_with($owner, 'Help4BuilderSuite\\')) {
                $conflicts[] = $tag . ($owner !== '' ? ' -> ' . $owner : '');
            }
        }

        if (! $missing && ! $conflicts) {
            return [
                'status' => 'pass',
                'details' => 'Reserved Help4 shortcode registry is healthy (no missing or hijacked tags).',
            ];
        }

        $parts = [];
        if ($missing) {
            $parts[] = 'Missing: ' . implode(', ', $missing);
        }
        if ($conflicts) {
            $parts[] = 'Conflicts: ' . implode(', ', $conflicts);
        }

        return [
            'status' => 'warn',
            'details' => 'Reserved shortcode issues detected. ' . implode(' | ', $parts),
        ];
    }

    /**
     * @return array<int, string>
     */
    private function reservedShortcodeTags(): array
    {
        return [
            'h4_builder',
            'h4_slider',
            'h4_website_snapshot',
            'h4_siteshot',
            'h4_template_library',
            'h4_template',
            'h4_popup',
            'h4_search',
            'h4_products',
            'h4_checkout',
            'h4_field',
            'h4_form',
            'h4_contact_form',
            'h4_newsletter_form',
            'h4_quote_request',
            'h4_callback_request',
            'h4_booking',
            'h4_lms_courses',
            'h4_lms_progress',
            'h4_lms_certificate',
            'h4_ea_info_box',
            'h4_ea_flip_box',
            'h4_ea_advanced_tabs',
            'h4_ea_advanced_accordion',
            'h4_ea_testimonial_slider',
            'h4_ea_logo_carousel',
            'h4_ea_data_table',
            'h4_ea_post_grid',
            'h4_ea_countdown',
            'h4_ea_filterable_gallery',
            'h4_ea_image_accordion',
            'h4_ea_hotspot',
            'h4_ea_content_ticker',
        ];
    }

    /**
     * @return array<int, array{tag: string, status: string, owner: string, recommended_alias: string, note: string}>
     */
    private function shortcodeRegistryRows(): array
    {
        $rows = [];
        foreach ($this->reservedShortcodeTags() as $tag) {
            $owner = $this->shortcodeCallbackOwner($tag);
            $status = 'ok';
            $note = 'Registered to Help4 core.';
            if (! shortcode_exists($tag)) {
                $status = 'missing';
                $note = 'Reserved tag is missing and should be re-registered by Help4 modules.';
            } elseif ($owner === '' || ! str_starts_with($owner, 'Help4BuilderSuite\\')) {
                $status = 'conflict';
                $note = 'Reserved tag is owned outside Help4 core and may break expected rendering.';
            }

            $rows[] = [
                'tag' => $tag,
                'status' => $status,
                'owner' => $owner !== '' ? $owner : '-',
                'recommended_alias' => $this->recommendedAliasForTag($tag),
                'note' => $note,
            ];
        }

        return $rows;
    }

    /**
     * @return array<int, array{tag: string, owner: string}>
     */
    private function thirdPartyH4Shortcodes(): array
    {
        global $shortcode_tags;
        if (! is_array($shortcode_tags)) {
            return [];
        }

        $reserved = array_fill_keys($this->reservedShortcodeTags(), true);
        $rows = [];
        foreach ($shortcode_tags as $tag => $callback) {
            $cleanTag = sanitize_key((string) $tag);
            if ($cleanTag === '' || ! str_starts_with($cleanTag, 'h4_')) {
                continue;
            }
            if (isset($reserved[$cleanTag])) {
                continue;
            }

            $owner = $this->shortcodeCallbackOwner($cleanTag);
            if ($owner !== '' && str_starts_with($owner, 'Help4BuilderSuite\\')) {
                continue;
            }

            $rows[] = [
                'tag' => $cleanTag,
                'owner' => $owner !== '' ? $owner : '-',
            ];
        }

        usort(
            $rows,
            static fn (array $a, array $b): int => strcmp((string) ($a['tag'] ?? ''), (string) ($b['tag'] ?? ''))
        );
        return $rows;
    }

    private function recommendedAliasForTag(string $tag): string
    {
        $suffix = preg_replace('/^h4_/', '', $tag);
        $suffix = is_string($suffix) ? $suffix : $tag;
        $suffix = trim($suffix);
        if ($suffix === '') {
            $suffix = $tag;
        }
        return 'h4bs_' . $suffix;
    }

    private function shortcodeCallbackOwner(string $tag): string
    {
        global $shortcode_tags;
        if (! is_array($shortcode_tags) || ! isset($shortcode_tags[$tag])) {
            return '';
        }

        $callback = $shortcode_tags[$tag];
        if (is_string($callback)) {
            return $callback;
        }
        if (! is_array($callback) || ! isset($callback[0])) {
            return '';
        }

        $target = $callback[0];
        if (is_object($target)) {
            return get_class($target);
        }
        if (is_string($target)) {
            return $target;
        }
        return '';
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    private function buildPageEstimates(): array
    {
        $posts = get_posts(
            [
                'post_type'      => ['page', 'post'],
                'post_status'    => 'publish',
                'posts_per_page' => 30,
                'orderby'        => 'modified',
                'order'          => 'DESC',
            ]
        );

        $out = [];
        foreach ($posts as $post) {
            if (! $post instanceof WP_Post) {
                continue;
            }
            $out[] = $this->estimatePost($post);
        }

        usort(
            $out,
            static fn (array $a, array $b): int => ((int) ($b['estimated_load_ms'] ?? 0)) <=> ((int) ($a['estimated_load_ms'] ?? 0))
        );

        return $out;
    }

    /**
     * @return array<string, mixed>
     */
    private function estimatePost(WP_Post $post): array
    {
        $ms = 650;
        $requests = 26;
        $kb = 290;
        $confidence = 'medium';

        if (! Settings::bool('perf_defer_scripts', true)) {
            $ms += 110;
            $requests += 2;
        }
        if (! Settings::bool('perf_lazyload_images', true)) {
            $ms += 90;
        }
        if (! Settings::bool('perf_cache_headers', true)) {
            $ms += 60;
        }
        if (! Settings::bool('perf_integrate_redis', true)) {
            $ms += 45;
        }

        $shortcodeWeights = [
            'h4_search'            => [120, 4, 45],
            'h4_products'          => [200, 5, 95],
            'h4_checkout'          => [260, 5, 90],
            'h4_template_library'  => [100, 2, 35],
            'h4_slider'            => [320, 6, 240],
            'h4_industry_templates'=> [110, 2, 40],
            'h4_builder'           => [220, 3, 60],
        ];

        foreach ($shortcodeWeights as $shortcode => [$addMs, $addReq, $addKb]) {
            $count = $this->shortcodeCount($post->post_content, $shortcode);
            if ($count > 0) {
                $ms += $addMs * $count;
                $requests += $addReq * $count;
                $kb += $addKb * $count;
            }
        }

        $builderEnabled = (string) get_post_meta($post->ID, '_h4_builder_enabled', true) === '1'
            && (string) get_post_meta($post->ID, '_h4_builder_mode', true) === 'help4';

        if ($builderEnabled) {
            $layout = json_decode((string) get_post_meta($post->ID, '_h4_builder_layout', true), true);
            if (is_array($layout)) {
                $weights = [
                    'heading'   => [6, 0, 1],
                    'text'      => [8, 0, 1],
                    'image'     => [65, 2, 80],
                    'button'    => [4, 0, 1],
                    'html'      => [20, 1, 10],
                    'shortcode' => [140, 3, 42],
                    'slider'    => [280, 4, 180],
                    'spacer'    => [1, 0, 0],
                ];
                foreach ($layout as $block) {
                    if (! is_array($block)) {
                        continue;
                    }
                    $type = sanitize_key((string) ($block['type'] ?? ''));
                    if (! isset($weights[$type])) {
                        continue;
                    }
                    [$addMs, $addReq, $addKb] = $weights[$type];
                    $ms += $addMs;
                    $requests += $addReq;
                    $kb += $addKb;
                }
                $confidence = 'high';
            }
        }

        return [
            'post_id'               => $post->ID,
            'title'                 => $post->post_title,
            'url'                   => get_permalink($post->ID),
            'estimated_load_ms'     => $ms,
            'estimated_requests'    => $requests,
            'estimated_transfer_kb' => $kb,
            'estimated_lcp_ms'      => (int) round($ms * 1.28),
            'confidence'            => $confidence,
        ];
    }

    private function shortcodeCount(string $content, string $shortcode): int
    {
        if ($content === '' || $shortcode === '') {
            return 0;
        }
        if (! str_contains($content, '[' . $shortcode)) {
            return 0;
        }
        preg_match_all('/\[' . preg_quote($shortcode, '/') . '\b/i', $content, $matches);
        return is_array($matches[0] ?? null) ? count($matches[0]) : 0;
    }

    /**
     * @return array<string, mixed>
     */
    private function runTest(string $module, callable $check, string $details, string $statusOverride = ''): array
    {
        $start = microtime(true);
        $ok = false;
        try {
            $ok = (bool) $check();
        } catch (\Throwable $e) {
            $ok = false;
            $details .= ' Error: ' . $e->getMessage();
        }

        $status = $statusOverride !== '' ? $statusOverride : ($ok ? 'pass' : 'fail');
        return [
            'module'      => $module,
            'status'      => $status,
            'duration_ms' => (int) round((microtime(true) - $start) * 1000),
            'details'     => $details,
        ];
    }
}
