<?php
declare(strict_types=1);

namespace Help4BuilderSuite\Admin;

use Help4BuilderSuite\Support\BusinessProfileDefaults;
use Help4BuilderSuite\Support\FeatureFlags;
use Help4BuilderSuite\Support\Settings;
use Help4BuilderSuite\Modules\SEO\DiscoveryStandards;

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

final class SettingsPage
{
    private const WIZARD_PAGE_SLUG = 'h4bs-setup-wizard';
    private const WIZARD_DONE_OPTION = 'h4bs_setup_wizard_done';
    private const WIZARD_NOTICE_TRANSIENT = 'h4bs_setup_wizard_notice';
    private const WIZARD_BYPASS_META = 'h4bs_setup_wizard_bypass_until';
    private const LAUNCH_SNAPSHOT_OPTION = 'h4bs_site_launch_last_snapshot';
    private const LAUNCH_REPORT_OPTION = 'h4bs_site_launch_last_report';
    private const STAFF_MENU_KEEP_SLUGS = [
        'h4bs-settings',
        'h4bs-calendar',
        'h4bs-staff-directory',
        'h4bs-builder-pages',
        'h4bs-forms',
        'h4bs-form-entries',
        'h4bs-form-privacy',
        'h4bs-newsletter',
        'h4bs-form-settings',
    ];

    private FeatureFlags $featureFlags;

    public function __construct(FeatureFlags $featureFlags)
    {
        $this->featureFlags = $featureFlags;
    }

    public function boot(): void
    {
        add_action('admin_menu', [$this, 'registerMenu']);
        add_action('admin_init', [$this, 'registerSettings']);
        add_action('admin_init', [$this, 'maybeRedirectToWizard']);
        add_action('admin_post_h4bs_setup_wizard', [$this, 'handleWizardSubmit']);
        add_action('admin_post_h4bs_apply_theme_pack', [$this, 'handleApplyThemePack']);
        add_action('admin_post_h4bs_apply_site_launch_profile', [$this, 'handleApplySiteLaunchProfile']);
        add_action('admin_post_h4bs_restore_site_launch_snapshot', [$this, 'handleRestoreSiteLaunchSnapshot']);
        add_action('admin_post_h4bs_toggle_staff_favorite', [$this, 'handleToggleStaffFavorite']);
        add_action('admin_post_h4bs_toggle_advanced_tools', [$this, 'handleToggleAdvancedTools']);
        add_action('admin_menu', [$this, 'simplifyStaffMenu'], 999);
        add_action('admin_notices', [$this, 'renderWizardNotice']);
        add_action('admin_notices', [$this, 'renderPluginsScreenWizardNotice']);
        add_filter('admin_footer_text', [$this, 'contextualAdminHelpFooter'], 20);

        if (defined('H4BS_FILE')) {
            add_filter('plugin_action_links_' . plugin_basename((string) H4BS_FILE), [$this, 'pluginActionLinks']);
        }
    }

    public function registerMenu(): void
    {
        add_menu_page(
            __('Help4 Builder', 'help4-builder-suite'),
            __('Help4 Builder', 'help4-builder-suite'),
            'edit_pages',
            'h4bs-settings',
            [$this, 'renderStaffHome'],
            'dashicons-layout',
            58
        );

        add_submenu_page(
            'h4bs-settings',
            __('Work Home', 'help4-builder-suite'),
            __('Work Home', 'help4-builder-suite'),
            'edit_pages',
            'h4bs-settings',
            [$this, 'renderStaffHome']
        );

        add_submenu_page(
            'h4bs-settings',
            __('Builder Settings', 'help4-builder-suite'),
            __('Builder Settings', 'help4-builder-suite'),
            'manage_options',
            'h4bs-settings-advanced',
            [$this, 'render']
        );

        add_submenu_page(
            'h4bs-settings',
            __('Setup Wizard', 'help4-builder-suite'),
            __('Setup Wizard', 'help4-builder-suite'),
            'manage_options',
            self::WIZARD_PAGE_SLUG,
            [$this, 'renderWizard']
        );
    }

    public function registerSettings(): void
    {
        register_setting(
            'h4bs_settings_group',
            FeatureFlags::OPTION_KEY,
            [$this, 'sanitizeFlags']
        );

        register_setting(
            'h4bs_settings_group',
            Settings::OPTION_KEY,
            [$this, 'sanitizeSettings']
        );
    }

    public function simplifyStaffMenu(): void
    {
        if ((string) get_user_meta(get_current_user_id(), 'h4bs_show_advanced_tools', true) === '1') {
            return;
        }
        $keep = $this->simpleStaffMenuSlugs();
        global $submenu, $menu;
        if (is_array($menu)) {
            foreach ($menu as $item) {
                $slug = (string) ($item[2] ?? '');
                if ($this->isPluginOwnedAdminSlug($slug) && ! in_array($slug, $keep, true)) {
                    remove_menu_page($slug);
                }
            }
        }
        if (! isset($submenu['h4bs-settings']) || ! is_array($submenu['h4bs-settings'])) {
            return;
        }
        $submenu['h4bs-settings'] = array_values(array_filter(
            $submenu['h4bs-settings'],
            fn (array $item): bool => $this->shouldKeepStaffSubmenuItem($item, $keep)
        ));
    }

    /** @return list<string> */
    private function simpleStaffMenuSlugs(): array
    {
        $keep = self::STAFF_MENU_KEEP_SLUGS;
        foreach ($this->staffWorkspaceDefinitions() as $workspace) {
            $keep[] = $workspace['slug'];
        }

        /**
         * Filters admin-page slugs that remain visible in simplified staff mode.
         *
         * Extensions should still register their page with add_submenu_page(). Use
         * h4bs_staff_workspaces when the page should also appear on Work Home.
         *
         * @param list<string> $keep Allowed Help4 child-menu slugs.
         */
        $filtered = apply_filters('h4bs_staff_menu_keep_slugs', $keep);
        $filtered = is_array($filtered) ? $filtered : $keep;

        $clean = [];
        foreach ($filtered as $slug) {
            $slug = sanitize_key((string) $slug);
            if ($slug !== '') {
                $clean[] = $slug;
            }
        }
        return array_values(array_unique($clean));
    }

    private function isPluginOwnedAdminSlug(string $slug): bool
    {
        return str_starts_with($slug, 'h4bs-') || str_starts_with($slug, 'edit.php?post_type=h4_');
    }

    /** @param array<int, mixed> $item */
    private function canAccessSubmenuItem(array $item): bool
    {
        $capability = sanitize_key((string) ($item[1] ?? ''));
        return $capability !== '' && current_user_can($capability);
    }

    /**
     * @param array<int, mixed> $item
     * @param list<string> $keep
     */
    private function shouldKeepStaffSubmenuItem(array $item, array $keep): bool
    {
        $slug = (string) ($item[2] ?? '');
        if ($slug === '' || ! $this->canAccessSubmenuItem($item)) {
            return false;
        }
        if (in_array(sanitize_key($slug), $keep, true)) {
            return true;
        }

        // Child themes and integrations own non-H4BS slugs and remain available.
        return ! $this->isPluginOwnedAdminSlug($slug);
    }

    /**
     * @return list<array{slug:string,label:string,description:string,capability:string,icon:string,url:string,priority:int}>
     */
    private function staffWorkspaceDefinitions(): array
    {
        /**
         * Registers site or extension workspaces for simplified menus and Work Home.
         *
         * Each item requires a slug matching an add_submenu_page() child registered
         * beneath h4bs-settings. Optional keys are label, description, capability,
         * icon (Dashicons class), url, and priority.
         *
         * @param list<array<string, mixed>> $workspaces Workspace definitions.
         */
        $raw = apply_filters('h4bs_staff_workspaces', []);
        if (! is_array($raw)) {
            return [];
        }

        $workspaces = [];
        foreach ($raw as $item) {
            if (! is_array($item)) {
                continue;
            }
            $slug = sanitize_key((string) ($item['slug'] ?? ''));
            if ($slug === '') {
                continue;
            }
            $workspaces[$slug] = [
                'slug' => $slug,
                'label' => sanitize_text_field((string) ($item['label'] ?? '')),
                'description' => sanitize_text_field((string) ($item['description'] ?? '')),
                'capability' => sanitize_key((string) ($item['capability'] ?? 'edit_pages')) ?: 'edit_pages',
                'icon' => sanitize_html_class((string) ($item['icon'] ?? 'dashicons-screenoptions')) ?: 'dashicons-screenoptions',
                'url' => esc_url_raw((string) ($item['url'] ?? '')),
                'priority' => isset($item['priority']) ? (int) $item['priority'] : 100,
            ];
        }
        return array_values($workspaces);
    }

    /**
     * @return list<array{slug:string,label:string,description:string,icon:string,url:string,priority:int}>
     */
    private function visibleStaffWorkspaces(): array
    {
        global $submenu;
        $items = isset($submenu['h4bs-settings']) && is_array($submenu['h4bs-settings'])
            ? $submenu['h4bs-settings']
            : [];
        $definitions = [];
        foreach ($this->staffWorkspaceDefinitions() as $workspace) {
            $definitions[$workspace['slug']] = $workspace;
        }
        $keep = $this->simpleStaffMenuSlugs();
        $workspaces = [];

        foreach ($items as $item) {
            if (! is_array($item) || ! $this->canAccessSubmenuItem($item)) {
                continue;
            }
            $rawSlug = (string) ($item[2] ?? '');
            $slug = sanitize_key($rawSlug);
            if ($slug === '' || in_array($slug, self::STAFF_MENU_KEEP_SLUGS, true)) {
                continue;
            }
            $definition = $definitions[$slug] ?? null;
            if ($this->isPluginOwnedAdminSlug($rawSlug) && $definition === null && ! in_array($slug, $keep, true)) {
                continue;
            }

            $menuLabel = sanitize_text_field(wp_strip_all_tags((string) ($item[0] ?? '')));
            $url = is_array($definition) ? (string) $definition['url'] : '';
            if ($url === '') {
                $url = (string) menu_page_url($rawSlug, false);
            }
            if ($url === '') {
                $url = admin_url('admin.php?page=' . rawurlencode($rawSlug));
            }
            $workspaces[$slug] = [
                'slug' => $slug,
                'label' => is_array($definition) && $definition['label'] !== '' ? $definition['label'] : ($menuLabel ?: $slug),
                'description' => is_array($definition) && $definition['description'] !== ''
                    ? $definition['description']
                    : __('Open this site workspace without leaving Help4 Work Home.', 'help4-builder-suite'),
                'icon' => is_array($definition) ? $definition['icon'] : 'dashicons-screenoptions',
                'url' => $url,
                'priority' => is_array($definition) ? $definition['priority'] : 100,
            ];
        }

        usort($workspaces, static function (array $left, array $right): int {
            $priority = $left['priority'] <=> $right['priority'];
            return $priority !== 0 ? $priority : strcasecmp($left['label'], $right['label']);
        });
        return array_values($workspaces);
    }

    public function handleToggleAdvancedTools(): void
    {
        if (! current_user_can('manage_options')) {
            wp_die(esc_html__('Only site administrators can change the advanced-tools view.', 'help4-builder-suite'));
        }
        check_admin_referer('h4bs_toggle_advanced_tools');
        $enabled = (string) get_user_meta(get_current_user_id(), 'h4bs_show_advanced_tools', true) === '1';
        update_user_meta(get_current_user_id(), 'h4bs_show_advanced_tools', $enabled ? '0' : '1');
        wp_safe_redirect(admin_url('admin.php?page=h4bs-settings'));
        exit;
    }

    /**
     * @param mixed $raw
     * @return array<string, bool>
     */
    public function sanitizeFlags($raw): array
    {
        $raw = is_array($raw) ? $raw : [];

        $clean = [];
        foreach ($this->featureFlags->defaults() as $key => $default) {
            $clean[$key] = ! empty($raw[$key]);
        }

        return $clean;
    }

    /**
     * @param mixed $raw
     * @return array<string, string>
     */
    public function sanitizeSettings($raw): array
    {
        $raw = is_array($raw) ? $raw : [];

        $defaults = Settings::recommendedDefaults();
        $clean = $defaults;

        $textKeys = [
            'brand_name',
            'footer_credit_text',
            'google_site_verification',
            'bing_site_verification',
            'yandex_site_verification',
            'baidu_site_verification',
            'naver_site_verification',
            'pinterest_site_verification',
            'facebook_domain_verification',
            'indexnow_key',
            'twitter_site',
            'business_phone',
            'default_social_image_alt',
            'commerce_seo_default_brand',
            'paypal_client_id',
            'square_application_id',
            'braintree_merchant_id',
            'hosted_payments_profile',
            'godaddy_payments_profile',
            'wise_profile_id',
            'authorize_net_login_id',
            'mls_idx_provider',
            'maps_api_key',
            'required_theme_slug',
            'required_plugin_basename',
            'license_whitelist_cidrs',
            'security_cloudflare_cidrs',
            'security_origin_bypass_cidrs',
            'security_rotate_salts_interval_hours',
            'footer_credit_start_year',
            'security_csp_policy',
        ];

        $urlKeys = [
            'support_url',
            'default_social_image_url',
            'igor_feedback_endpoint',
            'commerce_seo_return_policy_url',
            'commerce_seo_shipping_policy_url',
        ];

        $boolKeys = [
            'auto_install_dependencies',
            'footer_credit_enabled',
            'license_required_outside',
            'security_enable_headers',
            'security_disable_xmlrpc',
            'security_block_bad_queries',
            'security_require_cloudflare_origin',
            'security_trust_cf_connecting_ip',
            'security_hide_wp_version',
            'security_enforce_wp_config_permissions',
            'security_rotate_salts_enabled',
            'security_require_ssl_for_commerce',
            'security_csp_enabled',
            'ssl_force_https',
            'ssl_hsts_enabled',
            'perf_defer_scripts',
            'perf_lazyload_images',
            'perf_cache_headers',
            'perf_integrate_litespeed',
            'perf_integrate_w3tc',
            'perf_integrate_redis',
            'image_opt_enable',
            'image_opt_generate_webp',
            'image_opt_enhance_uploaded',
            'igor_feedback_enabled',
            'indexnow_enabled',
            'seo_video_sitemap_enabled',
            'seo_news_sitemap_enabled',
            'commerce_show_quick_view',
            'commerce_show_compare_action',
            'commerce_show_stock_badge',
            'commerce_show_sku',
            'commerce_show_product_type_badges',
            'commerce_show_product_image',
            'commerce_sticky_mobile_toolbar',
            'commerce_show_price_watch_prompt',
            'commerce_show_waitlist_prompt',
            'commerce_seo_feed_enabled',
        ];

        BusinessProfileDefaults::markUserOwnedSettings(array_unique(array_merge(array_keys($raw), $boolKeys)));

        foreach ($textKeys as $key) {
            $clean[$key] = sanitize_text_field((string) ($raw[$key] ?? ''));
        }

        foreach ($urlKeys as $key) {
            $clean[$key] = esc_url_raw((string) ($raw[$key] ?? ''));
        }

        foreach ($boolKeys as $key) {
            $clean[$key] = ! empty($raw[$key]) ? '1' : '0';
        }

        $clean['seo_rss_before_content'] = sanitize_textarea_field((string) ($raw['seo_rss_before_content'] ?? ''));
        $clean['seo_rss_after_content'] = sanitize_textarea_field((string) ($raw['seo_rss_after_content'] ?? ''));
        $indexNowKey = (string) preg_replace('/[^A-Za-z0-9-]/', '', (string) ($raw['indexnow_key'] ?? ''));
        if ($clean['indexnow_enabled'] === '1' && strlen($indexNowKey) < 8) {
            $indexNowKey = wp_generate_password(32, false, false);
        }
        $clean['indexnow_key'] = substr($indexNowKey, 0, 128);
        $twitterSite = trim((string) ($raw['twitter_site'] ?? ''));
        if (filter_var($twitterSite, FILTER_VALIDATE_URL)) {
            $twitterPath = trim((string) wp_parse_url($twitterSite, PHP_URL_PATH), '/');
            $twitterSite = basename($twitterPath);
        }
        $twitterSite = ltrim($twitterSite, '@');
        $twitterSite = (string) preg_replace('/[^A-Za-z0-9_]/', '', $twitterSite);
        $clean['twitter_site'] = $twitterSite !== '' ? '@' . substr($twitterSite, 0, 15) : '';
        $sameAsRaw = $raw['same_as_urls'] ?? '';
        $sameAsRows = is_array($sameAsRaw) ? $sameAsRaw : (preg_split('/\r\n|\r|\n/', (string) $sameAsRaw) ?: []);
        $clean['same_as_urls'] = [];
        foreach ($sameAsRows as $sameAsUrl) {
            $sameAsUrl = esc_url_raw(trim((string) $sameAsUrl), ['http', 'https']);
            if ($sameAsUrl !== '') {
                $clean['same_as_urls'][] = $sameAsUrl;
            }
        }
        $clean['same_as_urls'] = array_slice(array_values(array_unique($clean['same_as_urls'])), 0, 30);
        $discoveryStandards = new DiscoveryStandards();
        $clean['custom_site_verification_meta'] = $discoveryStandards->sanitizeCustomVerificationMeta(
            $raw['custom_site_verification_meta'] ?? []
        );

        $clean['security_max_login_attempts'] = (string) max(3, min(25, (int) ($raw['security_max_login_attempts'] ?? $defaults['security_max_login_attempts'])));
        $clean['security_lock_minutes'] = (string) max(1, min(1440, (int) ($raw['security_lock_minutes'] ?? $defaults['security_lock_minutes'])));
        $clean['security_rotate_salts_interval_hours'] = (string) max(24, min(720, (int) ($raw['security_rotate_salts_interval_hours'] ?? $defaults['security_rotate_salts_interval_hours'])));
        $clean['footer_credit_start_year'] = (string) max(1900, min((int) gmdate('Y') + 25, (int) ($raw['footer_credit_start_year'] ?? $defaults['footer_credit_start_year'])));
        $yearMode = sanitize_key((string) ($raw['footer_credit_year_mode'] ?? $defaults['footer_credit_year_mode']));
        $clean['footer_credit_year_mode'] = in_array($yearMode, ['current', 'range', 'none'], true) ? $yearMode : 'current';
        $clean['image_opt_quality'] = (string) max(40, min(95, (int) ($raw['image_opt_quality'] ?? $defaults['image_opt_quality'])));
        $intentProfile = sanitize_key((string) ($raw['seo_default_intent_profile'] ?? $defaults['seo_default_intent_profile']));
        $clean['seo_default_intent_profile'] = in_array($intentProfile, ['auto', 'general', 'local', 'ecommerce', 'publisher', 'global'], true) ? $intentProfile : 'auto';
        $productCondition = sanitize_key((string) ($raw['commerce_seo_default_condition'] ?? $defaults['commerce_seo_default_condition']));
        $clean['commerce_seo_default_condition'] = in_array($productCondition, ['new', 'used', 'refurbished'], true) ? $productCondition : 'new';
        $cardStyle = sanitize_key((string) ($raw['commerce_product_card_style'] ?? $defaults['commerce_product_card_style']));
        $clean['commerce_product_card_style'] = in_array($cardStyle, ['clean', 'overlay', 'compact', 'list', 'showcase'], true) ? $cardStyle : 'overlay';
        $cardHover = sanitize_key((string) ($raw['commerce_product_hover'] ?? $defaults['commerce_product_hover']));
        $clean['commerce_product_hover'] = in_array($cardHover, ['none', 'lift', 'image_zoom', 'quick_actions'], true) ? $cardHover : 'lift';
        $filterStyle = sanitize_key((string) ($raw['commerce_filter_style'] ?? $defaults['commerce_filter_style']));
        $clean['commerce_filter_style'] = in_array($filterStyle, ['toolbar', 'compact', 'drawer'], true) ? $filterStyle : 'toolbar';
        $clean['commerce_product_columns_desktop'] = (string) max(1, min(6, (int) ($raw['commerce_product_columns_desktop'] ?? $defaults['commerce_product_columns_desktop'])));
        $clean['commerce_product_columns_tablet'] = (string) max(1, min(4, (int) ($raw['commerce_product_columns_tablet'] ?? $defaults['commerce_product_columns_tablet'])));
        $clean['commerce_product_columns_mobile'] = (string) max(1, min(2, (int) ($raw['commerce_product_columns_mobile'] ?? $defaults['commerce_product_columns_mobile'])));

        foreach (Settings::lockedEndpointDefaults() as $key => $value) {
            $clean[$key] = $value;
        }

        return $clean;
    }

    public function maybeRedirectToWizard(): void
    {
        if (! is_admin() || ! current_user_can('manage_options')) {
            return;
        }
        if (wp_doing_ajax() || wp_doing_cron()) {
            return;
        }
        $wizardSaved = isset($_GET['h4bs_wizard_saved'])
            ? sanitize_key((string) wp_unslash($_GET['h4bs_wizard_saved']))
            : '';
        if ($wizardSaved === '1') {
            update_option(self::WIZARD_DONE_OPTION, '1');
            if (is_multisite()) {
                update_site_option(self::WIZARD_DONE_OPTION, '1');
            }
            $this->setWizardBypassForCurrentUser(900);
            return;
        }

        $skipWizard = isset($_GET['h4bs_skip_wizard'])
            ? sanitize_key((string) wp_unslash($_GET['h4bs_skip_wizard']))
            : '';
        $skipNonce = isset($_GET['_h4bs_skip'])
            ? sanitize_text_field((string) wp_unslash($_GET['_h4bs_skip']))
            : '';
        if (
            $skipWizard === '1'
            && $skipNonce !== ''
            && wp_verify_nonce($skipNonce, 'h4bs_skip_setup_wizard')
        ) {
            update_option(self::WIZARD_DONE_OPTION, '1');
            if (is_multisite()) {
                update_site_option(self::WIZARD_DONE_OPTION, '1');
            }
            $this->setWizardBypassForCurrentUser();
            return;
        }
    }

    public function handleWizardSubmit(): void
    {
        if (! current_user_can('manage_options')) {
            wp_die(esc_html__('Unauthorized request.', 'help4-builder-suite'));
        }
        check_admin_referer('h4bs_setup_wizard', 'h4bs_setup_wizard_nonce');

        $post = wp_unslash($_POST);
        $requestedThemePack = sanitize_key((string) ($post['theme_pack_slug'] ?? ''));
        $requestedBusinessType = sanitize_key((string) ($post['business_type'] ?? BusinessProfileDefaults::selectedSlug()));
        if (! BusinessProfileDefaults::profile($requestedBusinessType)) {
            $requestedBusinessType = 'business';
        }
        $answers = [
            'business_type'        => $requestedBusinessType,
            'needs_commerce'       => ! empty($post['needs_commerce']),
            'needs_standalone_payments' => ! empty($post['needs_standalone_payments']),
            'needs_invoice_tracking' => ! empty($post['needs_invoice_tracking']),
            'needs_subscriptions'  => ! empty($post['needs_subscriptions']),
            'needs_lms'            => ! empty($post['needs_lms']),
            'needs_realtor'        => ! empty($post['needs_realtor']),
            'needs_contractor'     => ! empty($post['needs_contractor']),
            'needs_templates'      => ! empty($post['needs_templates']),
            'needs_seo'            => ! empty($post['needs_seo']),
            'needs_security'       => ! empty($post['needs_security']),
            'needs_performance'    => ! empty($post['needs_performance']),
            'needs_demo_showcase'  => ! empty($post['needs_demo_showcase']),
            'theme_pack_slug'      => $requestedThemePack,
        ];

        $profileReport = BusinessProfileDefaults::selectProfile($answers['business_type'], true);

        $themePackSlug = $answers['theme_pack_slug'] !== ''
            ? $answers['theme_pack_slug']
            : $this->recommendedThemePackSlug($answers['business_type']);
        if (! $this->themePackBySlug($themePackSlug)) {
            $themePackSlug = $this->recommendedThemePackSlug($answers['business_type']);
        }
        $answers['theme_pack_slug'] = $themePackSlug;

        update_option(FeatureFlags::OPTION_KEY, $this->buildFeaturePlan($answers));

        $settings = Settings::all();
        $settings['security_enable_headers'] = $answers['needs_security'] ? '1' : '0';
        $settings['security_disable_xmlrpc'] = $answers['needs_security'] ? '1' : '0';
        $settings['security_block_bad_queries'] = $answers['needs_security'] ? '1' : '0';
        $settings['perf_defer_scripts'] = $answers['needs_performance'] ? '1' : '0';
        $settings['perf_lazyload_images'] = $answers['needs_performance'] ? '1' : '0';
        $settings['perf_cache_headers'] = $answers['needs_performance'] ? '1' : '0';
        $needsCommerceStack = $answers['needs_commerce']
            || $answers['needs_standalone_payments']
            || $answers['needs_invoice_tracking']
            || $answers['needs_subscriptions'];
        $settings['security_require_ssl_for_commerce'] = $needsCommerceStack ? '1' : '0';
        if ($answers['needs_realtor']) {
            $settings['mls_idx_provider'] = $settings['mls_idx_provider'] !== ''
                ? (string) $settings['mls_idx_provider']
                : 'Configure Provider';
        }
        foreach (Settings::lockedEndpointDefaults() as $key => $value) {
            $settings[$key] = $value;
        }
        update_option(Settings::OPTION_KEY, $settings);
        BusinessProfileDefaults::markUserOwnedSettings([
            'security_enable_headers',
            'security_disable_xmlrpc',
            'security_block_bad_queries',
            'perf_defer_scripts',
            'perf_lazyload_images',
            'perf_cache_headers',
            'security_require_ssl_for_commerce',
            'mls_idx_provider',
        ]);
        $themePack = $this->themePackBySlug($themePackSlug);
        if ($themePack) {
            update_option('h4bs_global_design_tokens', $this->sanitizeThemePackTokens($themePack['tokens'] ?? []), false);
            update_option('h4bs_active_theme_pack', $themePackSlug, false);
        }

        update_option(
            'h4bs_setup_wizard_answers',
            [
                'business_type'       => $answers['business_type'],
                'needs_commerce'      => $answers['needs_commerce'] ? '1' : '0',
                'needs_standalone_payments' => $answers['needs_standalone_payments'] ? '1' : '0',
                'needs_invoice_tracking' => $answers['needs_invoice_tracking'] ? '1' : '0',
                'needs_subscriptions' => $answers['needs_subscriptions'] ? '1' : '0',
                'needs_lms'           => $answers['needs_lms'] ? '1' : '0',
                'needs_realtor'       => $answers['needs_realtor'] ? '1' : '0',
                'needs_contractor'    => $answers['needs_contractor'] ? '1' : '0',
                'needs_templates'     => $answers['needs_templates'] ? '1' : '0',
                'needs_seo'           => $answers['needs_seo'] ? '1' : '0',
                'needs_security'      => $answers['needs_security'] ? '1' : '0',
                'needs_performance'   => $answers['needs_performance'] ? '1' : '0',
                'needs_demo_showcase' => $answers['needs_demo_showcase'] ? '1' : '0',
                'theme_pack_slug'     => $themePackSlug,
            ]
        );
        update_option(self::WIZARD_DONE_OPTION, '1');
        if (is_multisite()) {
            update_site_option(self::WIZARD_DONE_OPTION, '1');
        }
        $this->setWizardBypassForCurrentUser();
        if ($answers['needs_demo_showcase']) {
            update_option('h4bs_seed_showcase_requested', '1');
        }

        set_transient(
            self::WIZARD_NOTICE_TRANSIENT,
            sprintf(
                /* translators: 1: number of seeded settings, 2: theme pack label */
                __('Setup wizard saved. Modules were tuned to your business profile, %1$d new recommended settings were added, and theme pack "%2$s" is now active.', 'help4-builder-suite'),
                count((array) ($profileReport['seeded'] ?? [])) + count((array) ($profileReport['refreshed'] ?? [])),
                (string) ($themePack['label'] ?? ucfirst(str_replace('-', ' ', $themePackSlug)))
            ),
            45
        );

        wp_safe_redirect(
            add_query_arg(
                [
                    'page' => 'h4bs-settings',
                    'h4bs_wizard_saved' => '1',
                ],
                admin_url('admin.php')
            )
        );
        exit;
    }

    public function handleApplyThemePack(): void
    {
        if (! current_user_can('manage_options')) {
            wp_die(esc_html__('Unauthorized request.', 'help4-builder-suite'));
        }
        check_admin_referer('h4bs_apply_theme_pack', 'h4bs_apply_theme_pack_nonce');

        $slug = sanitize_key((string) wp_unslash($_POST['theme_pack_slug'] ?? ''));
        $pack = $this->themePackBySlug($slug);
        if (! $pack) {
            set_transient(
                self::WIZARD_NOTICE_TRANSIENT,
                __('Theme pack not found. Pick another pack and try again.', 'help4-builder-suite'),
                45
            );
            wp_safe_redirect(admin_url('admin.php?page=h4bs-settings'));
            exit;
        }

        update_option('h4bs_global_design_tokens', $this->sanitizeThemePackTokens($pack['tokens'] ?? []), false);
        update_option('h4bs_active_theme_pack', $slug, false);
        set_transient(
            self::WIZARD_NOTICE_TRANSIENT,
            sprintf(
                /* translators: %s: theme pack label */
                __('Theme pack "%s" is now active site-wide.', 'help4-builder-suite'),
                (string) ($pack['label'] ?? $slug)
            ),
            45
        );

        wp_safe_redirect(admin_url('admin.php?page=h4bs-settings'));
        exit;
    }

    /**
     * @return array<string, array<string, mixed>>
     */
    public function siteLaunchProfiles(): array
    {
        $answerDefaults = $this->launchAnswerDefaults();
        $profiles = [
            'essential' => [
                'label' => __('Essential WordPress site', 'help4-builder-suite'),
                'description' => __('Builder, templates, forms, SEO, redirects, security, performance, images, and reporting without store or course overhead.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-speed-lite',
                'answers' => array_replace($answerDefaults, [
                    'business_type' => 'business',
                    'needs_templates' => true,
                    'needs_seo' => true,
                    'needs_security' => true,
                    'needs_performance' => true,
                ]),
                'settings' => $this->baseLaunchSettings(),
                'outcomes' => [
                    __('Build pages and theme parts visually.', 'help4-builder-suite'),
                    __('Collect leads and publish search-ready content.', 'help4-builder-suite'),
                    __('Apply safe performance, image, and security defaults.', 'help4-builder-suite'),
                ],
            ],
            'service_business' => [
                'label' => __('Service business', 'help4-builder-suite'),
                'description' => __('A conversion-focused stack for agencies, consultants, local services, contractors, and managed client sites.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-foundation',
                'answers' => array_replace($answerDefaults, [
                    'business_type' => 'agency',
                    'needs_templates' => true,
                    'needs_seo' => true,
                    'needs_security' => true,
                    'needs_performance' => true,
                    'needs_contractor' => true,
                ]),
                'settings' => $this->baseLaunchSettings(),
                'outcomes' => [
                    __('Launch service, proof, quote, intake, and contact journeys.', 'help4-builder-suite'),
                    __('Use structured customer and project fields.', 'help4-builder-suite'),
                    __('Keep search, forms, redirects, and reporting in one stack.', 'help4-builder-suite'),
                ],
            ],
            'commerce' => [
                'label' => __('Commerce and subscriptions', 'help4-builder-suite'),
                'description' => __('Native products, variations, customer data, promotions, tax, shipping, subscriptions, processors, search, and checkout presentation.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-commerce-neo',
                'answers' => array_replace($answerDefaults, [
                    'business_type' => 'store',
                    'needs_commerce' => true,
                    'needs_standalone_payments' => true,
                    'needs_invoice_tracking' => true,
                    'needs_subscriptions' => true,
                    'needs_templates' => true,
                    'needs_seo' => true,
                    'needs_security' => true,
                    'needs_performance' => true,
                ]),
                'settings' => array_replace($this->baseLaunchSettings(), [
                    'commerce_product_card_style' => 'overlay',
                    'commerce_product_hover' => 'quick_actions',
                    'commerce_product_columns_desktop' => '4',
                    'commerce_product_columns_tablet' => '2',
                    'commerce_product_columns_mobile' => '1',
                    'commerce_filter_style' => 'toolbar',
                    'security_require_ssl_for_commerce' => '1',
                ]),
                'outcomes' => [
                    __('Run catalog, checkout, customer, order, tax, and inventory workflows.', 'help4-builder-suite'),
                    __('Use configurable processors without loading every gateway everywhere.', 'help4-builder-suite'),
                    __('Start with responsive product and mobile-shopping defaults.', 'help4-builder-suite'),
                ],
            ],
            'membership_learning' => [
                'label' => __('Membership and learning', 'help4-builder-suite'),
                'description' => __('Courses, gated resources, video, progress, certificates, subscriptions, member dashboards, forms, and protected downloads.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-foundation',
                'answers' => array_replace($answerDefaults, [
                    'business_type' => 'education',
                    'needs_commerce' => true,
                    'needs_standalone_payments' => true,
                    'needs_subscriptions' => true,
                    'needs_lms' => true,
                    'needs_templates' => true,
                    'needs_seo' => true,
                    'needs_security' => true,
                    'needs_performance' => true,
                ]),
                'settings' => array_replace($this->baseLaunchSettings(), [
                    'commerce_product_card_style' => 'clean',
                    'commerce_product_columns_desktop' => '3',
                    'commerce_product_columns_tablet' => '2',
                    'commerce_product_columns_mobile' => '1',
                    'security_require_ssl_for_commerce' => '1',
                ]),
                'outcomes' => [
                    __('Sell access, subscriptions, courses, and protected resources.', 'help4-builder-suite'),
                    __('Use progress, video, certificate, and dashboard surfaces.', 'help4-builder-suite'),
                    __('Keep member intake and profile fields in the same data model.', 'help4-builder-suite'),
                ],
            ],
            'publisher' => [
                'label' => __('Publisher and knowledge hub', 'help4-builder-suite'),
                'description' => __('A search-first stack for editorial sites, documentation, resource libraries, local publications, and content businesses.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-speed-lite',
                'answers' => array_replace($answerDefaults, [
                    'business_type' => 'content',
                    'needs_templates' => true,
                    'needs_seo' => true,
                    'needs_security' => true,
                    'needs_performance' => true,
                ]),
                'settings' => $this->baseLaunchSettings(),
                'outcomes' => [
                    __('Create searchable content hubs and reusable editorial layouts.', 'help4-builder-suite'),
                    __('Manage schema, readability, redirects, and social presentation.', 'help4-builder-suite'),
                    __('Keep media and page delivery lean.', 'help4-builder-suite'),
                ],
            ],
            'complete_suite' => [
                'label' => __('Complete Help4 suite', 'help4-builder-suite'),
                'description' => __('Turn on the complete production feature catalog for teams that want Builder, commerce, LMS, industry packs, forms, SEO, security, performance, and operations together.', 'help4-builder-suite'),
                'theme_pack_slug' => 'help4-enterprise-dark',
                'enable_all' => true,
                'answers' => array_replace($answerDefaults, [
                    'business_type' => 'agency',
                    'needs_commerce' => true,
                    'needs_standalone_payments' => true,
                    'needs_invoice_tracking' => true,
                    'needs_subscriptions' => true,
                    'needs_lms' => true,
                    'needs_realtor' => true,
                    'needs_contractor' => true,
                    'needs_templates' => true,
                    'needs_seo' => true,
                    'needs_security' => true,
                    'needs_performance' => true,
                ]),
                'settings' => array_replace($this->baseLaunchSettings(), [
                    'commerce_product_card_style' => 'showcase',
                    'commerce_product_hover' => 'quick_actions',
                    'commerce_product_columns_desktop' => '4',
                    'commerce_product_columns_tablet' => '2',
                    'commerce_product_columns_mobile' => '1',
                    'commerce_filter_style' => 'drawer',
                    'security_require_ssl_for_commerce' => '1',
                ]),
                'outcomes' => [
                    __('Expose every production module from one installation.', 'help4-builder-suite'),
                    __('Keep frontend assets compartmentalized by actual page use.', 'help4-builder-suite'),
                    __('Use one admin stack for building, selling, teaching, ranking, and operating.', 'help4-builder-suite'),
                ],
            ],
        ];

        $profiles = apply_filters('h4bs_site_launch_profiles', $profiles);
        if (! is_array($profiles)) {
            return [];
        }

        $clean = [];
        foreach ($profiles as $profileSlug => $profile) {
            if (! is_array($profile)) {
                continue;
            }
            $slug = sanitize_key((string) ($profile['slug'] ?? $profileSlug));
            if ($slug === '') {
                continue;
            }
            $answers = array_replace($answerDefaults, is_array($profile['answers'] ?? null) ? $profile['answers'] : []);
            $answers['business_type'] = in_array((string) $answers['business_type'], ['business', 'agency', 'store', 'realtor', 'contractor', 'education', 'content'], true)
                ? (string) $answers['business_type']
                : 'business';
            foreach (array_keys($answerDefaults) as $answerKey) {
                if ($answerKey === 'business_type') {
                    continue;
                }
                $answers[$answerKey] = ! empty($answers[$answerKey]);
            }
            $outcomes = [];
            foreach (array_slice(is_array($profile['outcomes'] ?? null) ? $profile['outcomes'] : [], 0, 6) as $outcome) {
                $outcome = sanitize_text_field((string) $outcome);
                if ($outcome !== '') {
                    $outcomes[] = $outcome;
                }
            }
            $clean[$slug] = [
                'slug' => $slug,
                'label' => sanitize_text_field((string) ($profile['label'] ?? ucfirst(str_replace('_', ' ', $slug)))),
                'description' => sanitize_text_field((string) ($profile['description'] ?? '')),
                'theme_pack_slug' => sanitize_key((string) ($profile['theme_pack_slug'] ?? 'help4-foundation')),
                'enable_all' => ! empty($profile['enable_all']),
                'answers' => $answers,
                'settings' => $this->normalizeLaunchSettingsPatch($profile['settings'] ?? []),
                'outcomes' => $outcomes,
            ];
        }

        return $clean;
    }

    /**
     * @return array<string, mixed>|\WP_Error
     */
    public function buildSiteLaunchPlan(string $profileSlug)
    {
        $profile = $this->siteLaunchProfileBySlug($profileSlug);
        if (! $profile) {
            return new \WP_Error('h4bs_launch_profile', __('Choose a valid Help4 launch profile.', 'help4-builder-suite'));
        }

        $answers = is_array($profile['answers'] ?? null) ? $profile['answers'] : $this->launchAnswerDefaults();
        $flags = $this->buildFeaturePlan($answers);
        if (! empty($profile['enable_all'])) {
            foreach ($this->featureFlags->defaults() as $key => $default) {
                $flags[$key] = true;
            }
            $flags['licensing'] = true;
            $flags['release_bridge'] = false;
            $flags['demos'] = false;
        }
        if (array_key_exists('dependency', $flags)) {
            $flags['dependency'] = true;
        }

        return [
            'schema' => 'h4bs/site-launch-plan',
            'schema_version' => 1,
            'profile' => $profile,
            'feature_flags' => $flags,
            'settings' => is_array($profile['settings'] ?? null) ? $profile['settings'] : [],
            'theme_pack_slug' => sanitize_key((string) ($profile['theme_pack_slug'] ?? 'help4-foundation')),
        ];
    }

    /**
     * @return array<int, array<string, string>>
     */
    public function siteLaunchReadinessChecks(): array
    {
        $upload = wp_upload_dir(null, false, false);
        $uploadWritable = empty($upload['error'])
            && isset($upload['basedir'])
            && is_string($upload['basedir'])
            && is_dir($upload['basedir'])
            && wp_is_writable($upload['basedir']);
        $memoryLimit = wp_convert_hr_to_bytes((string) ini_get('memory_limit'));
        $memoryReady = $memoryLimit === -1 || $memoryLimit >= 256 * MB_IN_BYTES;
        $httpsReady = is_ssl() || str_starts_with(strtolower(home_url('/')), 'https://');
        $prettyPermalinks = (string) get_option('permalink_structure', '') !== '';
        $cronReady = ! (defined('DISABLE_WP_CRON') && (bool) constant('DISABLE_WP_CRON'));
        $siteTitleReady = trim((string) get_option('blogname', '')) !== '';
        $searchVisible = (string) get_option('blog_public', '1') === '1';
        $theme = wp_get_theme('help4-blank');
        $themeInstalled = $theme->exists();
        $themeActive = $themeInstalled && get_stylesheet() === 'help4-blank';
        $themeAction = '';
        $themeActionLabel = '';
        if (current_user_can('switch_themes') && ! $themeActive) {
            $themeActionName = $themeInstalled ? 'h4bs_dependency_activate_theme' : 'h4bs_dependency_install_theme';
            $themeAction = wp_nonce_url(admin_url('admin-post.php?action=' . $themeActionName), $themeActionName);
            $themeActionLabel = $themeInstalled
                ? __('Activate Help4 Blank', 'help4-builder-suite')
                : __('Install Help4 Blank', 'help4-builder-suite');
        }

        $checks = [
            [
                'key' => 'wordpress',
                'label' => __('Supported WordPress core', 'help4-builder-suite'),
                'status' => version_compare(get_bloginfo('version'), '6.5', '>=') ? 'pass' : 'fail',
                'detail' => sprintf(
                    /* translators: %s: current WordPress version */
                    __('WordPress %s is installed.', 'help4-builder-suite'),
                    get_bloginfo('version')
                ),
                'action_url' => admin_url('update-core.php'),
                'action_label' => __('Open updates', 'help4-builder-suite'),
            ],
            [
                'key' => 'https',
                'label' => __('HTTPS site address', 'help4-builder-suite'),
                'status' => $httpsReady ? 'pass' : 'warn',
                'detail' => $httpsReady
                    ? __('The public site address uses HTTPS.', 'help4-builder-suite')
                    : __('Enable HTTPS before accepting logins or payments.', 'help4-builder-suite'),
                'action_url' => admin_url('options-general.php'),
                'action_label' => __('Open general settings', 'help4-builder-suite'),
            ],
            [
                'key' => 'permalinks',
                'label' => __('Readable permalinks', 'help4-builder-suite'),
                'status' => $prettyPermalinks ? 'pass' : 'warn',
                'detail' => $prettyPermalinks
                    ? __('Pretty permalinks are configured.', 'help4-builder-suite')
                    : __('Choose a readable permalink structure before publishing.', 'help4-builder-suite'),
                'action_url' => admin_url('options-permalink.php'),
                'action_label' => __('Open permalinks', 'help4-builder-suite'),
            ],
            [
                'key' => 'uploads',
                'label' => __('Writable media directory', 'help4-builder-suite'),
                'status' => $uploadWritable ? 'pass' : 'fail',
                'detail' => $uploadWritable
                    ? __('WordPress can write uploaded media and generated derivatives.', 'help4-builder-suite')
                    : sanitize_text_field((string) ($upload['error'] ?? __('The uploads directory is not writable.', 'help4-builder-suite'))),
                'action_url' => admin_url('site-health.php'),
                'action_label' => __('Open Site Health', 'help4-builder-suite'),
            ],
            [
                'key' => 'memory',
                'label' => __('Working memory budget', 'help4-builder-suite'),
                'status' => $memoryReady ? 'pass' : 'warn',
                'detail' => $memoryLimit === -1
                    ? __('PHP memory is unlimited for this request.', 'help4-builder-suite')
                    : sprintf(
                        /* translators: %s: PHP memory limit */
                        __('PHP memory limit is %s.', 'help4-builder-suite'),
                        size_format($memoryLimit)
                    ),
                'action_url' => admin_url('site-health.php?tab=debug'),
                'action_label' => __('Open technical details', 'help4-builder-suite'),
            ],
            [
                'key' => 'cron',
                'label' => __('Scheduled tasks', 'help4-builder-suite'),
                'status' => $cronReady ? 'pass' : 'warn',
                'detail' => $cronReady
                    ? __('WordPress scheduled tasks are available.', 'help4-builder-suite')
                    : __('WP-Cron is disabled; confirm a real server cron is configured.', 'help4-builder-suite'),
                'action_url' => admin_url('site-health.php'),
                'action_label' => __('Open Site Health', 'help4-builder-suite'),
            ],
            [
                'key' => 'identity',
                'label' => __('Site identity', 'help4-builder-suite'),
                'status' => $siteTitleReady ? 'pass' : 'warn',
                'detail' => $siteTitleReady
                    ? __('The site title is available to Builder and schema defaults.', 'help4-builder-suite')
                    : __('Add the real site name before generating schema and social previews.', 'help4-builder-suite'),
                'action_url' => admin_url('options-general.php'),
                'action_label' => __('Edit site identity', 'help4-builder-suite'),
            ],
            [
                'key' => 'visibility',
                'label' => __('Search visibility', 'help4-builder-suite'),
                'status' => $searchVisible ? 'pass' : 'warn',
                'detail' => $searchVisible
                    ? __('Search engines are allowed to index the site.', 'help4-builder-suite')
                    : __('Search indexing is discouraged. Keep this for staging, then enable it at launch.', 'help4-builder-suite'),
                'action_url' => admin_url('options-reading.php'),
                'action_label' => __('Open reading settings', 'help4-builder-suite'),
            ],
            [
                'key' => 'theme',
                'label' => __('Companion blank theme', 'help4-builder-suite'),
                'status' => $themeActive ? 'pass' : 'warn',
                'detail' => $themeActive
                    ? __('Help4 Blank is active as the clean Builder shell.', 'help4-builder-suite')
                    : __('The plugin works with other themes; Help4 Blank provides the cleanest starting shell.', 'help4-builder-suite'),
                'action_url' => $themeAction,
                'action_label' => $themeActionLabel,
            ],
        ];

        $checks = apply_filters('h4bs_site_launch_readiness_checks', $checks);
        if (! is_array($checks)) {
            return [];
        }

        $clean = [];
        foreach ($checks as $check) {
            if (! is_array($check)) {
                continue;
            }
            $key = sanitize_key((string) ($check['key'] ?? ''));
            $label = sanitize_text_field((string) ($check['label'] ?? ''));
            if ($key === '' || $label === '') {
                continue;
            }
            $status = sanitize_key((string) ($check['status'] ?? 'warn'));
            if (! in_array($status, ['pass', 'warn', 'fail'], true)) {
                $status = 'warn';
            }
            $clean[] = [
                'key' => $key,
                'label' => $label,
                'status' => $status,
                'detail' => sanitize_text_field((string) ($check['detail'] ?? '')),
                'action_url' => esc_url_raw((string) ($check['action_url'] ?? '')),
                'action_label' => sanitize_text_field((string) ($check['action_label'] ?? '')),
            ];
        }

        return $clean;
    }

    public function handleApplySiteLaunchProfile(): void
    {
        if (! current_user_can('manage_options')) {
            wp_die(esc_html__('Unauthorized request.', 'help4-builder-suite'));
        }
        check_admin_referer('h4bs_apply_site_launch_profile', 'h4bs_site_launch_nonce');

        $post = wp_unslash($_POST);
        $profileSlug = sanitize_key((string) ($post['profile_slug'] ?? ''));
        $submittedHash = sanitize_text_field((string) ($post['state_hash'] ?? ''));
        $plan = $this->buildSiteLaunchPlan($profileSlug);
        if (is_wp_error($plan)) {
            set_transient(self::WIZARD_NOTICE_TRANSIENT, $plan->get_error_message(), 45);
            wp_safe_redirect(admin_url('admin.php?page=h4bs-settings'));
            exit;
        }

        $stateBefore = $this->siteLaunchStateHash();
        if ($submittedHash === '' || ! hash_equals($stateBefore, $submittedHash)) {
            set_transient(
                self::WIZARD_NOTICE_TRANSIENT,
                __('The site configuration changed after this Launch Center screen loaded. Review the current settings and apply the profile again.', 'help4-builder-suite'),
                45
            );
            wp_safe_redirect(admin_url('admin.php?page=h4bs-settings'));
            exit;
        }

        $settingsPatch = is_array($plan['settings'] ?? null) ? $plan['settings'] : [];
        $snapshot = $this->createSiteLaunchSnapshot($profileSlug, array_keys($settingsPatch), $stateBefore);
        update_option(self::LAUNCH_SNAPSHOT_OPTION, $snapshot, false);

        $featureFlags = is_array($plan['feature_flags'] ?? null) ? $plan['feature_flags'] : [];
        update_option(FeatureFlags::OPTION_KEY, $featureFlags, false);

        $settings = Settings::all();
        foreach ($settingsPatch as $key => $value) {
            $settings[$key] = $value;
        }
        foreach (Settings::lockedEndpointDefaults() as $key => $value) {
            $settings[$key] = $value;
        }
        update_option(Settings::OPTION_KEY, $settings, false);

        $themePackSlug = sanitize_key((string) ($plan['theme_pack_slug'] ?? 'help4-foundation'));
        $themePack = $this->themePackBySlug($themePackSlug);
        if ($themePack) {
            update_option('h4bs_global_design_tokens', $this->sanitizeThemePackTokens($themePack['tokens'] ?? []), false);
            update_option('h4bs_active_theme_pack', $themePackSlug, false);
        }

        $profile = is_array($plan['profile'] ?? null) ? $plan['profile'] : [];
        $answers = is_array($profile['answers'] ?? null) ? $profile['answers'] : $this->launchAnswerDefaults();
        $businessType = BusinessProfileDefaults::rememberProfile((string) ($answers['business_type'] ?? 'business'));
        $savedAnswers = ['business_type' => $businessType];
        foreach ($answers as $key => $value) {
            if ($key === 'business_type') {
                continue;
            }
            $savedAnswers[sanitize_key((string) $key)] = ! empty($value) ? '1' : '0';
        }
        $savedAnswers['theme_pack_slug'] = $themePackSlug;
        $savedAnswers['site_launch_profile'] = $profileSlug;
        update_option('h4bs_setup_wizard_answers', $savedAnswers, false);
        update_option(self::WIZARD_DONE_OPTION, '1', false);
        if (is_multisite()) {
            update_site_option(self::WIZARD_DONE_OPTION, '1');
        }

        $stateAfter = $this->siteLaunchStateHash();
        $snapshot['state_after'] = $stateAfter;
        update_option(self::LAUNCH_SNAPSHOT_OPTION, $snapshot, false);

        $enabledModules = array_keys(array_filter($featureFlags));
        $report = [
            'schema' => 'h4bs/site-launch-report',
            'schema_version' => 1,
            'profile_slug' => $profileSlug,
            'profile_label' => sanitize_text_field((string) ($profile['label'] ?? $profileSlug)),
            'theme_pack_slug' => $themePackSlug,
            'enabled_modules' => $enabledModules,
            'enabled_module_count' => count($enabledModules),
            'changed_setting_keys' => array_values(array_map('sanitize_key', array_keys($settingsPatch))),
            'state_before' => $stateBefore,
            'state_after' => $stateAfter,
            'snapshot_id' => sanitize_text_field((string) ($snapshot['id'] ?? '')),
            'applied_at' => gmdate('c'),
            'applied_by' => get_current_user_id(),
        ];
        update_option(self::LAUNCH_REPORT_OPTION, $report, false);

        do_action('h4bs_site_launch_profile_applied', $profileSlug, $plan, $report);
        set_transient(
            self::WIZARD_NOTICE_TRANSIENT,
            sprintf(
                /* translators: 1: profile label, 2: number of enabled modules */
                __('Launch profile "%1$s" applied with %2$d modules. A one-click rollback snapshot is available below.', 'help4-builder-suite'),
                (string) ($report['profile_label'] ?? $profileSlug),
                count($enabledModules)
            ),
            45
        );
        $this->setWizardBypassForCurrentUser(900);

        wp_safe_redirect(admin_url('admin.php?page=h4bs-settings&h4bs_launch_applied=1'));
        exit;
    }

    public function handleRestoreSiteLaunchSnapshot(): void
    {
        if (! current_user_can('manage_options')) {
            wp_die(esc_html__('Unauthorized request.', 'help4-builder-suite'));
        }
        check_admin_referer('h4bs_restore_site_launch_snapshot', 'h4bs_site_launch_restore_nonce');

        $snapshot = get_option(self::LAUNCH_SNAPSHOT_OPTION, []);
        $snapshot = is_array($snapshot) ? $snapshot : [];
        $snapshotId = sanitize_text_field((string) wp_unslash($_POST['snapshot_id'] ?? ''));
        if ($snapshotId === '' || ! hash_equals((string) ($snapshot['id'] ?? ''), $snapshotId)) {
            set_transient(self::WIZARD_NOTICE_TRANSIENT, __('The launch rollback snapshot is no longer available.', 'help4-builder-suite'), 45);
            wp_safe_redirect(admin_url('admin.php?page=h4bs-settings'));
            exit;
        }

        $expectedState = sanitize_text_field((string) ($snapshot['state_after'] ?? ''));
        if ($expectedState === '' || ! hash_equals($expectedState, $this->siteLaunchStateHash())) {
            set_transient(
                self::WIZARD_NOTICE_TRANSIENT,
                __('Rollback stopped because settings changed after the profile was applied. This prevents an older snapshot from overwriting newer work.', 'help4-builder-suite'),
                45
            );
            wp_safe_redirect(admin_url('admin.php?page=h4bs-settings'));
            exit;
        }

        $this->restoreLaunchOptionSnapshot(FeatureFlags::OPTION_KEY, $snapshot['feature_flags'] ?? []);
        $this->restoreLaunchOptionSnapshot('h4bs_global_design_tokens', $snapshot['design_tokens'] ?? []);
        $this->restoreLaunchOptionSnapshot('h4bs_active_theme_pack', $snapshot['active_theme_pack'] ?? []);
        $this->restoreLaunchOptionSnapshot('h4bs_setup_wizard_answers', $snapshot['wizard_answers'] ?? []);
        $this->restoreLaunchOptionSnapshot(self::WIZARD_DONE_OPTION, $snapshot['wizard_done'] ?? []);
        $this->restoreLaunchOptionSnapshot(BusinessProfileDefaults::PROFILE_OPTION, $snapshot['business_profile'] ?? []);
        $this->restoreLaunchOptionSnapshot(BusinessProfileDefaults::SEED_STATE_OPTION, $snapshot['business_profile_seed_state'] ?? []);

        $settings = get_option(Settings::OPTION_KEY, []);
        $settings = is_array($settings) ? $settings : [];
        $settingsBefore = is_array($snapshot['settings_before'] ?? null) ? $snapshot['settings_before'] : [];
        $settingsPresent = array_fill_keys(
            array_values(array_filter(array_map('sanitize_key', is_array($snapshot['settings_present'] ?? null) ? $snapshot['settings_present'] : []))),
            true
        );
        foreach (array_values(array_filter(array_map('sanitize_key', is_array($snapshot['settings_keys'] ?? null) ? $snapshot['settings_keys'] : []))) as $key) {
            if (isset($settingsPresent[$key])) {
                $settings[$key] = $settingsBefore[$key] ?? '';
            } else {
                unset($settings[$key]);
            }
        }
        foreach (Settings::lockedEndpointDefaults() as $key => $value) {
            $settings[$key] = $value;
        }
        update_option(Settings::OPTION_KEY, $settings, false);

        $report = get_option(self::LAUNCH_REPORT_OPTION, []);
        $report = is_array($report) ? $report : [];
        $report['restored_at'] = gmdate('c');
        $report['restored_by'] = get_current_user_id();
        $report['restored_state'] = $this->siteLaunchStateHash();
        update_option(self::LAUNCH_REPORT_OPTION, $report, false);
        delete_option(self::LAUNCH_SNAPSHOT_OPTION);

        do_action('h4bs_site_launch_profile_restored', $snapshot, $report);
        set_transient(self::WIZARD_NOTICE_TRANSIENT, __('The previous Help4 module, settings, and design-token state has been restored.', 'help4-builder-suite'), 45);
        wp_safe_redirect(admin_url('admin.php?page=h4bs-settings'));
        exit;
    }

    public function siteLaunchStateHash(): string
    {
        $settings = Settings::all();
        $safeSettings = [];
        foreach ($this->launchSettingsAllowlist() as $key) {
            if (array_key_exists($key, $settings)) {
                $safeSettings[$key] = $settings[$key];
            }
        }
        $businessProfileState = get_option(BusinessProfileDefaults::SEED_STATE_OPTION, []);
        $businessProfileState = is_array($businessProfileState) ? $businessProfileState : [];
        $businessProfileState = array_intersect_key(
            $businessProfileState,
            array_fill_keys(['schema', 'schema_version', 'profile_slug', 'catalog_hash', 'managed', 'user_owned_keys'], true)
        );
        $payload = [
            'feature_flags' => $this->featureFlags->all(),
            'settings' => $safeSettings,
            'design_tokens' => get_option('h4bs_global_design_tokens', []),
            'active_theme_pack' => get_option('h4bs_active_theme_pack', ''),
            'wizard_answers' => get_option('h4bs_setup_wizard_answers', []),
            'wizard_done' => get_option(self::WIZARD_DONE_OPTION, '0'),
            'business_profile' => get_option(BusinessProfileDefaults::PROFILE_OPTION, ''),
            'business_profile_seed_state' => $businessProfileState,
        ];
        $encoded = wp_json_encode($payload, JSON_UNESCAPED_SLASHES);

        return hash('sha256', is_string($encoded) ? $encoded : serialize($payload));
    }

    /**
     * @return array<string, mixed>
     */
    private function launchAnswerDefaults(): array
    {
        return [
            'business_type' => 'business',
            'needs_commerce' => false,
            'needs_standalone_payments' => false,
            'needs_invoice_tracking' => false,
            'needs_subscriptions' => false,
            'needs_lms' => false,
            'needs_realtor' => false,
            'needs_contractor' => false,
            'needs_templates' => false,
            'needs_seo' => false,
            'needs_security' => false,
            'needs_performance' => false,
            'needs_demo_showcase' => false,
        ];
    }

    /**
     * @return array<string, string>
     */
    private function baseLaunchSettings(): array
    {
        return [
            'security_enable_headers' => '1',
            'security_disable_xmlrpc' => '1',
            'security_block_bad_queries' => '1',
            'security_hide_wp_version' => '1',
            'perf_defer_scripts' => '1',
            'perf_lazyload_images' => '1',
            'perf_cache_headers' => '1',
            'perf_integrate_litespeed' => '1',
            'perf_integrate_w3tc' => '1',
            'perf_integrate_redis' => '1',
            'image_opt_enable' => '1',
            'image_opt_generate_webp' => '1',
            'image_opt_enhance_uploaded' => '0',
            'igor_feedback_enabled' => '1',
            'commerce_show_product_image' => '1',
            'commerce_show_quick_view' => '1',
            'commerce_show_compare_action' => '1',
            'commerce_show_stock_badge' => '1',
            'commerce_show_sku' => '1',
            'commerce_show_product_type_badges' => '1',
            'commerce_sticky_mobile_toolbar' => '1',
            'commerce_show_price_watch_prompt' => '1',
            'commerce_show_waitlist_prompt' => '1',
        ];
    }

    /**
     * @return array<int, string>
     */
    private function launchSettingsAllowlist(): array
    {
        return [
            'security_enable_headers',
            'security_disable_xmlrpc',
            'security_block_bad_queries',
            'security_hide_wp_version',
            'security_require_ssl_for_commerce',
            'perf_defer_scripts',
            'perf_lazyload_images',
            'perf_cache_headers',
            'perf_integrate_litespeed',
            'perf_integrate_w3tc',
            'perf_integrate_redis',
            'image_opt_enable',
            'image_opt_generate_webp',
            'image_opt_enhance_uploaded',
            'igor_feedback_enabled',
            'commerce_product_card_style',
            'commerce_product_hover',
            'commerce_product_columns_desktop',
            'commerce_product_columns_tablet',
            'commerce_product_columns_mobile',
            'commerce_filter_style',
            'commerce_show_product_image',
            'commerce_show_quick_view',
            'commerce_show_compare_action',
            'commerce_show_stock_badge',
            'commerce_show_sku',
            'commerce_show_product_type_badges',
            'commerce_sticky_mobile_toolbar',
            'commerce_show_price_watch_prompt',
            'commerce_show_waitlist_prompt',
        ];
    }

    /**
     * @param mixed $raw
     * @return array<string, string>
     */
    private function normalizeLaunchSettingsPatch($raw): array
    {
        $raw = is_array($raw) ? $raw : [];
        $allow = array_fill_keys($this->launchSettingsAllowlist(), true);
        $boolKeys = array_fill_keys([
            'security_enable_headers',
            'security_disable_xmlrpc',
            'security_block_bad_queries',
            'security_hide_wp_version',
            'security_require_ssl_for_commerce',
            'perf_defer_scripts',
            'perf_lazyload_images',
            'perf_cache_headers',
            'perf_integrate_litespeed',
            'perf_integrate_w3tc',
            'perf_integrate_redis',
            'image_opt_enable',
            'image_opt_generate_webp',
            'image_opt_enhance_uploaded',
            'igor_feedback_enabled',
            'commerce_show_product_image',
            'commerce_show_quick_view',
            'commerce_show_compare_action',
            'commerce_show_stock_badge',
            'commerce_show_sku',
            'commerce_show_product_type_badges',
            'commerce_sticky_mobile_toolbar',
            'commerce_show_price_watch_prompt',
            'commerce_show_waitlist_prompt',
        ], true);
        $clean = [];
        foreach ($raw as $key => $value) {
            $key = sanitize_key((string) $key);
            if (! isset($allow[$key])) {
                continue;
            }
            if (isset($boolKeys[$key])) {
                $clean[$key] = rest_sanitize_boolean($value) ? '1' : '0';
                continue;
            }
            if ($key === 'commerce_product_card_style') {
                $value = sanitize_key((string) $value);
                $clean[$key] = in_array($value, ['clean', 'overlay', 'compact', 'list', 'showcase'], true) ? $value : 'overlay';
                continue;
            }
            if ($key === 'commerce_product_hover') {
                $value = sanitize_key((string) $value);
                $clean[$key] = in_array($value, ['none', 'lift', 'image_zoom', 'quick_actions'], true) ? $value : 'lift';
                continue;
            }
            if ($key === 'commerce_filter_style') {
                $value = sanitize_key((string) $value);
                $clean[$key] = in_array($value, ['toolbar', 'compact', 'drawer'], true) ? $value : 'toolbar';
                continue;
            }
            if ($key === 'commerce_product_columns_desktop') {
                $clean[$key] = (string) max(1, min(6, (int) $value));
                continue;
            }
            if ($key === 'commerce_product_columns_tablet') {
                $clean[$key] = (string) max(1, min(4, (int) $value));
                continue;
            }
            if ($key === 'commerce_product_columns_mobile') {
                $clean[$key] = (string) max(1, min(2, (int) $value));
            }
        }

        return $clean;
    }

    /**
     * @return array<string, mixed>|null
     */
    private function siteLaunchProfileBySlug(string $profileSlug): ?array
    {
        $profileSlug = sanitize_key($profileSlug);
        $profiles = $this->siteLaunchProfiles();

        return isset($profiles[$profileSlug]) && is_array($profiles[$profileSlug]) ? $profiles[$profileSlug] : null;
    }

    /**
     * @param array<int, string> $settingsKeys
     * @return array<string, mixed>
     */
    private function createSiteLaunchSnapshot(string $profileSlug, array $settingsKeys, string $stateBefore): array
    {
        $rawSettings = get_option(Settings::OPTION_KEY, []);
        $rawSettings = is_array($rawSettings) ? $rawSettings : [];
        $allowedSettings = array_fill_keys($this->launchSettingsAllowlist(), true);
        $settingsKeys = array_values(array_filter(
            array_map('sanitize_key', $settingsKeys),
            static fn (string $key): bool => isset($allowedSettings[$key])
        ));
        $settingsBefore = [];
        $settingsPresent = [];
        foreach ($settingsKeys as $key) {
            if (! array_key_exists($key, $rawSettings)) {
                continue;
            }
            $settingsBefore[$key] = $rawSettings[$key];
            $settingsPresent[] = $key;
        }

        return [
            'schema' => 'h4bs/site-launch-snapshot',
            'schema_version' => 1,
            'id' => wp_generate_uuid4(),
            'profile_slug' => sanitize_key($profileSlug),
            'created_at' => gmdate('c'),
            'created_by' => get_current_user_id(),
            'state_before' => $stateBefore,
            'state_after' => '',
            'feature_flags' => $this->captureLaunchOption(FeatureFlags::OPTION_KEY),
            'design_tokens' => $this->captureLaunchOption('h4bs_global_design_tokens'),
            'active_theme_pack' => $this->captureLaunchOption('h4bs_active_theme_pack'),
            'wizard_answers' => $this->captureLaunchOption('h4bs_setup_wizard_answers'),
            'wizard_done' => $this->captureLaunchOption(self::WIZARD_DONE_OPTION),
            'business_profile' => $this->captureLaunchOption(BusinessProfileDefaults::PROFILE_OPTION),
            'business_profile_seed_state' => $this->captureLaunchOption(BusinessProfileDefaults::SEED_STATE_OPTION),
            'settings_keys' => $settingsKeys,
            'settings_present' => $settingsPresent,
            'settings_before' => $settingsBefore,
        ];
    }

    /**
     * @return array{exists:bool,value:mixed}
     */
    private function captureLaunchOption(string $optionKey): array
    {
        $sentinel = '__h4bs_missing_' . wp_generate_uuid4();
        $value = get_option($optionKey, $sentinel);

        return [
            'exists' => $value !== $sentinel,
            'value' => $value === $sentinel ? null : $value,
        ];
    }

    /**
     * @param mixed $snapshot
     */
    private function restoreLaunchOptionSnapshot(string $optionKey, $snapshot): void
    {
        $snapshot = is_array($snapshot) ? $snapshot : [];
        if (! empty($snapshot['exists'])) {
            update_option($optionKey, $snapshot['value'] ?? '', false);
            return;
        }
        delete_option($optionKey);
    }

    /**
     * @param array<string, mixed> $answers
     * @return array<string, bool>
     */
    private function buildFeaturePlan(array $answers): array
    {
        $plan = [];
        foreach ($this->featureFlags->defaults() as $key => $default) {
            $plan[$key] = false;
        }

        $alwaysOn = [
            'builder',
            'addon_pack',
            'template_library',
            'forms',
            'redirection',
            'security',
            'performance',
            'image_optimization',
            'insights',
            'cutover',
            'feedback',
            'dependency',
        ];
        foreach ($alwaysOn as $key) {
            if (array_key_exists($key, $plan)) {
                $plan[$key] = true;
            }
        }

        if (! empty($answers['needs_templates'])) {
            $plan['template_library'] = true;
            $plan['mega_menu'] = true;
            $plan['slider'] = true;
            $plan['fields'] = true;
        }

        if (! empty($answers['needs_seo'])) {
            $plan['seo'] = true;
            $plan['search'] = true;
        }

        $needsCommerceStack = ! empty($answers['needs_commerce'])
            || ! empty($answers['needs_standalone_payments'])
            || ! empty($answers['needs_invoice_tracking'])
            || ! empty($answers['needs_subscriptions'])
            || (string) ($answers['business_type'] ?? '') === 'store';
        if ($needsCommerceStack) {
            $plan['commerce'] = true;
            $plan['search'] = true;
            $plan['slider'] = true;
            $plan['fields'] = true;
        }

        if (! empty($answers['needs_lms'])) {
            $plan['lms'] = true;
            $plan['fields'] = true;
        }

        if (! empty($answers['needs_realtor']) || (string) ($answers['business_type'] ?? '') === 'realtor') {
            $plan['industry'] = true;
            $plan['fields'] = true;
            $plan['search'] = true;
            $plan['mega_menu'] = true;
        }

        if (! empty($answers['needs_contractor']) || (string) ($answers['business_type'] ?? '') === 'contractor') {
            $plan['industry'] = true;
            $plan['fields'] = true;
            $plan['search'] = true;
        }

        $businessType = (string) ($answers['business_type'] ?? 'business');
        if ($businessType === 'agency' || $businessType === 'business') {
            $plan['template_library'] = true;
            $plan['slider'] = true;
            $plan['fields'] = true;
            $plan['seo'] = true;
        }
        if ($businessType === 'content') {
            $plan['seo'] = true;
            $plan['search'] = true;
            $plan['slider'] = true;
        }
        if ($businessType === 'education') {
            $plan['lms'] = true;
            $plan['fields'] = true;
            $plan['template_library'] = true;
        }

        if (! empty($answers['needs_security'])) {
            $plan['security'] = true;
        }
        if (! empty($answers['needs_performance'])) {
            $plan['performance'] = true;
            $plan['image_optimization'] = true;
            $plan['insights'] = true;
        }

        // Updates are core infrastructure and remain enabled for every profile.
        $plan['licensing'] = true;

        return $plan;
    }

    public function renderWizardNotice(): void
    {
        if (! current_user_can('manage_options')) {
            return;
        }
        $notice = get_transient(self::WIZARD_NOTICE_TRANSIENT);
        if (! is_string($notice) || $notice === '') {
            return;
        }
        delete_transient(self::WIZARD_NOTICE_TRANSIENT);
        printf('<div class="notice notice-success is-dismissible"><p>%s</p></div>', esc_html($notice));
    }

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

        $saved = get_option('h4bs_setup_wizard_answers', []);
        $saved = is_array($saved) ? $saved : [];
        $businessProfiles = BusinessProfileDefaults::catalog();
        $selectedBusinessType = sanitize_key((string) ($saved['business_type'] ?? BusinessProfileDefaults::selectedSlug()));
        if (! isset($businessProfiles[$selectedBusinessType])) {
            $selectedBusinessType = BusinessProfileDefaults::selectedSlug();
        }
        $recommendedAnswers = BusinessProfileDefaults::wizardDefaults($selectedBusinessType);
        $themePacks = $this->themePackCatalog();
        $activeThemePack = $this->activeThemePackSlug();
        $defaults = [
            'business_type'       => $selectedBusinessType,
            'needs_commerce'      => array_key_exists('needs_commerce', $saved) ? (string) $saved['needs_commerce'] === '1' : ! empty($recommendedAnswers['needs_commerce']),
            'needs_standalone_payments' => array_key_exists('needs_standalone_payments', $saved) ? (string) $saved['needs_standalone_payments'] === '1' : ! empty($recommendedAnswers['needs_standalone_payments']),
            'needs_invoice_tracking' => array_key_exists('needs_invoice_tracking', $saved) ? (string) $saved['needs_invoice_tracking'] === '1' : ! empty($recommendedAnswers['needs_invoice_tracking']),
            'needs_subscriptions' => array_key_exists('needs_subscriptions', $saved) ? (string) $saved['needs_subscriptions'] === '1' : ! empty($recommendedAnswers['needs_subscriptions']),
            'needs_lms'           => array_key_exists('needs_lms', $saved) ? (string) $saved['needs_lms'] === '1' : ! empty($recommendedAnswers['needs_lms']),
            'needs_realtor'       => array_key_exists('needs_realtor', $saved) ? (string) $saved['needs_realtor'] === '1' : ! empty($recommendedAnswers['needs_realtor']),
            'needs_contractor'    => array_key_exists('needs_contractor', $saved) ? (string) $saved['needs_contractor'] === '1' : ! empty($recommendedAnswers['needs_contractor']),
            'needs_templates'     => array_key_exists('needs_templates', $saved) ? (string) $saved['needs_templates'] === '1' : ! empty($recommendedAnswers['needs_templates']),
            'needs_seo'           => array_key_exists('needs_seo', $saved) ? (string) $saved['needs_seo'] === '1' : ! empty($recommendedAnswers['needs_seo']),
            'needs_security'      => array_key_exists('needs_security', $saved) ? (string) $saved['needs_security'] === '1' : ! empty($recommendedAnswers['needs_security']),
            'needs_performance'   => array_key_exists('needs_performance', $saved) ? (string) $saved['needs_performance'] === '1' : ! empty($recommendedAnswers['needs_performance']),
            'needs_demo_showcase' => array_key_exists('needs_demo_showcase', $saved) ? (string) $saved['needs_demo_showcase'] === '1' : ! empty($recommendedAnswers['needs_demo_showcase']),
            'theme_pack_slug'     => sanitize_key((string) ($saved['theme_pack_slug'] ?? $activeThemePack)),
        ];
        if ($defaults['theme_pack_slug'] === '' || ! $this->themePackBySlug($defaults['theme_pack_slug'])) {
            $defaults['theme_pack_slug'] = BusinessProfileDefaults::themePackSlug($defaults['business_type']);
        }
        $profileClientData = [];
        foreach ($businessProfiles as $profileSlug => $profile) {
            $profileClientData[$profileSlug] = [
                'description' => (string) ($profile['description'] ?? ''),
                'themePack' => (string) ($profile['theme_pack_slug'] ?? 'help4-foundation'),
                'wizard' => BusinessProfileDefaults::wizardDefaults((string) $profileSlug),
            ];
        }
        ?>
        <div class="wrap h4bs-admin-wrap">
            <h1><?php esc_html_e('Help4 Builder Setup Wizard', 'help4-builder-suite'); ?></h1>
            <p><?php esc_html_e('Answer a few project questions and we will auto-enable only the modules your site needs.', 'help4-builder-suite'); ?></p>
            <?php $this->renderSiteLaunchCenter(true); ?>
            <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
                <?php wp_nonce_field('h4bs_setup_wizard', 'h4bs_setup_wizard_nonce'); ?>
                <input type="hidden" name="action" value="h4bs_setup_wizard">
                <table class="form-table" role="presentation">
                    <tbody>
                        <tr>
                            <th scope="row"><?php esc_html_e('What are you building?', 'help4-builder-suite'); ?></th>
                            <td>
                                <select id="h4bs-business-profile" name="business_type">
                                    <?php foreach ($businessProfiles as $key => $profile) : ?>
                                        <option value="<?php echo esc_attr((string) $key); ?>" <?php selected($defaults['business_type'], $key); ?>><?php echo esc_html((string) ($profile['label'] ?? $key)); ?></option>
                                    <?php endforeach; ?>
                                </select>
                                <p id="h4bs-business-profile-description" class="description" aria-live="polite"><?php echo esc_html((string) ($businessProfiles[$defaults['business_type']]['description'] ?? '')); ?></p>
                                <p>
                                    <button id="h4bs-apply-profile-recommendations" type="button" class="button"><?php esc_html_e('Apply This Business Profile\'s Recommendations', 'help4-builder-suite'); ?></button>
                                </p>
                                <p class="description"><?php esc_html_e('Recommendations are starting values. Saving this plan keeps every setting editable, and future plugin settings are added only while they are still unconfigured.', 'help4-builder-suite'); ?></p>
                            </td>
                        </tr>
                        <?php $this->wizardBoolField('needs_commerce', __('Will this site sell a product catalog directly?', 'help4-builder-suite'), $defaults); ?>
                        <?php $this->wizardBoolField('needs_standalone_payments', __('Need standalone payment collection (without full catalog)?', 'help4-builder-suite'), $defaults); ?>
                        <?php $this->wizardBoolField('needs_invoice_tracking', __('Need invoice/payment status synced back into the site?', 'help4-builder-suite'), $defaults); ?>
                        <?php $this->wizardBoolField('needs_subscriptions', __('Need recurring billing/subscriptions?', 'help4-builder-suite'), $defaults); ?>
                        <?php $this->wizardBoolField('needs_lms', __('Do you need courses and certifications (LMS)?', 'help4-builder-suite'), $defaults); ?>
                        <?php $this->wizardBoolField('needs_realtor', __('Do you need real-estate style tools (IDX/MLS, map search)?', 'help4-builder-suite'), $defaults); ?>
                        <?php $this->wizardBoolField('needs_contractor', __('Do you need contractor/trade service tools?', 'help4-builder-suite'), $defaults); ?>
                        <?php $this->wizardBoolField('needs_templates', __('Do you want advanced templates, sliders, and mega menu tooling?', 'help4-builder-suite'), $defaults); ?>
                        <?php $this->wizardBoolField('needs_seo', __('Enable built-in SEO/search optimization?', 'help4-builder-suite'), $defaults); ?>
                        <?php $this->wizardBoolField('needs_security', __('Enable security hardening defaults?', 'help4-builder-suite'), $defaults); ?>
                        <?php $this->wizardBoolField('needs_performance', __('Enable performance/caching/image optimization defaults?', 'help4-builder-suite'), $defaults); ?>
                        <?php $this->wizardBoolField('needs_demo_showcase', __('Create a public showcase/download section automatically?', 'help4-builder-suite'), $defaults); ?>
                        <tr>
                            <th scope="row"><?php esc_html_e('Theme pack starter', 'help4-builder-suite'); ?></th>
                            <td>
                                <select name="theme_pack_slug">
                                    <?php foreach ($themePacks as $pack) : ?>
                                        <?php
                                        $slug = sanitize_key((string) ($pack['slug'] ?? ''));
                                        if ($slug === '') {
                                            continue;
                                        }
                                        $label = sanitize_text_field((string) ($pack['label'] ?? $slug));
                                        $industry = sanitize_text_field((string) ($pack['industry'] ?? 'General'));
                                        ?>
                                        <option value="<?php echo esc_attr($slug); ?>" <?php selected($defaults['theme_pack_slug'], $slug); ?>>
                                            <?php echo esc_html($label . ' (' . $industry . ')'); ?>
                                        </option>
                                    <?php endforeach; ?>
                                </select>
                                <p class="description"><?php esc_html_e('Applies global colors, typography, container width, and section defaults site-wide.', 'help4-builder-suite'); ?></p>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <?php submit_button(__('Save Setup Plan', 'help4-builder-suite')); ?>
                <p><a href="<?php echo esc_url(wp_nonce_url(admin_url('admin.php?page=h4bs-settings&h4bs_skip_wizard=1'), 'h4bs_skip_setup_wizard', '_h4bs_skip')); ?>"><?php esc_html_e('Skip wizard and keep current settings', 'help4-builder-suite'); ?></a></p>
            </form>
            <script>
            (function () {
                var profiles = <?php echo wp_json_encode($profileClientData, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>;
                var select = document.getElementById('h4bs-business-profile');
                var apply = document.getElementById('h4bs-apply-profile-recommendations');
                var description = document.getElementById('h4bs-business-profile-description');
                var form = select ? select.closest('form') : null;
                if (!select || !apply || !form) {
                    return;
                }
                function currentProfile() {
                    return profiles[select.value] || null;
                }
                function describe() {
                    var profile = currentProfile();
                    if (description) {
                        description.textContent = profile ? profile.description : '';
                    }
                }
                select.addEventListener('change', describe);
                apply.addEventListener('click', function () {
                    var profile = currentProfile();
                    if (!profile) {
                        return;
                    }
                    Object.keys(profile.wizard || {}).forEach(function (key) {
                        var control = form.elements.namedItem(key);
                        if (control && control.type === 'checkbox') {
                            control.checked = Boolean(profile.wizard[key]);
                        }
                    });
                    var themePack = form.elements.namedItem('theme_pack_slug');
                    if (themePack && profile.themePack) {
                        themePack.value = profile.themePack;
                    }
                    describe();
                });
            }());
            </script>
        </div>
        <?php
    }

    /** @return list<int> */
    private function staffFavorites(int $userId): array
    {
        $stored = get_user_meta($userId, 'h4bs_staff_favorite_pages', true);
        if (is_string($stored)) {
            $decoded = json_decode($stored, true);
            $stored = is_array($decoded) ? $decoded : [];
        }
        return array_values(array_filter(array_map('absint', is_array($stored) ? $stored : [])));
    }

    public function handleToggleStaffFavorite(): void
    {
        if (! current_user_can('edit_pages')) {
            wp_die(esc_html__('You cannot edit pages on this site.', 'help4-builder-suite'));
        }

        $postId = isset($_POST['post_id']) ? absint($_POST['post_id']) : 0;
        check_admin_referer('h4bs_toggle_staff_favorite_' . $postId);
        if ($postId < 1 || ! current_user_can('edit_post', $postId)) {
            wp_die(esc_html__('That page is not available.', 'help4-builder-suite'));
        }

        $userId = get_current_user_id();
        $favorites = $this->staffFavorites($userId);
        if (in_array($postId, $favorites, true)) {
            $favorites = array_values(array_diff($favorites, [$postId]));
        } else {
            array_unshift($favorites, $postId);
            $favorites = array_slice(array_values(array_unique($favorites)), 0, 12);
        }
        update_user_meta($userId, 'h4bs_staff_favorite_pages', wp_json_encode($favorites));
        wp_safe_redirect(admin_url('admin.php?page=h4bs-settings#h4bs-your-pages'));
        exit;
    }

    public function renderStaffHome(): void
    {
        if (! current_user_can('edit_pages')) {
            wp_die(esc_html__('You cannot edit pages on this site.', 'help4-builder-suite'));
        }

        $favorites = $this->staffFavorites(get_current_user_id());
        $registeredTypes = get_post_types(['show_ui' => true], 'objects');
        $postTypes = [];
        $explicitEditorialTypes = ['page', 'post', 'h4_course', 'h4_product', 'h4_template', 'product'];
        foreach ($registeredTypes as $typeName => $typeObject) {
            $transactional = (bool) preg_match('/(order|submission|entry|payment|transaction|log|feedback)/i', $typeName);
            $editorial = ! $transactional && ($typeObject->publicly_queryable || in_array($typeName, $explicitEditorialTypes, true));
            if ($editorial && current_user_can($typeObject->cap->edit_posts)) {
                $postTypes[$typeName] = $typeObject;
            }
        }
        $content = [];
        foreach (array_keys($postTypes) as $postType) {
            $content = array_merge($content, get_posts([
                'post_type' => $postType,
                'post_status' => ['publish', 'draft', 'pending', 'private', 'future'],
                'posts_per_page' => -1,
                'orderby' => 'modified',
                'order' => 'DESC',
            ]));
        }
        usort($content, static fn (\WP_Post $left, \WP_Post $right): int => strcmp($right->post_modified_gmt, $left->post_modified_gmt));
        $isPublic = (string) get_option('blog_public', '1') === '1';
        $environment = wp_get_environment_type();
        $siteHost = strtolower((string) wp_parse_url(home_url('/'), PHP_URL_HOST));
        $hostLooksStaging = (bool) preg_match('/(^|\.)(staging|stage|dev|test|local)(\.|$)/', $siteHost) || in_array($siteHost, ['127.0.0.1', 'localhost'], true);
        $isNonProduction = $environment !== 'production' || $hostLooksStaging;
        $advancedTools = (string) get_user_meta(get_current_user_id(), 'h4bs_show_advanced_tools', true) === '1';
        $staffWorkspaces = $this->visibleStaffWorkspaces();
        ?>
        <div class="wrap h4bs-staff-home">
            <header class="h4bs-staff-home__hero">
                <div>
                    <p class="h4bs-staff-home__eyebrow"><?php esc_html_e('Help4 work home', 'help4-builder-suite'); ?></p>
                    <h1><?php esc_html_e('What do you need to update?', 'help4-builder-suite'); ?></h1>
                    <p><?php esc_html_e('Choose a task. Help4 opens the right workspace.', 'help4-builder-suite'); ?></p>
                </div>
                <div class="h4bs-staff-home__state<?php echo $isNonProduction && $isPublic ? ' is-warning' : ''; ?>" aria-label="<?php esc_attr_e('Website state', 'help4-builder-suite'); ?>">
                    <strong><?php echo esc_html($isNonProduction ? __('Staging or development workspace', 'help4-builder-suite') : __('Live-site workspace', 'help4-builder-suite')); ?></strong>
                    <span><?php echo esc_html($isPublic ? __('Search engines are allowed', 'help4-builder-suite') : __('Search engines are discouraged', 'help4-builder-suite')); ?></span>
                    <?php if ($isNonProduction && $isPublic) : ?><em><?php esc_html_e('Warning: this development site is currently indexable. Review visibility before sharing it.', 'help4-builder-suite'); ?></em><?php endif; ?>
                    <small><?php esc_html_e('Saving here does not launch or reroute the site.', 'help4-builder-suite'); ?></small>
                </div>
            </header>

            <section aria-labelledby="h4bs-common-tasks">
                <h2 id="h4bs-common-tasks"><?php esc_html_e('Common staff tasks', 'help4-builder-suite'); ?></h2>
                <div class="h4bs-staff-home__tasks">
                    <?php
                    $canManageCalendar = current_user_can('manage_help4_calendar');
                    $canManageStaff = current_user_can('manage_help4_staff_directory');
                    $tasks = [
                        ['dashicons-welcome-write-blog', __('Update a page', 'help4-builder-suite'), __('1. Find it below. 2. Preview it. 3. Choose visual or content editing.', 'help4-builder-suite'), '#h4bs-your-pages', true],
                        ['dashicons-calendar-alt', __('Calendar & events', 'help4-builder-suite'), $canManageCalendar ? __('Add local events, review connected calendar items, or hide an imported event.', 'help4-builder-suite') : __('Ask a site administrator to grant Calendar Workspace access.', 'help4-builder-suite'), $canManageCalendar ? admin_url('admin.php?page=h4bs-calendar') : '#h4bs-your-pages', $canManageCalendar],
                        ['dashicons-megaphone', __('Auditions & registration', 'help4-builder-suite'), __('Search “audition” below, preview the current card, then update only that record.', 'help4-builder-suite'), '#h4bs-your-pages', true],
                        ['dashicons-groups', __('Teachers & team', 'help4-builder-suite'), $canManageStaff ? __('Add, reorder, update, or archive staff profiles.', 'help4-builder-suite') : __('Ask a site administrator to grant Staff Directory access.', 'help4-builder-suite'), $canManageStaff ? admin_url('admin.php?page=h4bs-staff-directory') : '#h4bs-your-pages', $canManageStaff],
                        ['dashicons-media-document', __('News & announcements', 'help4-builder-suite'), __('Write an update with a clear preview before publishing.', 'help4-builder-suite'), admin_url('post-new.php?post_type=post'), true],
                        ['dashicons-visibility', __('Review the website', 'help4-builder-suite'), __('Open the public-facing site in a new tab.', 'help4-builder-suite'), home_url('/'), true],
                    ];
                    if (current_user_can('view_help4_form_entries') || current_user_can('access_help4_form_privacy')) {
                        $formsTaskUrl = current_user_can('view_help4_form_entries') ? admin_url('admin.php?page=h4bs-form-entries') : admin_url('admin.php?page=h4bs-form-privacy');
                        array_splice($tasks, 4, 0, [[
                            'dashicons-email-alt',
                            __('Forms & messages', 'help4-builder-suite'),
                            current_user_can('access_help4_form_privacy')
                                ? __('Review messages, assignments, holds, and privacy planning.', 'help4-builder-suite')
                                : __('Review stored messages and staff assignments.', 'help4-builder-suite'),
                            $formsTaskUrl,
                            true,
                        ]]);
                    }
                    foreach ($tasks as [$icon, $title, $description, $url, $available]) :
                        $unavailable = ! $available;
                        ?>
                        <?php if ($unavailable) : ?><div class="h4bs-staff-home__task is-unavailable" aria-disabled="true"><?php else : ?><a class="h4bs-staff-home__task" href="<?php echo esc_url($url); ?>"<?php echo $title === __('Review the website', 'help4-builder-suite') ? ' target="_blank" rel="noopener"' : ''; ?>><?php endif; ?>
                            <span class="dashicons <?php echo esc_attr($icon); ?>" aria-hidden="true"></span>
                            <strong><?php echo esc_html($title); ?></strong>
                            <span><?php echo esc_html($description); ?></span>
                        <?php echo $unavailable ? '</div>' : '</a>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
                    <?php endforeach; ?>
                </div>
            </section>

            <?php if ($staffWorkspaces !== []) : ?>
                <section class="h4bs-staff-home__workspaces" aria-labelledby="h4bs-site-workspaces">
                    <div class="h4bs-staff-home__section-head">
                        <div>
                            <h2 id="h4bs-site-workspaces"><?php esc_html_e('Site workspaces', 'help4-builder-suite'); ?></h2>
                            <p><?php esc_html_e('Tools added for this website. Only workspaces your account can use are shown.', 'help4-builder-suite'); ?></p>
                        </div>
                    </div>
                    <div class="h4bs-staff-home__tasks">
                        <?php foreach ($staffWorkspaces as $workspace) : ?>
                            <a class="h4bs-staff-home__task" href="<?php echo esc_url($workspace['url']); ?>" data-h4bs-staff-workspace="<?php echo esc_attr($workspace['slug']); ?>">
                                <span class="dashicons <?php echo esc_attr($workspace['icon']); ?>" aria-hidden="true"></span>
                                <strong><?php echo esc_html($workspace['label']); ?></strong>
                                <span><?php echo esc_html($workspace['description']); ?></span>
                            </a>
                        <?php endforeach; ?>
                    </div>
                </section>
            <?php endif; ?>

            <section id="h4bs-your-pages" class="h4bs-staff-home__pages" aria-labelledby="h4bs-your-pages-title">
                <div class="h4bs-staff-home__section-head">
                    <div><h2 id="h4bs-your-pages-title"><?php esc_html_e('Your content', 'help4-builder-suite'); ?></h2><p><?php esc_html_e('Recently changed public-facing content appears first. Star the items you use every week.', 'help4-builder-suite'); ?></p></div>
                    <details class="h4bs-staff-home__create"><summary><?php esc_html_e('Need brand-new content?', 'help4-builder-suite'); ?></summary><p><?php esc_html_e('Most updates belong on an existing page. Create a page only when the content needs a new public URL.', 'help4-builder-suite'); ?></p><a class="button" href="<?php echo esc_url(admin_url('post-new.php?post_type=page')); ?>"><?php esc_html_e('Create a new page', 'help4-builder-suite'); ?></a></details>
                </div>
                <div class="h4bs-staff-home__filters" role="search">
                    <label for="h4bs-page-search"><?php esc_html_e('Find content', 'help4-builder-suite'); ?></label>
                    <input id="h4bs-page-search" type="search" placeholder="<?php esc_attr_e('Search by title, type, or URL', 'help4-builder-suite'); ?>">
                    <div class="h4bs-staff-home__filter-buttons" role="group" aria-label="<?php esc_attr_e('Filter content', 'help4-builder-suite'); ?>">
                        <button class="button is-active" type="button" data-h4bs-page-filter="all" aria-pressed="true"><?php esc_html_e('All', 'help4-builder-suite'); ?></button>
                        <button class="button" type="button" data-h4bs-page-filter="favorite" aria-pressed="false"><?php esc_html_e('Favorites', 'help4-builder-suite'); ?></button>
                        <button class="button" type="button" data-h4bs-page-filter="publish" aria-pressed="false"><?php esc_html_e('Published', 'help4-builder-suite'); ?></button>
                        <button class="button" type="button" data-h4bs-page-filter="draft" aria-pressed="false"><?php esc_html_e('Draft', 'help4-builder-suite'); ?></button>
                        <button class="button" type="button" data-h4bs-page-filter="pending" aria-pressed="false"><?php esc_html_e('Pending review', 'help4-builder-suite'); ?></button>
                        <button class="button" type="button" data-h4bs-page-filter="private" aria-pressed="false"><?php esc_html_e('Private', 'help4-builder-suite'); ?></button>
                        <button class="button" type="button" data-h4bs-page-filter="future" aria-pressed="false"><?php esc_html_e('Scheduled', 'help4-builder-suite'); ?></button>
                    </div>
                    <p class="h4bs-staff-home__result-count" aria-live="polite"></p>
                </div>
                <div class="h4bs-staff-home__page-list">
                    <?php foreach ($content as $page) :
                        $postId = (int) $page->ID;
                        if (! current_user_can('edit_post', $postId)) { continue; }
                        $favorite = in_array($postId, $favorites, true);
                        $builder = (string) get_post_meta($postId, '_h4_builder_enabled', true) === '1';
                        $status = get_post_status_object((string) $page->post_status);
                        $typeObject = $postTypes[$page->post_type] ?? get_post_type_object($page->post_type);
                        $typeLabel = $typeObject ? $typeObject->labels->singular_name : $page->post_type;
                        $noIndex = (string) get_post_meta($postId, '_h4_seo_noindex', true) === '1';
                        $indexLabel = $page->post_status === 'publish' && $isPublic && ! $noIndex ? __('Search-visible', 'help4-builder-suite') : __('Not search-visible', 'help4-builder-suite');
                        $editUrl = $builder ? admin_url('admin.php?page=h4bs-builder-studio&post=' . $postId) : get_edit_post_link($postId, 'raw');
                        $previewUrl = get_preview_post_link($postId) ?: get_permalink($postId);
                        $displayPath = $page->post_status === 'publish' ? (string) wp_parse_url(get_permalink($postId), PHP_URL_PATH) : '/' . trim($page->post_name, '/') . '/ (preview only)';
                        $modifiedTimestamp = strtotime($page->post_modified_gmt . ' GMT');
                        if (! $modifiedTimestamp || (int) gmdate('Y', $modifiedTimestamp) < 2000) {
                            $modifiedTimestamp = strtotime($page->post_modified);
                        }
                        if ($modifiedTimestamp && (int) gmdate('Y', $modifiedTimestamp) >= 2000) {
                            /* translators: %s: human-readable time since the content was updated. */
                            $updatedLabel = sprintf(__('Updated %s ago', 'help4-builder-suite'), human_time_diff($modifiedTimestamp));
                        } else {
                            $updatedLabel = __('Update time unavailable', 'help4-builder-suite');
                        }
                        ?>
                        <article class="h4bs-staff-home__page" data-title="<?php echo esc_attr(strtolower($page->post_title . ' ' . $page->post_name . ' ' . get_permalink($postId) . ' ' . $typeLabel)); ?>" data-status="<?php echo esc_attr($page->post_status); ?>" data-favorite="<?php echo $favorite ? '1' : '0'; ?>">
                            <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
                                <input type="hidden" name="action" value="h4bs_toggle_staff_favorite"><input type="hidden" name="post_id" value="<?php echo esc_attr((string) $postId); ?>">
                                <?php wp_nonce_field('h4bs_toggle_staff_favorite_' . $postId); ?>
                                <button class="h4bs-staff-home__favorite" type="submit" aria-label="<?php echo esc_attr($favorite ? __('Remove from favorites', 'help4-builder-suite') : __('Add to favorites', 'help4-builder-suite')); ?>" aria-pressed="<?php echo $favorite ? 'true' : 'false'; ?>"><span class="dashicons <?php echo $favorite ? 'dashicons-star-filled' : 'dashicons-star-empty'; ?>" aria-hidden="true"></span></button>
                            </form>
                            <div class="h4bs-staff-home__page-main"><strong><?php echo esc_html(get_the_title($postId) ?: __('Untitled content', 'help4-builder-suite')); ?></strong><span><?php echo esc_html($typeLabel); ?> · <?php echo esc_html($displayPath); ?> · <?php echo esc_html($status ? $status->label : $page->post_status); ?> · <?php echo esc_html($indexLabel); ?> · <?php echo esc_html($updatedLabel); ?></span></div>
                            <div class="h4bs-staff-home__page-actions"><a class="button" href="<?php echo esc_url($previewUrl); ?>" target="_blank" rel="noopener"><?php esc_html_e('Preview', 'help4-builder-suite'); ?></a><a class="button button-primary" href="<?php echo esc_url((string) $editUrl); ?>"><?php echo esc_html($builder ? __('Edit page design', 'help4-builder-suite') : __('Edit words and images', 'help4-builder-suite')); ?></a><small><?php echo esc_html($builder ? __('Opens Help4 Builder for layout and design changes.', 'help4-builder-suite') : __('Opens the WordPress content editor; page layout stays unchanged.', 'help4-builder-suite')); ?></small></div>
                        </article>
                    <?php endforeach; ?>
                    <p class="h4bs-staff-home__empty" hidden><?php esc_html_e('No content matches that search and filter.', 'help4-builder-suite'); ?></p>
                </div>
            </section>
            <?php if (current_user_can('manage_options')) : ?>
                <aside class="h4bs-staff-home__advanced" aria-labelledby="h4bs-advanced-title"><h2 id="h4bs-advanced-title"><?php esc_html_e('Administrator tools', 'help4-builder-suite'); ?></h2><p><?php esc_html_e('Technical setup, SEO systems, templates, integrations, and diagnostics are hidden from the staff menu by default. Showing them changes only your menu.', 'help4-builder-suite'); ?></p><form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>"><input type="hidden" name="action" value="h4bs_toggle_advanced_tools"><?php wp_nonce_field('h4bs_toggle_advanced_tools'); ?><button class="button" type="submit"><?php echo esc_html($advancedTools ? __('Hide advanced tools', 'help4-builder-suite') : __('Show advanced tools', 'help4-builder-suite')); ?></button></form><?php if ($advancedTools) : ?><a href="<?php echo esc_url(admin_url('admin.php?page=h4bs-settings-advanced')); ?>"><?php esc_html_e('Open Builder settings', 'help4-builder-suite'); ?></a><?php endif; ?></aside>
            <?php endif; ?>
        </div>
        <?php
    }

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

        $flags    = $this->featureFlags->all();
        $settings = Settings::all();
        $themePacks = $this->themePackCatalog();
        $activeThemePack = $this->activeThemePackSlug();
        $selectedBusinessProfile = BusinessProfileDefaults::selectedSlug();
        $businessProfile = BusinessProfileDefaults::profile($selectedBusinessProfile);
        $selectedThemePack = $activeThemePack !== '' ? $activeThemePack : $this->recommendedThemePackSlug($selectedBusinessProfile);
        $activeThemePackLabel = __('Not selected', 'help4-builder-suite');
        foreach ($themePacks as $pack) {
            if (sanitize_key((string) ($pack['slug'] ?? '')) !== $activeThemePack) {
                continue;
            }
            $activeThemePackLabel = sanitize_text_field((string) ($pack['label'] ?? $activeThemePack));
            break;
        }
        $help4BlankTheme = wp_get_theme('help4-blank');
        $help4BlankInstalled = $help4BlankTheme->exists();
        $help4BlankActive = $help4BlankInstalled && get_stylesheet() === 'help4-blank';
        $help4InstallThemeUrl = wp_nonce_url(
            admin_url('admin-post.php?action=h4bs_dependency_install_theme'),
            'h4bs_dependency_install_theme'
        );
        $help4ActivateThemeUrl = wp_nonce_url(
            admin_url('admin-post.php?action=h4bs_dependency_activate_theme'),
            'h4bs_dependency_activate_theme'
        );
        ?>
        <div class="wrap h4bs-admin-wrap">
            <h1><?php esc_html_e('Help4 Builder Suite', 'help4-builder-suite'); ?></h1>
            <p>
                <?php esc_html_e('Core settings for the Help4 theme builder stack. Toggle modules, configure SEO verification tokens, and connect payment providers.', 'help4-builder-suite'); ?>
            </p>
            <div class="notice notice-info inline">
                <p>
                    <strong><?php esc_html_e('Looking for the theme files?', 'help4-builder-suite'); ?></strong>
                    <?php esc_html_e('Help4 Builder Suite and the Help4 Blank companion theme are separate downloads because WordPress.org treats plugins and themes as separate packages. Install the plugin from this ZIP, then upload the theme ZIP under Appearance > Themes when you want the clean blank-theme workflow.', 'help4-builder-suite'); ?>
                </p>
                <p>
                    <a class="button" href="https://help4wordpress.com/help4-blank/help4-blank.zip" target="_blank" rel="noopener">
                        <?php esc_html_e('Download Help4 Blank Theme ZIP', 'help4-builder-suite'); ?>
                    </a>
                    <?php if (current_user_can('switch_themes')) : ?>
                        <?php if ($help4BlankActive) : ?>
                            <a class="button button-disabled" aria-disabled="true">
                                <?php esc_html_e('Help4 Blank Theme Active', 'help4-builder-suite'); ?>
                            </a>
                        <?php elseif ($help4BlankInstalled) : ?>
                            <a class="button button-primary" href="<?php echo esc_url($help4ActivateThemeUrl); ?>">
                                <?php esc_html_e('Activate Help4 Blank Theme', 'help4-builder-suite'); ?>
                            </a>
                        <?php else : ?>
                            <a class="button button-primary" href="<?php echo esc_url($help4InstallThemeUrl); ?>">
                                <?php esc_html_e('Install + Activate Help4 Blank Theme', 'help4-builder-suite'); ?>
                            </a>
                        <?php endif; ?>
                    <?php endif; ?>
                    <a class="button" href="<?php echo esc_url(admin_url('theme-install.php?browse=upload')); ?>">
                        <?php esc_html_e('Open WordPress Theme Upload', 'help4-builder-suite'); ?>
                    </a>
                    <a class="button" href="https://help4wordpress.com/help4-blank/manifest.json" target="_blank" rel="noopener">
                        <?php esc_html_e('Open Theme Manifest', 'help4-builder-suite'); ?>
                    </a>
                    <a class="button" href="https://help4wordpress.com/help4-builder-guide/" target="_blank" rel="noopener">
                        <?php esc_html_e('Open Install Guide', 'help4-builder-suite'); ?>
                    </a>
                </p>
            </div>
            <p>
                <a class="button" href="<?php echo esc_url(admin_url('admin.php?page=h4bs-commerce')); ?>"><?php esc_html_e('Open Commerce Menu', 'help4-builder-suite'); ?></a>
                <a class="button" href="<?php echo esc_url(admin_url('admin.php?page=h4bs-security')); ?>"><?php esc_html_e('Open Security Menu', 'help4-builder-suite'); ?></a>
                <a class="button" href="<?php echo esc_url(admin_url('admin.php?page=h4bs-theme-builder')); ?>"><?php esc_html_e('Open Theme Builder', 'help4-builder-suite'); ?></a>
                <a class="button" href="<?php echo esc_url(admin_url('edit.php?post_type=h4_template')); ?>"><?php esc_html_e('Open Templates', 'help4-builder-suite'); ?></a>
                <a class="button" href="<?php echo esc_url(admin_url('admin.php?page=h4bs-fields-lab')); ?>"><?php esc_html_e('Open Fields Lab', 'help4-builder-suite'); ?></a>
                <a class="button button-primary" href="<?php echo esc_url(admin_url('admin.php?page=' . self::WIZARD_PAGE_SLUG)); ?>"><?php esc_html_e('Review Business Profile', 'help4-builder-suite'); ?></a>
            </p>
            <p>
                <strong><?php esc_html_e('Current business profile:', 'help4-builder-suite'); ?></strong>
                <?php echo esc_html((string) ($businessProfile['label'] ?? ucfirst(str_replace('_', ' ', $selectedBusinessProfile)))); ?>
                <span class="description"><?php esc_html_e('Recommended values seed only unconfigured settings; saved choices remain yours.', 'help4-builder-suite'); ?></span>
            </p>
            <?php $this->renderSiteLaunchCenter(); ?>
            <?php $this->renderTutorialHub(); ?>
            <h2><?php esc_html_e('Global Theme Pack', 'help4-builder-suite'); ?></h2>
            <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
                <?php wp_nonce_field('h4bs_apply_theme_pack', 'h4bs_apply_theme_pack_nonce'); ?>
                <input type="hidden" name="action" value="h4bs_apply_theme_pack">
                <p>
                    <strong><?php esc_html_e('Current pack:', 'help4-builder-suite'); ?></strong>
                    <?php echo esc_html($activeThemePackLabel); ?>
                </p>
                <p>
                    <label for="h4bs_theme_pack_slug"><?php esc_html_e('Apply pack site-wide:', 'help4-builder-suite'); ?></label>
                    <select id="h4bs_theme_pack_slug" name="theme_pack_slug">
                        <?php foreach ($themePacks as $pack) : ?>
                            <?php
                            $slug = sanitize_key((string) ($pack['slug'] ?? ''));
                            if ($slug === '') {
                                continue;
                            }
                            $label = sanitize_text_field((string) ($pack['label'] ?? $slug));
                            $industry = sanitize_text_field((string) ($pack['industry'] ?? 'General'));
                            ?>
                            <option value="<?php echo esc_attr($slug); ?>" <?php selected($selectedThemePack, $slug); ?>>
                                <?php echo esc_html($label . ' (' . $industry . ')'); ?>
                            </option>
                        <?php endforeach; ?>
                    </select>
                    <button type="submit" class="button"><?php esc_html_e('Apply Theme Pack', 'help4-builder-suite'); ?></button>
                </p>
            </form>

            <form method="post" action="options.php">
                <?php settings_fields('h4bs_settings_group'); ?>
                <h2><?php esc_html_e('Feature Modules', 'help4-builder-suite'); ?></h2>
                <table class="form-table" role="presentation">
                    <tbody>
                        <?php foreach ($this->featureLabels() as $key => $label) : ?>
                            <tr>
                                <th scope="row"><?php echo esc_html($label); ?></th>
                                <td>
                                    <label>
                                        <input
                                            type="checkbox"
                                            name="<?php echo esc_attr(FeatureFlags::OPTION_KEY . '[' . $key . ']'); ?>"
                                            value="1"
                                            <?php checked(! empty($flags[$key])); ?>
                                        >
                                        <?php esc_html_e('Enabled', 'help4-builder-suite'); ?>
                                    </label>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>

                <h2><?php esc_html_e('Brand, SEO, and Integrations', 'help4-builder-suite'); ?></h2>
                <table class="form-table" role="presentation">
                    <tbody>
                        <?php $this->textField('brand_name', __('Brand Name', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('footer_credit_enabled', __('Show Default Footer Credit', 'help4-builder-suite'), $settings); ?>
                        <tr>
                            <th scope="row"><?php esc_html_e('Default Footer Credit Text', 'help4-builder-suite'); ?></th>
                            <td>
                                <input
                                    class="regular-text"
                                    type="text"
                                    name="h4bs_settings[footer_credit_text]"
                                    value="<?php echo esc_attr((string) ($settings['footer_credit_text'] ?? '')); ?>"
                                >
                                <p class="description"><?php esc_html_e('Use {site} for the site name and {year} for the auto-updating year. Leave this blank, or disable the footer credit, to remove the fallback text.', 'help4-builder-suite'); ?></p>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row"><?php esc_html_e('Footer Year Behavior', 'help4-builder-suite'); ?></th>
                            <td>
                                <?php $footerYearMode = sanitize_key((string) ($settings['footer_credit_year_mode'] ?? 'current')); ?>
                                <select name="h4bs_settings[footer_credit_year_mode]">
                                    <option value="current" <?php selected($footerYearMode, 'current'); ?>><?php esc_html_e('Current year', 'help4-builder-suite'); ?></option>
                                    <option value="range" <?php selected($footerYearMode, 'range'); ?>><?php esc_html_e('Start year to current year', 'help4-builder-suite'); ?></option>
                                    <option value="none" <?php selected($footerYearMode, 'none'); ?>><?php esc_html_e('No year', 'help4-builder-suite'); ?></option>
                                </select>
                            </td>
                        </tr>
                        <?php $this->numberField('footer_credit_start_year', __('Footer Start Year', 'help4-builder-suite'), $settings, 1900, (int) gmdate('Y') + 25); ?>
                        <?php $this->urlField('support_url', __('Support Ticket URL', 'help4-builder-suite'), $settings); ?>
                        <?php $this->urlField('default_social_image_url', __('Default Social Image URL', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('default_social_image_alt', __('Default Social Image Alt Text', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('twitter_site', __('X / Twitter Site Handle', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('business_phone', __('Business Phone', 'help4-builder-suite'), $settings); ?>
                        <tr>
                            <th scope="row"><label for="h4bs_seo_default_intent_profile"><?php esc_html_e('Default SEO Page Profile', 'help4-builder-suite'); ?></label></th>
                            <td>
                                <?php $defaultIntent = sanitize_key((string) ($settings['seo_default_intent_profile'] ?? 'auto')); ?>
                                <select id="h4bs_seo_default_intent_profile" name="h4bs_settings[seo_default_intent_profile]">
                                    <option value="auto" <?php selected($defaultIntent, 'auto'); ?>><?php esc_html_e('Automatic from business profile and page content', 'help4-builder-suite'); ?></option>
                                    <option value="general" <?php selected($defaultIntent, 'general'); ?>><?php esc_html_e('General website', 'help4-builder-suite'); ?></option>
                                    <option value="local" <?php selected($defaultIntent, 'local'); ?>><?php esc_html_e('Local or service business', 'help4-builder-suite'); ?></option>
                                    <option value="ecommerce" <?php selected($defaultIntent, 'ecommerce'); ?>><?php esc_html_e('Online store or catalog', 'help4-builder-suite'); ?></option>
                                    <option value="publisher" <?php selected($defaultIntent, 'publisher'); ?>><?php esc_html_e('Publisher or knowledge site', 'help4-builder-suite'); ?></option>
                                    <option value="global" <?php selected($defaultIntent, 'global'); ?>><?php esc_html_e('International or multilingual', 'help4-builder-suite'); ?></option>
                                </select>
                                <p class="description"><?php esc_html_e('Automatic is recommended. Individual pages can override this without changing the rest of the site.', 'help4-builder-suite'); ?></p>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row"><label for="h4bs_same_as_urls"><?php esc_html_e('Organization Social Profile URLs', 'help4-builder-suite'); ?></label></th>
                            <td><textarea id="h4bs_same_as_urls" class="large-text code" rows="5" name="h4bs_settings[same_as_urls]" placeholder="https://www.linkedin.com/company/example/&#10;https://www.facebook.com/example/"><?php echo esc_textarea(implode("\n", array_map('strval', (array) ($settings['same_as_urls'] ?? [])))); ?></textarea><p class="description"><?php esc_html_e('One verified public organization profile URL per line. These become sameAs references in Organization schema.', 'help4-builder-suite'); ?></p></td>
                        </tr>
                        <?php $this->boolField('igor_feedback_enabled', __('Enable I.G.O.R. Feedback Intake', 'help4-builder-suite'), $settings); ?>
                        <?php $this->urlField('igor_feedback_endpoint', __('I.G.O.R. Feedback Endpoint', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('google_site_verification', __('Google Site Verification', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('bing_site_verification', __('Bing Site Verification', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('yandex_site_verification', __('Yandex Site Verification', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('baidu_site_verification', __('Baidu Site Verification', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('naver_site_verification', __('Naver Site Verification', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('pinterest_site_verification', __('Pinterest Site Verification', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('facebook_domain_verification', __('Meta / Facebook Domain Verification', 'help4-builder-suite'), $settings); ?>
                        <tr>
                            <th scope="row"><label for="h4bs_custom_site_verification_meta"><?php esc_html_e('Additional Webmaster Verification Tags', 'help4-builder-suite'); ?></label></th>
                            <td>
                                <?php $customVerification = (new DiscoveryStandards())->formatVerificationMeta((array) ($settings['custom_site_verification_meta'] ?? [])); ?>
                                <textarea id="h4bs_custom_site_verification_meta" class="large-text code" rows="5" name="h4bs_settings[custom_site_verification_meta]" placeholder="regional-engine-verification=issued-token"><?php echo esc_textarea($customVerification); ?></textarea>
                                <p class="description"><?php esc_html_e('One issued ownership tag per line as meta-name=token. Only verification-style names are accepted; scripts, arbitrary HTML, robots overrides, and redirects are rejected.', 'help4-builder-suite'); ?></p>
                            </td>
                        </tr>
                        <?php $this->boolField('indexnow_enabled', __('Submit Published URL Changes with IndexNow', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('indexnow_key', __('IndexNow Key', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('seo_video_sitemap_enabled', __('Video Sitemap', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('seo_news_sitemap_enabled', __('Recent News Sitemap', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('commerce_seo_feed_enabled', __('Commerce Merchant Discovery Feed', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('commerce_seo_default_brand', __('Default Product Brand', 'help4-builder-suite'), $settings); ?>
                        <tr>
                            <th scope="row"><label for="h4bs_commerce_seo_default_condition"><?php esc_html_e('Default Product Condition', 'help4-builder-suite'); ?></label></th>
                            <td>
                                <?php $defaultCondition = sanitize_key((string) ($settings['commerce_seo_default_condition'] ?? 'new')); ?>
                                <select id="h4bs_commerce_seo_default_condition" name="h4bs_settings[commerce_seo_default_condition]">
                                    <option value="new" <?php selected($defaultCondition, 'new'); ?>><?php esc_html_e('New', 'help4-builder-suite'); ?></option>
                                    <option value="used" <?php selected($defaultCondition, 'used'); ?>><?php esc_html_e('Used', 'help4-builder-suite'); ?></option>
                                    <option value="refurbished" <?php selected($defaultCondition, 'refurbished'); ?>><?php esc_html_e('Refurbished', 'help4-builder-suite'); ?></option>
                                </select>
                            </td>
                        </tr>
                        <?php $this->urlField('commerce_seo_return_policy_url', __('Public Return Policy URL', 'help4-builder-suite'), $settings); ?>
                        <?php $this->urlField('commerce_seo_shipping_policy_url', __('Public Shipping Policy URL', 'help4-builder-suite'), $settings); ?>
                        <tr>
                            <th scope="row"><label for="h4bs_seo_rss_before_content"><?php esc_html_e('RSS Content Before Each Item', 'help4-builder-suite'); ?></label></th>
                            <td><textarea id="h4bs_seo_rss_before_content" class="large-text" rows="3" name="h4bs_settings[seo_rss_before_content]"><?php echo esc_textarea((string) ($settings['seo_rss_before_content'] ?? '')); ?></textarea><p class="description"><?php esc_html_e('Supports %POSTLINK%, %BLOGLINK%, and %AUTHORLINK%.', 'help4-builder-suite'); ?></p></td>
                        </tr>
                        <tr>
                            <th scope="row"><label for="h4bs_seo_rss_after_content"><?php esc_html_e('RSS Content After Each Item', 'help4-builder-suite'); ?></label></th>
                            <td><textarea id="h4bs_seo_rss_after_content" class="large-text" rows="3" name="h4bs_settings[seo_rss_after_content]"><?php echo esc_textarea((string) ($settings['seo_rss_after_content'] ?? '')); ?></textarea><p class="description"><?php esc_html_e('Adds clear source attribution when feed items are republished.', 'help4-builder-suite'); ?></p></td>
                        </tr>
                        <tr>
                            <th scope="row"><?php esc_html_e('Stripe Router Endpoint', 'help4-builder-suite'); ?></th>
                            <td>
                                <code><?php echo esc_html((string) ($settings['stripe_router_endpoint'] ?? '')); ?></code>
                                <p class="description"><?php esc_html_e('Optional payment-router endpoint. Leave empty unless you manage a separate checkout service and understand what data it receives.', 'help4-builder-suite'); ?></p>
                            </td>
                        </tr>
                        <?php $this->textField('paypal_client_id', __('PayPal Client ID', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('square_application_id', __('Square Application ID', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('braintree_merchant_id', __('Braintree Merchant ID', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('hosted_payments_profile', __('Hosted Payments Profile', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('wise_profile_id', __('Wise Profile ID', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('authorize_net_login_id', __('Authorize.Net Login ID', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('mls_idx_provider', __('MLS / IDX Provider', 'help4-builder-suite'), $settings); ?>
                        <?php $this->textField('maps_api_key', __('Google Maps API Key', 'help4-builder-suite'), $settings); ?>
                    </tbody>
                </table>

                <h2><?php esc_html_e('Live Update Channel', 'help4-builder-suite'); ?></h2>
                <table class="form-table" role="presentation">
                    <tbody>
                        <tr>
                            <th scope="row"><?php esc_html_e('Update Source', 'help4-builder-suite'); ?></th>
                            <td>
                                <code><?php echo esc_html((string) ($settings['update_manifest_url'] ?? '')); ?></code>
                                <p class="description"><?php esc_html_e('The live Help4 package can use this manifest for package updates. The WordPress.org package removes this updater and updates through WordPress.org.', 'help4-builder-suite'); ?></p>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row"><?php esc_html_e('Companion Theme Package', 'help4-builder-suite'); ?></th>
                            <td>
                                <code>https://help4wordpress.com/help4-blank/help4-blank.zip</code>
                                <p class="description"><?php esc_html_e('The Help4 Blank theme is not bundled inside the plugin ZIP. WordPress.org treats plugin and theme packages separately, so users who want the blank shell should download and upload the theme ZIP separately under Appearance > Themes.', 'help4-builder-suite'); ?></p>
                                <p>
                                    <?php if (current_user_can('switch_themes')) : ?>
                                        <?php if ($help4BlankActive) : ?>
                                            <span class="button button-disabled" aria-disabled="true"><?php esc_html_e('Help4 Blank Theme Active', 'help4-builder-suite'); ?></span>
                                        <?php elseif ($help4BlankInstalled) : ?>
                                            <a class="button button-primary" href="<?php echo esc_url($help4ActivateThemeUrl); ?>"><?php esc_html_e('Activate Theme', 'help4-builder-suite'); ?></a>
                                        <?php else : ?>
                                            <a class="button button-primary" href="<?php echo esc_url($help4InstallThemeUrl); ?>"><?php esc_html_e('Install + Activate Theme', 'help4-builder-suite'); ?></a>
                                        <?php endif; ?>
                                    <?php endif; ?>
                                    <a class="button" href="<?php echo esc_url(admin_url('theme-install.php?browse=upload')); ?>"><?php esc_html_e('Manual Upload Screen', 'help4-builder-suite'); ?></a>
                                </p>
                            </td>
                        </tr>
                    </tbody>
                </table>

                <h2><?php esc_html_e('Commerce Experience Defaults', 'help4-builder-suite'); ?></h2>
                <table class="form-table" role="presentation">
                    <tbody>
                        <?php
                        $this->selectField(
                            'commerce_product_card_style',
                            __('Default Product Card Style', 'help4-builder-suite'),
                            $settings,
                            [
                                'overlay' => __('Overlay image card', 'help4-builder-suite'),
                                'clean' => __('Clean catalog card', 'help4-builder-suite'),
                                'compact' => __('Compact dense card', 'help4-builder-suite'),
                                'list' => __('List row card', 'help4-builder-suite'),
                                'showcase' => __('Showcase product card', 'help4-builder-suite'),
                            ]
                        );
                        $this->selectField(
                            'commerce_product_hover',
                            __('Default Hover Behavior', 'help4-builder-suite'),
                            $settings,
                            [
                                'lift' => __('Lift card', 'help4-builder-suite'),
                                'image_zoom' => __('Image zoom', 'help4-builder-suite'),
                                'quick_actions' => __('Reveal quick actions', 'help4-builder-suite'),
                                'none' => __('No motion', 'help4-builder-suite'),
                            ]
                        );
                        $this->selectField(
                            'commerce_filter_style',
                            __('Catalog Filter Layout', 'help4-builder-suite'),
                            $settings,
                            [
                                'toolbar' => __('Full toolbar', 'help4-builder-suite'),
                                'compact' => __('Compact toolbar', 'help4-builder-suite'),
                                'drawer' => __('Drawer-style block', 'help4-builder-suite'),
                            ]
                        );
                        ?>
                        <?php $this->numberField('commerce_product_columns_desktop', __('Desktop Columns', 'help4-builder-suite'), $settings, 1, 6); ?>
                        <?php $this->numberField('commerce_product_columns_tablet', __('Tablet Columns', 'help4-builder-suite'), $settings, 1, 4); ?>
                        <?php $this->numberField('commerce_product_columns_mobile', __('Mobile Columns', 'help4-builder-suite'), $settings, 1, 2); ?>
                        <?php $this->boolField('commerce_show_product_image', __('Show Product Images', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('commerce_show_quick_view', __('Show Quick View', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('commerce_show_compare_action', __('Show Compare Tray', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('commerce_show_stock_badge', __('Show Stock Badges', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('commerce_show_sku', __('Show SKU', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('commerce_show_product_type_badges', __('Show Type and Variation Badges', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('commerce_sticky_mobile_toolbar', __('Show Mobile Commerce Toolbar', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('commerce_show_price_watch_prompt', __('Show Price-Watch Prompt', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('commerce_show_waitlist_prompt', __('Show Waitlist Prompt', 'help4-builder-suite'), $settings); ?>
                    </tbody>
                </table>

                <h2><?php esc_html_e('Security and SSL', 'help4-builder-suite'); ?></h2>
                <table class="form-table" role="presentation">
                    <tbody>
                        <tr>
                            <th scope="row"><?php esc_html_e('Dedicated Security Area', 'help4-builder-suite'); ?></th>
                            <td>
                                <a class="button button-primary" href="<?php echo esc_url(admin_url('admin.php?page=h4bs-security')); ?>">
                                    <?php esc_html_e('Open Security + SSL Control Center', 'help4-builder-suite'); ?>
                                </a>
                                <p class="description"><?php esc_html_e('All SSL, headers, Cloudflare hardening, wp-config permissions, and salt rotation are managed in the Security menu.', 'help4-builder-suite'); ?></p>
                            </td>
                        </tr>
                    </tbody>
                </table>

                <h2><?php esc_html_e('Performance and Image Optimization', 'help4-builder-suite'); ?></h2>
                <table class="form-table" role="presentation">
                    <tbody>
                        <?php $this->boolField('perf_defer_scripts', __('Defer Non-Critical Scripts', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('perf_lazyload_images', __('Lazyload Images', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('perf_cache_headers', __('Set Cache Headers For Guests', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('perf_integrate_litespeed', __('LiteSpeed Cache Integration', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('perf_integrate_w3tc', __('Full Page Cache Integration', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('perf_integrate_redis', __('Redis/Object Cache Integration', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('image_opt_enable', __('Enable Imagick Optimization', 'help4-builder-suite'), $settings); ?>
                        <?php $this->numberField('image_opt_quality', __('Image Compression Quality', 'help4-builder-suite'), $settings, 40, 95); ?>
                        <?php $this->boolField('image_opt_generate_webp', __('Generate WebP Derivatives', 'help4-builder-suite'), $settings); ?>
                        <?php $this->boolField('image_opt_enhance_uploaded', __('Auto Enhance Uploaded Images (Imagick)', 'help4-builder-suite'), $settings); ?>
                    </tbody>
                </table>

                <?php submit_button(__('Save Help4 Settings', 'help4-builder-suite')); ?>
            </form>
        </div>
        <?php
    }

    /**
     * @param array<int, string> $links
     * @return array<int, string>
     */
    public function pluginActionLinks(array $links): array
    {
        if (! current_user_can('manage_options')) {
            return $links;
        }

        $wizardLink = '<a href="' . esc_url(admin_url('admin.php?page=' . self::WIZARD_PAGE_SLUG)) . '">'
            . esc_html__('Launch Setup Wizard', 'help4-builder-suite')
            . '</a>';
        $settingsLink = '<a href="' . esc_url(admin_url('admin.php?page=h4bs-settings')) . '">'
            . esc_html__('Open Help4 Settings', 'help4-builder-suite')
            . '</a>';

        $newLinks = array_filter([$wizardLink, $settingsLink], static fn (string $item): bool => $item !== '');
        if ($newLinks) {
            array_unshift($links, ...$newLinks);
        }
        return $links;
    }

    public function renderPluginsScreenWizardNotice(): void
    {
        if (! current_user_can('manage_options')) {
            return;
        }
        $screen = function_exists('get_current_screen') ? get_current_screen() : null;
        if (! $screen || (string) $screen->id !== 'plugins') {
            return;
        }

        $done = (string) get_option(self::WIZARD_DONE_OPTION, '0') === '1';
        if ($done) {
            return;
        }

        $wizardUrl = admin_url('admin.php?page=' . self::WIZARD_PAGE_SLUG);
        $skipUrl = wp_nonce_url(
            add_query_arg(
                [
                    'page' => 'h4bs-settings',
                    'h4bs_skip_wizard' => '1',
                ],
                admin_url('admin.php')
            ),
            'h4bs_skip_setup_wizard',
            '_h4bs_skip'
        );

        echo '<div class="notice notice-info"><p><strong>'
            . esc_html__('Help4 Builder Setup Wizard is ready.', 'help4-builder-suite')
            . '</strong> '
            . esc_html__('Use the guided setup to auto-enable only the modules your site needs.', 'help4-builder-suite')
            . '</p><p><a class="button button-primary" href="' . esc_url($wizardUrl) . '">'
            . esc_html__('Launch Setup Wizard', 'help4-builder-suite')
            . '</a> <a class="button" href="' . esc_url(admin_url('admin.php?page=h4bs-settings')) . '">'
            . esc_html__('Open Help4 Settings', 'help4-builder-suite')
            . '</a> <a class="button-link" href="' . esc_url($skipUrl) . '">'
            . esc_html__('Skip for now', 'help4-builder-suite')
            . '</a></p></div>';
    }

    private function renderSiteLaunchCenter(bool $compact = false): void
    {
        $profiles = $this->siteLaunchProfiles();
        $checks = $this->siteLaunchReadinessChecks();
        $stateHash = $this->siteLaunchStateHash();
        $report = get_option(self::LAUNCH_REPORT_OPTION, []);
        $report = is_array($report) ? $report : [];
        $snapshot = get_option(self::LAUNCH_SNAPSHOT_OPTION, []);
        $snapshot = is_array($snapshot) ? $snapshot : [];
        $statusCounts = ['pass' => 0, 'warn' => 0, 'fail' => 0];
        foreach ($checks as $check) {
            $status = (string) ($check['status'] ?? 'warn');
            if (isset($statusCounts[$status])) {
                ++$statusCounts[$status];
            }
        }
        /* translators: %d: number of readiness checks that passed. */
        $passedSummary = sprintf(_n('%d passed', '%d passed', $statusCounts['pass'], 'help4-builder-suite'), $statusCounts['pass']);
        /* translators: %d: number of readiness warnings. */
        $warningSummary = sprintf(_n('%d warning', '%d warnings', $statusCounts['warn'], 'help4-builder-suite'), $statusCounts['warn']);
        /* translators: %d: number of readiness blockers. */
        $blockerSummary = sprintf(_n('%d blocker', '%d blockers', $statusCounts['fail'], 'help4-builder-suite'), $statusCounts['fail']);

        $activeProfile = '';
        $reportState = sanitize_text_field((string) ($report['state_after'] ?? ''));
        if ($reportState !== '' && hash_equals($reportState, $stateHash) && empty($report['restored_at'])) {
            $activeProfile = sanitize_key((string) ($report['profile_slug'] ?? ''));
        }

        $snapshotId = sanitize_text_field((string) ($snapshot['id'] ?? ''));
        $snapshotState = sanitize_text_field((string) ($snapshot['state_after'] ?? ''));
        $canRestore = $snapshotId !== '' && $snapshotState !== '' && hash_equals($snapshotState, $stateHash);
        $themePackLabels = [];
        foreach ($this->themePackCatalog() as $themePack) {
            $themePackSlug = sanitize_key((string) ($themePack['slug'] ?? ''));
            if ($themePackSlug !== '') {
                $themePackLabels[$themePackSlug] = sanitize_text_field((string) ($themePack['label'] ?? $themePackSlug));
            }
        }
        ?>
        <section class="h4bs-site-launch<?php echo $compact ? ' is-compact' : ''; ?>" aria-labelledby="h4bs-site-launch-title">
            <div class="h4bs-site-launch-heading">
                <div>
                    <span class="h4bs-admin-kicker"><?php esc_html_e('One plugin. One launch plan.', 'help4-builder-suite'); ?></span>
                    <h2 id="h4bs-site-launch-title"><?php esc_html_e('Help4 Site Launch Center', 'help4-builder-suite'); ?></h2>
                    <p class="h4bs-admin-lead"><?php esc_html_e('Choose what you are building and Help4 will configure the matching Builder, templates, fields, forms, SEO, redirects, security, performance, images, commerce, membership, and operations modules. Existing payment credentials, API keys, and endpoint secrets are preserved.', 'help4-builder-suite'); ?></p>
                </div>
                <div class="h4bs-launch-summary" aria-label="<?php esc_attr_e('Site readiness summary', 'help4-builder-suite'); ?>">
                    <strong><?php esc_html_e('Launch readiness', 'help4-builder-suite'); ?></strong>
                    <span class="is-pass"><?php echo esc_html($passedSummary); ?></span>
                    <?php if ($statusCounts['warn'] > 0) : ?>
                        <span class="is-warn"><?php echo esc_html($warningSummary); ?></span>
                    <?php endif; ?>
                    <?php if ($statusCounts['fail'] > 0) : ?>
                        <span class="is-fail"><?php echo esc_html($blockerSummary); ?></span>
                    <?php endif; ?>
                </div>
            </div>

            <details class="h4bs-launch-readiness"<?php echo $statusCounts['fail'] > 0 ? ' open' : ''; ?>>
                <summary><?php esc_html_e('Review WordPress and hosting readiness', 'help4-builder-suite'); ?></summary>
                <div class="h4bs-launch-checks">
                    <?php foreach ($checks as $check) : ?>
                        <?php $status = (string) ($check['status'] ?? 'warn'); ?>
                        <div class="h4bs-launch-check is-<?php echo esc_attr($status); ?>">
                            <span class="h4bs-launch-check-mark" aria-hidden="true"><?php echo $status === 'pass' ? '&#10003;' : ($status === 'fail' ? '!' : '&#8226;'); ?></span>
                            <div>
                                <strong><?php echo esc_html((string) ($check['label'] ?? '')); ?></strong>
                                <span><?php echo esc_html((string) ($check['detail'] ?? '')); ?></span>
                            </div>
                            <?php if (! empty($check['action_url']) && ! empty($check['action_label'])) : ?>
                                <a href="<?php echo esc_url((string) $check['action_url']); ?>"><?php echo esc_html((string) $check['action_label']); ?></a>
                            <?php endif; ?>
                        </div>
                    <?php endforeach; ?>
                </div>
            </details>

            <div class="h4bs-launch-profile-grid">
                <?php foreach ($profiles as $profileSlug => $profile) : ?>
                    <?php
                    $plan = $this->buildSiteLaunchPlan((string) $profileSlug);
                    if (is_wp_error($plan)) {
                        continue;
                    }
                    $flags = is_array($plan['feature_flags'] ?? null) ? $plan['feature_flags'] : [];
                    $enabledFlags = array_keys(array_filter($flags));
                    $themePackSlug = sanitize_key((string) ($plan['theme_pack_slug'] ?? ''));
                    $isActive = $activeProfile === (string) $profileSlug;
                    ?>
                    <article class="h4bs-launch-profile<?php echo $isActive ? ' is-current' : ''; ?>">
                        <div class="h4bs-launch-profile-title">
                            <h3><?php echo esc_html((string) ($profile['label'] ?? $profileSlug)); ?></h3>
                            <?php if ($isActive) : ?>
                                <span><?php esc_html_e('Current', 'help4-builder-suite'); ?></span>
                            <?php endif; ?>
                        </div>
                        <p><?php echo esc_html((string) ($profile['description'] ?? '')); ?></p>
                        <?php if (! empty($profile['outcomes']) && is_array($profile['outcomes'])) : ?>
                            <ul class="h4bs-launch-outcomes">
                                <?php foreach ($profile['outcomes'] as $outcome) : ?>
                                    <li><?php echo esc_html((string) $outcome); ?></li>
                                <?php endforeach; ?>
                            </ul>
                        <?php endif; ?>
                        <p class="h4bs-launch-profile-meta">
                            <?php
                            echo esc_html(sprintf(
                                /* translators: 1: enabled module count, 2: theme pack name */
                                __('%1$d compartmentalized modules | %2$s design pack', 'help4-builder-suite'),
                                count($enabledFlags),
                                (string) ($themePackLabels[$themePackSlug] ?? $themePackSlug)
                            ));
                            ?>
                        </p>
                        <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
                            <?php wp_nonce_field('h4bs_apply_site_launch_profile', 'h4bs_site_launch_nonce'); ?>
                            <input type="hidden" name="action" value="h4bs_apply_site_launch_profile">
                            <input type="hidden" name="profile_slug" value="<?php echo esc_attr((string) $profileSlug); ?>">
                            <input type="hidden" name="state_hash" value="<?php echo esc_attr($stateHash); ?>">
                            <button type="submit" class="button<?php echo $profileSlug === 'complete_suite' ? ' button-primary' : ''; ?>">
                                <?php echo esc_html($isActive ? __('Reapply current plan', 'help4-builder-suite') : __('Apply this launch plan', 'help4-builder-suite')); ?>
                            </button>
                        </form>
                    </article>
                <?php endforeach; ?>
            </div>

            <?php if ($snapshotId !== '') : ?>
                <div class="h4bs-launch-rollback">
                    <div>
                        <strong><?php esc_html_e('One-click launch rollback', 'help4-builder-suite'); ?></strong>
                        <p>
                            <?php echo esc_html($canRestore
                                ? __('Restore the module, design-token, wizard, and launch-setting state captured immediately before the last profile was applied.', 'help4-builder-suite')
                                : __('The site changed after the last profile was applied, so automatic rollback is locked to protect newer work.', 'help4-builder-suite')); ?>
                        </p>
                    </div>
                    <?php if ($canRestore) : ?>
                        <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
                            <?php wp_nonce_field('h4bs_restore_site_launch_snapshot', 'h4bs_site_launch_restore_nonce'); ?>
                            <input type="hidden" name="action" value="h4bs_restore_site_launch_snapshot">
                            <input type="hidden" name="snapshot_id" value="<?php echo esc_attr($snapshotId); ?>">
                            <button type="submit" class="button"><?php esc_html_e('Restore pre-launch settings', 'help4-builder-suite'); ?></button>
                        </form>
                    <?php endif; ?>
                </div>
            <?php endif; ?>
            <p class="h4bs-launch-footnote"><?php esc_html_e('Applying a profile never creates public demo pages and never installs or activates a theme without a separate administrator confirmation.', 'help4-builder-suite'); ?></p>
        </section>
        <?php
    }

    private function renderTutorialHub(): void
    {
        $items = $this->tutorialHubItems();
        ?>
        <section class="h4bs-admin-tutorial-hub" aria-labelledby="h4bs-tutorial-hub-title">
            <div>
                <span class="h4bs-admin-kicker"><?php esc_html_e('Start here', 'help4-builder-suite'); ?></span>
                <h2 id="h4bs-tutorial-hub-title"><?php esc_html_e('Builder tutorials for the next thing you need to do', 'help4-builder-suite'); ?></h2>
                <p class="h4bs-admin-lead"><?php esc_html_e('Use these evergreen page tutorials when you need the plain-English path from install to first page, templates, fields, commerce, forms, SEO, security, performance, and updates. Pick the job in front of you and open that guide.', 'help4-builder-suite'); ?></p>
                <p><a class="button button-primary" href="<?php echo esc_url($this->tutorialUrl('help4-builder-tutorials')); ?>" target="_blank" rel="noopener"><?php esc_html_e('Search all Help4 tutorials', 'help4-builder-suite'); ?></a> <a class="button" href="<?php echo esc_url($this->tutorialUrl('help4-builder-screenshots')); ?>" target="_blank" rel="noopener"><?php esc_html_e('Compare blank-install screens', 'help4-builder-suite'); ?></a></p>
            </div>
            <div class="h4bs-admin-card-grid h4bs-admin-tutorial-grid">
                <?php foreach ($items as $item) : ?>
                    <article class="h4bs-admin-card">
                        <h3><?php echo esc_html((string) $item['title']); ?></h3>
                        <p><?php echo esc_html((string) $item['copy']); ?></p>
                        <p class="h4bs-admin-card-action">
                            <a href="<?php echo esc_url((string) $item['url']); ?>" target="_blank" rel="noopener">
                                <?php echo esc_html((string) $item['action']); ?>
                            </a>
                        </p>
                    </article>
                <?php endforeach; ?>
            </div>
        </section>
        <?php
    }

    /**
     * @return array<int, array{title:string, copy:string, action:string, url:string}>
     */
    private function tutorialHubItems(): array
    {
        return [
            [
                'title' => __('Install and setup', 'help4-builder-suite'),
                'copy' => __('Download the plugin, install Help4 Blank, activate modules, and run the setup wizard without command-line steps.', 'help4-builder-suite'),
                'action' => __('Open install tutorial', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-guide'),
            ],
            [
                'title' => __('Build the first page', 'help4-builder-suite'),
                'copy' => __('Open Builder Pages, launch Builder Studio, add layout sections, and clean up responsive settings before publishing.', 'help4-builder-suite'),
                'action' => __('Open first-page tutorial', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-first-page'),
            ],
            [
                'title' => __('Build a sales homepage', 'help4-builder-suite'),
                'copy' => __('Turn an offer into open content bands for proof, services, packages, process, FAQ, and one clear contact or checkout path.', 'help4-builder-suite'),
                'action' => __('Open homepage guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-sales-homepage'),
            ],
            [
                'title' => __('Pricing comparisons', 'help4-builder-suite'),
                'copy' => __('Compare up to five plans with honest feature rows and a mobile layout that keeps every value attached to its label.', 'help4-builder-suite'),
                'action' => __('Open pricing guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-pricing-comparison'),
            ],
            [
                'title' => __('FAQ accordion and schema', 'help4-builder-suite'),
                'copy' => __('Build keyboard-accessible FAQ disclosures and structured data that matches the answers visitors can actually read.', 'help4-builder-suite'),
                'action' => __('Open FAQ guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-faq-accordion-schema'),
            ],
            [
                'title' => __('Builder Studio deep dives', 'help4-builder-suite'),
                'copy' => __('Learn live preview, Navigator layers, safe media replacement, design controls, dynamic data, forms, motion, and migration workflows.', 'help4-builder-suite'),
                'action' => __('Open live preview guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-live-preview-workflow'),
            ],
            [
                'title' => __('Save, preview, and publish', 'help4-builder-suite'),
                'copy' => __('Understand what remains a private Studio draft, what Save Element & Publish commits, how revision conflicts work, and how to verify the public page.', 'help4-builder-suite'),
                'action' => __('Open publishing guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-save-preview-publish'),
            ],
            [
                'title' => __('Template conditions', 'help4-builder-suite'),
                'copy' => __('Assign headers, footers, single templates, archives, search, 404, and canvas layouts using explicit scopes, exclusions, and priorities.', 'help4-builder-suite'),
                'action' => __('Open condition guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-theme-builder-template-conditions'),
            ],
            [
                'title' => __('Header and footer launch', 'help4-builder-suite'),
                'copy' => __('Preserve the exact logo, build native menus and mobile controls, finish legal/support links, and verify global template assignments.', 'help4-builder-suite'),
                'action' => __('Open site shell guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-header-footer-launch'),
            ],
            [
                'title' => __('Reusable and global sections', 'help4-builder-suite'),
                'copy' => __('Choose copied, reusable, or condition-assigned content so a local edit never becomes an unexpected site-wide change.', 'help4-builder-suite'),
                'action' => __('Open reusable sections guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-reusable-global-sections'),
            ],
            [
                'title' => __('Safe editing and recovery', 'help4-builder-suite'),
                'copy' => __('Replace images without losing neighboring content, handle stale drafts, and load a page-local recovery point from Builder History.', 'help4-builder-suite'),
                'action' => __('Open recovery guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-safe-editing-recovery'),
            ],
            [
                'title' => __('Responsive design', 'help4-builder-suite'),
                'copy' => __('Set real desktop, tablet, and mobile spacing, widths, columns, alignment, and typography while checking common breakpoint edges.', 'help4-builder-suite'),
                'action' => __('Open responsive guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-responsive-design'),
            ],
            [
                'title' => __('Global styles and theme packs', 'help4-builder-suite'),
                'copy' => __('Manage semantic colors, typography, spacing, shape, and style-only packs without replacing the current page structure.', 'help4-builder-suite'),
                'action' => __('Open global styles guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-global-styles-theme-packs'),
            ],
            [
                'title' => __('Templates and icons', 'help4-builder-suite'),
                'copy' => __('Choose starter templates, apply a theme pack, use default icons, and open the AI image prompt guide so the first site does not start empty.', 'help4-builder-suite'),
                'action' => __('Open template tutorial', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-templates'),
            ],
            [
                'title' => __('AI image prompt guide', 'help4-builder-suite'),
                'copy' => __('Use prompt briefs for hero images, service proof, product scenes, tutorial visuals, social previews, and recent-work cards before uploading media into Builder.', 'help4-builder-suite'),
                'action' => __('Open image prompt guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-ai-image-prompts'),
            ],
            [
                'title' => __('Template library chooser', 'help4-builder-suite'),
                'copy' => __('Pick from the 135 starter specs by customer problem: header, footer, 404, page shell, canvas landing page, service page, product flow, proof page, design handoff, rescue page, or docs hub.', 'help4-builder-suite'),
                'action' => __('Open template library guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-template-library'),
            ],
            [
                'title' => __('Module controls', 'help4-builder-suite'),
                'copy' => __('Turn on only the builder, commerce, field, form, SEO, security, and performance modules this site actually needs.', 'help4-builder-suite'),
                'action' => __('Open module guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-module-controls'),
            ],
            [
                'title' => __('Fields and dynamic content', 'help4-builder-suite'),
                'copy' => __('Use structured field groups, repeaters, relationships, and dynamic output for richer pages without one-off admin screens.', 'help4-builder-suite'),
                'action' => __('Open fields tutorial', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-fields'),
            ],
            [
                'title' => __('Commerce and payments', 'help4-builder-suite'),
                'copy' => __('Start native catalog, variations, subscriptions, and payment-routing workflows from the Commerce control area.', 'help4-builder-suite'),
                'action' => __('Open commerce tutorial', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-commerce-getting-started'),
            ],
            [
                'title' => __('Advanced commerce and customer fields', 'help4-builder-suite'),
                'copy' => __('Configure product variants, subscriptions, dynamic customer fields, payment routes, and complete order-lifecycle testing.', 'help4-builder-suite'),
                'action' => __('Open advanced commerce guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-commerce-products-variations-customer-fields'),
            ],
            [
                'title' => __('Commerce launch testing', 'help4-builder-suite'),
                'copy' => __('Test products, variations, customer fields, totals, payments, webhooks, subscriptions, refunds, email, and mobile checkout before accepting live orders.', 'help4-builder-suite'),
                'action' => __('Open commerce launch guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-commerce-launch-testing'),
            ],
            [
                'title' => __('Stripe Router setup', 'help4-builder-suite'),
                'copy' => __('Connect multiple Stripe accounts, create product and geographic assignments, compare Pro and Enterprise, and validate checkout before live traffic.', 'help4-builder-suite'),
                'action' => __('Open Stripe Router tutorial', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('stripe-router-tutorial'),
            ],
            [
                'title' => __('Help4 Net CDN and WAF', 'help4-builder-suite'),
                'copy' => __('Compare free plugin onboarding, the Help4 Net Pro CDN and GeoDNS path, and managed full-proxy WAF service.', 'help4-builder-suite'),
                'action' => __('Open CDN buyer guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-net-wordpress-cdn-waf'),
            ],
            [
                'title' => __('Menus, headers, and footers', 'help4-builder-suite'),
                'copy' => __('Build accessible menu hierarchy, dependable hover dropdowns, mobile navigation, and global template assignments.', 'help4-builder-suite'),
                'action' => __('Open navigation guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-menus-headers-footers'),
            ],
            [
                'title' => __('Sliders and forms', 'help4-builder-suite'),
                'copy' => __('Use motion sections and lead forms where they support the offer, then keep those assets off pages that do not use them.', 'help4-builder-suite'),
                'action' => __('Open sliders and forms guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-sliders-forms'),
            ],
            [
                'title' => __('SEO, security, speed', 'help4-builder-suite'),
                'copy' => __('Turn on metadata, schema, redirects, headers, SSL, image optimization, and performance defaults in the right order.', 'help4-builder-suite'),
                'action' => __('Open launch checklist', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-seo-security-performance'),
            ],
            [
                'title' => __('Local and international SEO', 'help4-builder-suite'),
                'copy' => __('Configure business entities, social metadata, structured data, language targeting, IndexNow, sitemaps, and indexing health.', 'help4-builder-suite'),
                'action' => __('Open advanced SEO guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-seo-local-international-indexnow'),
            ],
            [
                'title' => __('WordPress multisite', 'help4-builder-suite'),
                'copy' => __('Provision helpful defaults across a network while preserving site ownership, data isolation, search settings, and bounded background jobs.', 'help4-builder-suite'),
                'action' => __('Open multisite guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-multisite-guide'),
            ],
            [
                'title' => __('Migration and troubleshooting', 'help4-builder-suite'),
                'copy' => __('Diagnose preview differences, missing media, lost styling, cache problems, theme assets, and migration issues with an evidence-first checklist.', 'help4-builder-suite'),
                'action' => __('Open troubleshooting guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-migration-troubleshooting'),
            ],
            [
                'title' => __('Updates and WordPress 7', 'help4-builder-suite'),
                'copy' => __('Keep public sites on the stable release path while a separate test install checks Builder Suite, templates, forms, commerce, and admin screens against the next core release.', 'help4-builder-suite'),
                'action' => __('Open update guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-builder-updates-wordpress-7'),
            ],
            [
                'title' => __('Email marketing and drip campaigns', 'help4-builder-suite'),
                'copy' => __('Configure subscribed audiences, sender verification, templates, segments, queues, suppression, privacy tools, and engagement reports.', 'help4-builder-suite'),
                'action' => __('Open email marketing guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-email-marketing-newsletters-drip-campaigns'),
            ],
            [
                'title' => __('Images, optimization, and search', 'help4-builder-suite'),
                'copy' => __('Prepare responsive media in Image Studio, verify modern delivery formats, then configure useful search across pages, posts, and native products.', 'help4-builder-suite'),
                'action' => __('Open image workflow guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-image-optimization-image-studio'),
            ],
            [
                'title' => __('Redirects, 404s, and diagnostics', 'help4-builder-suite'),
                'copy' => __('Repair old URLs with narrow one-hop rules, monitor 404 evidence, and use Insights plus fresh logs to diagnose real failures.', 'help4-builder-suite'),
                'action' => __('Open redirect guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-redirects-404-monitoring'),
            ],
            [
                'title' => __('Performance and security operations', 'help4-builder-suite'),
                'copy' => __('Measure cache and asset behavior, reduce unused module cost, harden transport and access safely, and rerun the functional matrix.', 'help4-builder-suite'),
                'action' => __('Open performance guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-performance-cache-assets-guide'),
            ],
            [
                'title' => __('I.G.O.R. feedback diagnostics', 'help4-builder-suite'),
                'copy' => __('Send one privacy-safe report with the affected target, reproduction steps, versions, viewport, expected result, and fresh evidence.', 'help4-builder-suite'),
                'action' => __('Open feedback guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-feedback-igor-diagnostics'),
            ],
            [
                'title' => __('Learning sites and protected media', 'help4-builder-suite'),
                'copy' => __('Test courses, progress, certificates, HLS video, protected resources, and Builder templates across anonymous, member, editor, and completed states.', 'help4-builder-suite'),
                'action' => __('Open LMS guide', 'help4-builder-suite'),
                'url' => $this->tutorialUrl('help4-lms-courses-progress-certificates'),
            ],
        ];
    }

    private function tutorialUrl(string $slug): string
    {
        $slug = trim(sanitize_title($slug), '/');
        $host = strtolower((string) wp_parse_url(home_url('/'), PHP_URL_HOST));
        $base = $host === 'md.help4wordpress.com'
            ? 'https://md.help4wordpress.com/'
            : 'https://help4wordpress.com/';

        return $base . $slug . '/';
    }

    public function contextualAdminHelpFooter(string $footerText): string
    {
        if (! is_admin() || ! current_user_can('edit_posts') || ! function_exists('get_current_screen')) {
            return $footerText;
        }

        $screen = get_current_screen();
        $screenId = $screen instanceof \WP_Screen ? strtolower((string) $screen->id) : '';
        if ($screenId === '') {
            return $footerText;
        }

        $guides = [
            'h4bs-builder-studio' => ['help4-builder-editor-controls', __('Open the guide for this Builder screen', 'help4-builder-suite')],
            'h4bs-builder-pages' => ['help4-builder-first-page', __('Open the Builder Pages guide', 'help4-builder-suite')],
            'h4bs-theme-builder' => ['help4-theme-builder-template-conditions', __('Open the Theme Builder guide', 'help4-builder-suite')],
            'h4bs-email-marketing' => ['help4-email-marketing-newsletters-drip-campaigns', __('Open the email marketing guide', 'help4-builder-suite')],
            'h4bs-image-studio' => ['help4-image-optimization-image-studio', __('Open the Image Studio guide', 'help4-builder-suite')],
            'h4bs-redirection' => ['help4-redirects-404-monitoring', __('Open the redirects and 404 guide', 'help4-builder-suite')],
            'h4bs-insights' => ['help4-insights-site-health-shortcodes', __('Open the Insights guide', 'help4-builder-suite')],
            'h4bs-shortcode-registry' => ['help4-insights-site-health-shortcodes', __('Open the shortcode diagnostics guide', 'help4-builder-suite')],
            'h4bs-security' => ['help4-security-hardening-guide', __('Open the security hardening guide', 'help4-builder-suite')],
            'h4bs-igor-feedback' => ['help4-feedback-igor-diagnostics', __('Open the I.G.O.R. reporting guide', 'help4-builder-suite')],
            'h4bs-lms' => ['help4-lms-courses-progress-certificates', __('Open the LMS guide', 'help4-builder-suite')],
            'h4bs-seo-control' => ['help4-seo-local-international-indexnow', __('Open the SEO guide', 'help4-builder-suite')],
            'h4bs-forms' => ['help4-builder-forms-lead-capture', __('Open the forms guide', 'help4-builder-suite')],
            'h4bs-form-entries' => ['help4-builder-forms-lead-capture', __('Open the form delivery guide', 'help4-builder-suite')],
            'h4bs-commerce' => ['help4-commerce-products-variations-customer-fields', __('Open the Help4 Commerce guide', 'help4-builder-suite')],
            'h4bs-settings' => ['help4-builder-tutorials', __('Search all Help4 tutorials', 'help4-builder-suite')],
        ];

        foreach ($guides as $screenNeedle => $guide) {
            if (! str_contains($screenId, $screenNeedle)) {
                continue;
            }
            $link = '<a href="' . esc_url($this->tutorialUrl((string) $guide[0])) . '" target="_blank" rel="noopener"><span class="dashicons dashicons-editor-help" aria-hidden="true"></span> ' . esc_html((string) $guide[1]) . '</a>';
            return $footerText !== '' ? $footerText . ' <span aria-hidden="true">|</span> ' . $link : $link;
        }

        return $footerText;
    }

    private function wizardBypassActive(): bool
    {
        $userId = get_current_user_id();
        if ($userId <= 0) {
            return false;
        }

        $until = (int) get_user_meta($userId, self::WIZARD_BYPASS_META, true);
        if ($until <= time()) {
            if ($until > 0) {
                delete_user_meta($userId, self::WIZARD_BYPASS_META);
            }
            return false;
        }

        return true;
    }

    private function setWizardBypassForCurrentUser(int $seconds = 300): void
    {
        $userId = get_current_user_id();
        if ($userId <= 0) {
            return;
        }
        $seconds = max(30, min(7200, $seconds));
        update_user_meta($userId, self::WIZARD_BYPASS_META, time() + $seconds);
    }

    /**
     * @return array<int, array<string, mixed>>
     */
    private function themePackCatalog(): array
    {
        $defaultThumb = defined('H4BS_URL')
            ? (string) H4BS_URL . 'assets/demo/responsive-devices-dark.svg'
            : '';
        $packs = [
            [
                'slug' => 'help4-foundation',
                'label' => 'Help4 Foundation',
                'description' => 'Clean, balanced base pack for service and SaaS sites.',
                'industry' => 'General',
                'tokens' => [
                    'colors' => ['primary' => '#0f6cbf', 'secondary' => '#0a9b7a', 'accent' => '#ff7a33', 'text' => '#1f2937', 'surface' => '#ffffff'],
                    'fonts' => ['heading' => 'Poppins', 'body' => 'Inter', 'base_size' => '16'],
                    'layout' => ['container_max_width' => '1200', 'container_max_width_unit' => 'px', 'structure_columns' => '2', 'structure_gap' => '20', 'structure_min_height' => '160'],
                ],
            ],
            [
                'slug' => 'help4-enterprise-dark',
                'label' => 'Enterprise Dark',
                'description' => 'High-contrast enterprise pack for agencies and managed hosting brands.',
                'industry' => 'Agency + Enterprise',
                'tokens' => [
                    'colors' => ['primary' => '#1f78e0', 'secondary' => '#19b79e', 'accent' => '#ffb347', 'text' => '#e8f0f8', 'surface' => '#0f1d2a'],
                    'fonts' => ['heading' => 'Montserrat', 'body' => 'Open Sans', 'base_size' => '16'],
                    'layout' => ['container_max_width' => '1320', 'container_max_width_unit' => 'px', 'structure_columns' => '3', 'structure_gap' => '24', 'structure_min_height' => '180'],
                ],
            ],
            [
                'slug' => 'help4-contractor-pro',
                'label' => 'Contractor Pro',
                'description' => 'Quote-first layout pack for plumbers, roofers, HVAC, and field services.',
                'industry' => 'Contractor + Trades',
                'tokens' => [
                    'colors' => ['primary' => '#c15e16', 'secondary' => '#2a7f4f', 'accent' => '#f2b130', 'text' => '#1d242b', 'surface' => '#fffdf8'],
                    'fonts' => ['heading' => 'Oswald', 'body' => 'Roboto', 'base_size' => '16'],
                    'layout' => ['container_max_width' => '1240', 'container_max_width_unit' => 'px', 'structure_columns' => '2', 'structure_gap' => '22', 'structure_min_height' => '170'],
                ],
            ],
            [
                'slug' => 'help4-realtor-luxe',
                'label' => 'Realtor Luxe',
                'description' => 'Listing-forward pack for agent teams with map/search focused sections.',
                'industry' => 'Realtor + IDX',
                'tokens' => [
                    'colors' => ['primary' => '#1a4f93', 'secondary' => '#2f8fb5', 'accent' => '#c68f2f', 'text' => '#1e2c3a', 'surface' => '#f7fafc'],
                    'fonts' => ['heading' => 'Playfair Display', 'body' => 'Lato', 'base_size' => '16'],
                    'layout' => ['container_max_width' => '1360', 'container_max_width_unit' => 'px', 'structure_columns' => '3', 'structure_gap' => '24', 'structure_min_height' => '180'],
                ],
            ],
            [
                'slug' => 'help4-commerce-neo',
                'label' => 'Commerce Neo',
                'description' => 'Shop-focused pack with product-grid spacing and checkout-forward defaults.',
                'industry' => 'Commerce',
                'tokens' => [
                    'colors' => ['primary' => '#4f46e5', 'secondary' => '#0ea5e9', 'accent' => '#f97316', 'text' => '#1f2937', 'surface' => '#ffffff'],
                    'fonts' => ['heading' => 'Poppins', 'body' => 'Inter', 'base_size' => '16'],
                    'layout' => ['container_max_width' => '1400', 'container_max_width_unit' => 'px', 'structure_columns' => '4', 'structure_gap' => '20', 'structure_min_height' => '160'],
                ],
            ],
            [
                'slug' => 'help4-speed-lite',
                'label' => 'Speed Lite',
                'description' => 'Lean performance preset with tighter spacing and lighter defaults.',
                'industry' => 'Performance',
                'tokens' => [
                    'colors' => ['primary' => '#0f6cbf', 'secondary' => '#0a9b7a', 'accent' => '#ff7a33', 'text' => '#1d2935', 'surface' => '#ffffff'],
                    'fonts' => ['heading' => 'Poppins', 'body' => 'Inter', 'base_size' => '15'],
                    'layout' => ['container_max_width' => '1120', 'container_max_width_unit' => 'px', 'structure_columns' => '2', 'structure_gap' => '14', 'structure_min_height' => '120'],
                ],
            ],
        ];

        $catalog = [];
        foreach ($packs as $pack) {
            if (! is_array($pack)) {
                continue;
            }
            $slug = sanitize_key((string) ($pack['slug'] ?? ''));
            if ($slug === '') {
                continue;
            }
            $catalog[] = [
                'slug' => $slug,
                'label' => sanitize_text_field((string) ($pack['label'] ?? $slug)),
                'description' => sanitize_text_field((string) ($pack['description'] ?? '')),
                'industry' => sanitize_text_field((string) ($pack['industry'] ?? 'General')),
                'thumbnail' => esc_url_raw((string) ($pack['thumbnail'] ?? $defaultThumb)),
                'tokens' => $this->sanitizeThemePackTokens($pack['tokens'] ?? []),
            ];
        }

        return $catalog;
    }

    private function recommendedThemePackSlug(string $businessType): string
    {
        $slug = BusinessProfileDefaults::themePackSlug($businessType);
        return $this->themePackBySlug($slug) ? $slug : 'help4-foundation';
    }

    private function activeThemePackSlug(): string
    {
        $slug = sanitize_key((string) get_option('h4bs_active_theme_pack', ''));
        if ($slug === '') {
            return '';
        }
        return $this->themePackBySlug($slug) ? $slug : '';
    }

    /**
     * @return array<string, mixed>|null
     */
    private function themePackBySlug(string $slug): ?array
    {
        $needle = sanitize_key($slug);
        if ($needle === '') {
            return null;
        }
        foreach ($this->themePackCatalog() as $pack) {
            if ((string) ($pack['slug'] ?? '') === $needle) {
                return $pack;
            }
        }
        return null;
    }

    /**
     * @param mixed $raw
     * @return array{
     *   colors: array<string, string>,
     *   fonts: array<string, string>,
     *   layout: array<string, string>
     * }
     */
    private function sanitizeThemePackTokens($raw): array
    {
        if (is_string($raw)) {
            $decoded = json_decode($raw, true);
            $raw = is_array($decoded) ? $decoded : [];
        }
        $source = is_array($raw) ? $raw : [];
        $sourceColors = is_array($source['colors'] ?? null) ? $source['colors'] : [];
        $sourceFonts = is_array($source['fonts'] ?? null) ? $source['fonts'] : [];
        $sourceLayout = is_array($source['layout'] ?? null) ? $source['layout'] : [];

        $defaultColors = [
            'primary' => '#0f6cbf',
            'secondary' => '#0a9b7a',
            'accent' => '#ff7a33',
            'text' => '#1f2937',
            'surface' => '#ffffff',
        ];
        $defaultFonts = [
            'heading' => 'Poppins',
            'body' => 'Inter',
            'base_size' => '16',
        ];
        $defaultLayout = [
            'container_max_width' => '1200',
            'container_max_width_unit' => 'px',
            'structure_columns' => '2',
            'structure_gap' => '18',
            'structure_min_height' => '140',
            'structure_layout_mode' => 'grid',
            'structure_content_width_mode' => 'inherit',
            'structure_flex_direction' => 'row',
            'structure_flex_wrap' => 'wrap',
            'structure_justify_content' => 'flex-start',
            'structure_align_items' => 'stretch',
            'structure_align_content' => 'stretch',
        ];

        $colors = [];
        foreach ($defaultColors as $key => $fallback) {
            $candidate = sanitize_hex_color((string) ($sourceColors[$key] ?? ''));
            $colors[$key] = is_string($candidate) && $candidate !== '' ? $candidate : $fallback;
        }

        $fonts = [];
        foreach (['heading', 'body'] as $key) {
            $candidate = sanitize_text_field((string) ($sourceFonts[$key] ?? ''));
            $fonts[$key] = $candidate !== '' ? $candidate : $defaultFonts[$key];
        }
        $fonts['base_size'] = (string) max(12, min(24, (int) ($sourceFonts['base_size'] ?? $defaultFonts['base_size'])));

        $containerMaxWidth = (float) ($sourceLayout['container_max_width'] ?? $defaultLayout['container_max_width']);
        if (! is_finite($containerMaxWidth) || $containerMaxWidth <= 0) {
            $containerMaxWidth = (float) $defaultLayout['container_max_width'];
        }
        $containerMaxWidth = max(320.0, min(7680.0, $containerMaxWidth));
        $containerMaxWidthUnit = strtolower(trim((string) ($sourceLayout['container_max_width_unit'] ?? $defaultLayout['container_max_width_unit'])));
        if (! in_array($containerMaxWidthUnit, ['px', '%', 'vw', 'vh', 'rem', 'em'], true)) {
            $containerMaxWidthUnit = 'px';
        }

        $structureColumns = (int) ($sourceLayout['structure_columns'] ?? $defaultLayout['structure_columns']);
        $structureColumns = max(1, min(24, $structureColumns));
        $structureGap = (int) ($sourceLayout['structure_gap'] ?? $defaultLayout['structure_gap']);
        $structureGap = max(0, min(160, $structureGap));
        $structureMinHeight = (int) ($sourceLayout['structure_min_height'] ?? $defaultLayout['structure_min_height']);
        $structureMinHeight = max(40, min(2400, $structureMinHeight));

        $layoutMode = sanitize_key((string) ($sourceLayout['structure_layout_mode'] ?? $defaultLayout['structure_layout_mode']));
        if (! in_array($layoutMode, ['grid', 'flex'], true)) {
            $layoutMode = 'grid';
        }
        $contentWidthMode = sanitize_key((string) ($sourceLayout['structure_content_width_mode'] ?? $defaultLayout['structure_content_width_mode']));
        if (! in_array($contentWidthMode, ['inherit', 'custom', 'full'], true)) {
            $contentWidthMode = 'inherit';
        }
        $flexDirection = sanitize_key((string) ($sourceLayout['structure_flex_direction'] ?? $defaultLayout['structure_flex_direction']));
        if (! in_array($flexDirection, ['row', 'row-reverse', 'column', 'column-reverse'], true)) {
            $flexDirection = 'row';
        }
        $flexWrap = sanitize_key((string) ($sourceLayout['structure_flex_wrap'] ?? $defaultLayout['structure_flex_wrap']));
        if (! in_array($flexWrap, ['nowrap', 'wrap', 'wrap-reverse'], true)) {
            $flexWrap = 'wrap';
        }
        $justifyContent = sanitize_key((string) ($sourceLayout['structure_justify_content'] ?? $defaultLayout['structure_justify_content']));
        if (! in_array($justifyContent, ['flex-start', 'center', 'flex-end', 'space-between', 'space-around', 'space-evenly'], true)) {
            $justifyContent = 'flex-start';
        }
        $alignItems = sanitize_key((string) ($sourceLayout['structure_align_items'] ?? $defaultLayout['structure_align_items']));
        if (! in_array($alignItems, ['stretch', 'flex-start', 'center', 'flex-end', 'baseline'], true)) {
            $alignItems = 'stretch';
        }
        $alignContent = sanitize_key((string) ($sourceLayout['structure_align_content'] ?? $defaultLayout['structure_align_content']));
        if (! in_array($alignContent, ['stretch', 'flex-start', 'center', 'flex-end', 'space-between', 'space-around', 'space-evenly'], true)) {
            $alignContent = 'stretch';
        }

        return [
            'colors' => $colors,
            'fonts' => $fonts,
            'layout' => [
                'container_max_width' => rtrim(rtrim(number_format($containerMaxWidth, 2, '.', ''), '0'), '.'),
                'container_max_width_unit' => $containerMaxWidthUnit,
                'structure_columns' => (string) $structureColumns,
                'structure_gap' => (string) $structureGap,
                'structure_min_height' => (string) $structureMinHeight,
                'structure_layout_mode' => $layoutMode,
                'structure_content_width_mode' => $contentWidthMode,
                'structure_flex_direction' => $flexDirection,
                'structure_flex_wrap' => $flexWrap,
                'structure_justify_content' => $justifyContent,
                'structure_align_items' => $alignItems,
                'structure_align_content' => $alignContent,
            ],
        ];
    }

    /**
     * @return array<string, string>
     */
    private function featureLabels(): array
    {
        return [
            'template_library' => __('Template Library', 'help4-builder-suite'),
            'slider'           => __('Slider Engine', 'help4-builder-suite'),
            'seo'              => __('SEO Layer', 'help4-builder-suite'),
            'commerce'         => __('Commerce Core', 'help4-builder-suite'),
            'forms'            => __('Forms + Newsletter', 'help4-builder-suite'),
            'redirection'      => __('Redirects + 404 Logs', 'help4-builder-suite'),
            'search'           => __('Advanced Search', 'help4-builder-suite'),
            'fields'           => __('Custom Field Engine', 'help4-builder-suite'),
            'industry'         => __('Industry Packs', 'help4-builder-suite'),
            'lms'              => __('LMS + Certifications', 'help4-builder-suite'),
            'mega_menu'        => __('Mega Menu', 'help4-builder-suite'),
            'builder'          => __('Visual Builder', 'help4-builder-suite'),
            'addon_pack'       => __('Advanced Widget Library', 'help4-builder-suite'),
            'licensing'        => __('Updates (always on)', 'help4-builder-suite'),
            'dependency'       => __('Dependency Manager', 'help4-builder-suite'),
            'security'         => __('Security Hardening', 'help4-builder-suite'),
            'performance'      => __('Performance Layer', 'help4-builder-suite'),
            'image_optimization' => __('Image Optimization', 'help4-builder-suite'),
            'insights'         => __('Insights and Speed Reports', 'help4-builder-suite'),
            'cutover'          => __('Site Cutover and Migration', 'help4-builder-suite'),
            'feedback'         => __('I.G.O.R. Feedback Reports', 'help4-builder-suite'),
            'demos'            => __('Demo Lab and Seeders', 'help4-builder-suite'),
        ];
    }

    /**
     * @param array<string, mixed> $settings
     */
    private function textField(string $key, string $label, array $settings): void
    {
        ?>
        <tr>
            <th scope="row"><?php echo esc_html($label); ?></th>
            <td>
                <input
                    class="regular-text"
                    type="text"
                    name="<?php echo esc_attr("h4bs_settings[{$key}]"); ?>"
                    value="<?php echo esc_attr((string) ($settings[$key] ?? '')); ?>"
                >
            </td>
        </tr>
        <?php
    }

    /**
     * @param array<string, mixed> $settings
     */
    private function urlField(string $key, string $label, array $settings): void
    {
        ?>
        <tr>
            <th scope="row"><?php echo esc_html($label); ?></th>
            <td>
                <input
                    class="regular-text code"
                    type="url"
                    name="<?php echo esc_attr("h4bs_settings[{$key}]"); ?>"
                    value="<?php echo esc_attr((string) ($settings[$key] ?? '')); ?>"
                >
            </td>
        </tr>
        <?php
    }

    /**
     * @param array<string, mixed> $settings
     */
    private function boolField(string $key, string $label, array $settings): void
    {
        ?>
        <tr>
            <th scope="row"><?php echo esc_html($label); ?></th>
            <td>
                <label>
                    <input
                        type="checkbox"
                        name="<?php echo esc_attr("h4bs_settings[{$key}]"); ?>"
                        value="1"
                        <?php checked(! empty($settings[$key])); ?>
                    >
                    <?php esc_html_e('Enabled', 'help4-builder-suite'); ?>
                </label>
            </td>
        </tr>
        <?php
    }

    /**
     * @param array<string, mixed> $settings
     */
    private function numberField(string $key, string $label, array $settings, int $min, int $max): void
    {
        ?>
        <tr>
            <th scope="row"><?php echo esc_html($label); ?></th>
            <td>
                <input
                    class="small-text"
                    type="number"
                    min="<?php echo esc_attr((string) $min); ?>"
                    max="<?php echo esc_attr((string) $max); ?>"
                    name="<?php echo esc_attr("h4bs_settings[{$key}]"); ?>"
                    value="<?php echo esc_attr((string) ($settings[$key] ?? '')); ?>"
                >
            </td>
        </tr>
        <?php
    }

    /**
     * @param array<string, mixed> $settings
     * @param array<string, string> $options
     */
    private function selectField(string $key, string $label, array $settings, array $options): void
    {
        $current = sanitize_key((string) ($settings[$key] ?? ''));
        ?>
        <tr>
            <th scope="row"><?php echo esc_html($label); ?></th>
            <td>
                <select name="<?php echo esc_attr("h4bs_settings[{$key}]"); ?>">
                    <?php foreach ($options as $value => $optionLabel) : ?>
                        <?php $value = sanitize_key((string) $value); ?>
                        <option value="<?php echo esc_attr($value); ?>" <?php selected($current, $value); ?>>
                            <?php echo esc_html($optionLabel); ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </td>
        </tr>
        <?php
    }

    /**
     * @param array<string, mixed> $defaults
     */
    private function wizardBoolField(string $key, string $label, array $defaults): void
    {
        ?>
        <tr>
            <th scope="row"><?php echo esc_html($label); ?></th>
            <td>
                <label>
                    <input
                        type="checkbox"
                        name="<?php echo esc_attr($key); ?>"
                        value="1"
                        <?php checked(! empty($defaults[$key])); ?>
                    >
                    <?php esc_html_e('Yes', 'help4-builder-suite'); ?>
                </label>
            </td>
        </tr>
        <?php
    }
}
