<?php
declare(strict_types=1);

namespace Help4BuilderSuite\Modules\Dependency;

use Help4BuilderSuite\Contracts\ModuleContract;
use Help4BuilderSuite\Support\AdminRequest;
use Help4BuilderSuite\Support\Settings;
use Automatic_Upgrader_Skin;
use Theme_Upgrader;

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

final class Module implements ModuleContract
{
    private const NOTICE_OPTION = 'h4bs_dependency_notice';
    private const THEME_NOTICE_SNOOZE_OPTION = 'h4bs_dependency_theme_notice_snooze_until';
    private const ACTION_INSTALL_THEME = 'h4bs_dependency_install_theme';
    private const ACTION_ACTIVATE_THEME = 'h4bs_dependency_activate_theme';
    private const ACTION_SNOOZE_THEME = 'h4bs_dependency_snooze_theme_notice';
    private const ACTION_INSTALL_CATALOG_THEME = 'h4bs_dependency_install_catalog_theme';
    private const ACTION_ACTIVATE_CATALOG_THEME = 'h4bs_dependency_activate_catalog_theme';
    private const CATALOG_PAGE_SLUG = 'h4bs-theme-catalog';
    private const DEFAULT_THEME_ZIP_URL = 'https://help4wordpress.com/help4-blank/help4-blank.zip';
    /**
     * @var array<int, string>
     */
    private const THEME_ZIP_FALLBACKS = [
        'https://help4wordpress.com/help4-blank/help4-blank.zip',
        'https://md.help4wordpress.com/help4-blank/help4-blank.zip',
        'https://plugins.help4wordpress.com/help4-blank/help4-blank.zip',
        'https://plugin.help4wordpress.com/help4-blank/help4-blank.zip',
    ];
    /**
     * @var array<int, string>
     */
    private const CATALOG_ENDPOINTS = [
        'https://plugins.help4wordpress.com/themes/catalog.json',
        'https://md.help4wordpress.com/themes/catalog.json',
        'https://plugin.help4wordpress.com/themes/catalog.json',
    ];
    private const THEME_PACKAGE_HOSTS = [
        'help4wordpress.com',
        'plugins.help4wordpress.com',
        'md.help4wordpress.com',
        'plugin.help4wordpress.com',
    ];

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

    public function boot(): void
    {
        $this->hookActionIfAvailable('admin_init', 'ensureThemeDependency');
        $this->hookActionIfAvailable('admin_menu', 'registerThemeCatalogPage');
        $this->hookActionIfAvailable('admin_notices', 'renderNotice');
        $this->hookActionIfAvailable('admin_notices', 'renderThemeRequirementNotice');
        $this->hookActionIfAvailable('admin_post_' . self::ACTION_INSTALL_THEME, 'handleInstallThemeAction');
        $this->hookActionIfAvailable('admin_post_' . self::ACTION_ACTIVATE_THEME, 'handleActivateThemeAction');
        $this->hookActionIfAvailable('admin_post_' . self::ACTION_SNOOZE_THEME, 'handleSnoozeThemeNoticeAction');
        $this->hookActionIfAvailable('admin_post_' . self::ACTION_INSTALL_CATALOG_THEME, 'handleInstallCatalogThemeAction');
        $this->hookActionIfAvailable('admin_post_' . self::ACTION_ACTIVATE_CATALOG_THEME, 'handleActivateCatalogThemeAction');
    }

    private function hookActionIfAvailable(string $hook, string $method, int $priority = 10, int $acceptedArgs = 0): void
    {
        if (! method_exists($this, $method)) {
            error_log(sprintf('[Help4 Builder Suite] Dependency module skipped missing callback "%s" for hook "%s".', $method, $hook)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            return;
        }

        add_action($hook, [$this, $method], $priority, $acceptedArgs);
    }

    /**
     * Defensive fallback for stale callback names on mixed-version installs.
     *
     * This prevents fatal activation failures when an older build references
     * a callback that was renamed/removed in a newer module file.
     *
     * @param string $name
     * @param array<int, mixed> $arguments
     * @return null
     */
    public function __call(string $name, array $arguments)
    {
        error_log(sprintf('[Help4 Builder Suite] Dependency module ignored unknown callback "%s".', $name)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
        return null;
    }

    public function ensureThemeDependency(): void
    {
        if (! current_user_can('switch_themes')) {
            return;
        }
        if ($this->isRequiredThemeActive()) {
            delete_option(self::THEME_NOTICE_SNOOZE_OPTION);
        }
    }

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

        $notice = get_option(self::NOTICE_OPTION, '');
        if (! is_string($notice) || $notice === '') {
            return;
        }

        delete_option(self::NOTICE_OPTION);
        printf('<div class="notice notice-info"><p>%s</p></div>', esc_html($notice));
    }

    public function renderThemeRequirementNotice(): void
    {
        if (! current_user_can('switch_themes')) {
            return;
        }
        if ($this->isRequiredThemeActive()) {
            return;
        }
        $requiredTheme = $this->requiredThemeSlug();
        if ($requiredTheme === '') {
            return;
        }

        $snoozeUntil = (int) get_option(self::THEME_NOTICE_SNOOZE_OPTION, 0);
        if ($snoozeUntil > time()) {
            return;
        }

        $theme = wp_get_theme($requiredTheme);
        $installed = $theme->exists();

        $installUrl = wp_nonce_url(
            admin_url('admin-post.php?action=' . self::ACTION_INSTALL_THEME),
            self::ACTION_INSTALL_THEME
        );
        $activateUrl = wp_nonce_url(
            admin_url('admin-post.php?action=' . self::ACTION_ACTIVATE_THEME),
            self::ACTION_ACTIVATE_THEME
        );
        $snoozeUrl = wp_nonce_url(
            admin_url('admin-post.php?action=' . self::ACTION_SNOOZE_THEME),
            self::ACTION_SNOOZE_THEME
        );

        ?>
        <div class="notice notice-warning">
            <p><strong><?php esc_html_e('Help4 Builder works best with Help4 Blank Theme.', 'help4-builder-suite'); ?></strong></p>
            <p><?php esc_html_e('Current active theme is not Help4 Blank. That can cause unwanted colors/layout (including the green styling you reported).', 'help4-builder-suite'); ?></p>
            <ol style="margin:0 0 10px 18px;">
                <li>
                    <?php
                    echo $installed
                        ? esc_html__('Step 1: Help4 Blank Theme is already installed.', 'help4-builder-suite')
                        : esc_html__('Step 1: Install Help4 Blank Theme from the Help4 update channel.', 'help4-builder-suite');
                    ?>
                </li>
                <li><?php esc_html_e('Step 2: Activate Help4 Blank Theme so the builder renders as designed.', 'help4-builder-suite'); ?></li>
            </ol>
            <p>
                <?php if ($installed) : ?>
                    <a class="button button-primary" href="<?php echo esc_url($activateUrl); ?>">
                        <?php esc_html_e('Activate Help4 Blank Theme (Recommended)', 'help4-builder-suite'); ?>
                    </a>
                <?php else : ?>
                    <a class="button button-primary" href="<?php echo esc_url($installUrl); ?>">
                        <?php esc_html_e('Install + Activate Help4 Blank Theme (Recommended)', 'help4-builder-suite'); ?>
                    </a>
                <?php endif; ?>
                <a class="button" href="<?php echo esc_url($snoozeUrl); ?>" style="margin-left:8px;">
                    <?php esc_html_e('Snooze for 24 Hours', 'help4-builder-suite'); ?>
                </a>
            </p>
        </div>
        <?php
    }

    public function handleInstallThemeAction(): void
    {
        if (! current_user_can('switch_themes')) {
            wp_die(esc_html__('Unauthorized request.', 'help4-builder-suite'));
        }
        check_admin_referer(self::ACTION_INSTALL_THEME);

        $requiredTheme = $this->requiredThemeSlug();
        if ($requiredTheme === '') {
            update_option(self::NOTICE_OPTION, 'Dependency manager could not determine the required theme slug.');
            $this->redirectBack();
        }

        $targetTheme = wp_get_theme($requiredTheme);
        if (! $targetTheme->exists()) {
            $zipUrl = $this->requiredThemeZipUrl();
            if ($zipUrl === '') {
                update_option(self::NOTICE_OPTION, 'Required Help4 theme ZIP URL is missing.');
                $this->redirectBack();
            }

            require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
            require_once ABSPATH . 'wp-admin/includes/file.php';
            require_once ABSPATH . 'wp-admin/includes/theme.php';

            $upgrader = new Theme_Upgrader(new Automatic_Upgrader_Skin());
            $result = $upgrader->install($zipUrl);
            if (is_wp_error($result)) {
                update_option(self::NOTICE_OPTION, 'Dependency manager could not install Help4 Blank Theme: ' . $result->get_error_message());
                $this->redirectBack();
            }
        }

        if (! wp_get_theme($requiredTheme)->exists()) {
            update_option(self::NOTICE_OPTION, 'Dependency manager could not locate Help4 Blank Theme after installation.');
            $this->redirectBack();
        }

        switch_theme($requiredTheme);
        delete_option(self::THEME_NOTICE_SNOOZE_OPTION);
        update_option(self::NOTICE_OPTION, 'Help4 Blank Theme is now installed and activated.');
        $this->redirectBack();
    }

    public function handleActivateThemeAction(): void
    {
        if (! current_user_can('switch_themes')) {
            wp_die(esc_html__('Unauthorized request.', 'help4-builder-suite'));
        }
        check_admin_referer(self::ACTION_ACTIVATE_THEME);

        $requiredTheme = $this->requiredThemeSlug();
        if ($requiredTheme === '') {
            update_option(self::NOTICE_OPTION, 'Dependency manager could not determine the required theme slug.');
            $this->redirectBack();
        }

        if (! wp_get_theme($requiredTheme)->exists()) {
            update_option(self::NOTICE_OPTION, 'Help4 Blank Theme is not installed yet. Use Install + Activate first.');
            $this->redirectBack();
        }

        switch_theme($requiredTheme);
        delete_option(self::THEME_NOTICE_SNOOZE_OPTION);
        update_option(self::NOTICE_OPTION, 'Help4 Blank Theme has been activated.');
        $this->redirectBack();
    }

    public function handleSnoozeThemeNoticeAction(): void
    {
        if (! current_user_can('switch_themes')) {
            wp_die(esc_html__('Unauthorized request.', 'help4-builder-suite'));
        }
        check_admin_referer(self::ACTION_SNOOZE_THEME);

        update_option(self::THEME_NOTICE_SNOOZE_OPTION, time() + DAY_IN_SECONDS);
        update_option(self::NOTICE_OPTION, 'Theme setup reminder snoozed for 24 hours.');
        $this->redirectBack();
    }

    public function registerThemeCatalogPage(): void
    {
        if (! current_user_can('switch_themes')) {
            return;
        }

        add_submenu_page(
            'themes.php',
            __('Help4 Theme Catalog', 'help4-builder-suite'),
            __('Help4 Theme Catalog', 'help4-builder-suite'),
            'switch_themes',
            self::CATALOG_PAGE_SLUG,
            [$this, 'renderThemeCatalogPage']
        );
    }

    public function renderThemeCatalogPage(): void
    {
        if (! current_user_can('switch_themes')) {
            wp_die(esc_html__('Unauthorized request.', 'help4-builder-suite'));
        }

        $themes = $this->fetchThemeCatalog();
        $industryOptions = ['all' => __('All industries', 'help4-builder-suite')];
        foreach ($themes as $theme) {
            $industry = sanitize_text_field((string) ($theme['industry'] ?? 'General'));
            if ($industry === '') {
                $industry = 'General';
            }
            $industryKey = sanitize_key(strtolower(str_replace(' ', '-', $industry)));
            if ($industryKey === '') {
                $industryKey = 'general';
            }
            if (! isset($industryOptions[$industryKey])) {
                $industryOptions[$industryKey] = $industry;
            }
        }
        ?>
        <div class="wrap">
            <h1><?php esc_html_e('Help4 Theme Catalog', 'help4-builder-suite'); ?></h1>
            <p><?php esc_html_e('Install and activate Help4-supported themes from this catalog.', 'help4-builder-suite'); ?></p>
            <?php if (! $themes) : ?>
                <div class="notice notice-warning"><p><?php esc_html_e('No catalog themes were found right now. Try again in a moment.', 'help4-builder-suite'); ?></p></div>
            <?php else : ?>
                <div style="display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-bottom:14px;background:#fff;border:1px solid #d5e1ec;border-radius:10px;padding:10px 12px;">
                    <label for="h4bs-theme-industry-filter" style="font-weight:600;"><?php esc_html_e('Industry', 'help4-builder-suite'); ?></label>
                    <select id="h4bs-theme-industry-filter">
                        <?php foreach ($industryOptions as $industryKey => $industryLabel) : ?>
                            <option value="<?php echo esc_attr($industryKey); ?>"><?php echo esc_html((string) $industryLabel); ?></option>
                        <?php endforeach; ?>
                    </select>
                    <input id="h4bs-theme-search" type="search" placeholder="<?php esc_attr_e('Search themes...', 'help4-builder-suite'); ?>" style="min-width:220px;">
                    <span style="margin-left:auto;color:#5f7389;font-size:12px;">
                        <?php
                        echo esc_html(
                            sprintf(
                                /* translators: %d is the number of catalog themes. */
                                __('%d themes in catalog', 'help4-builder-suite'),
                                count($themes)
                            )
                        );
                        ?>
                    </span>
                </div>
                <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:16px;">
                    <?php foreach ($themes as $theme) : ?>
                        <?php
                        $slug = sanitize_key((string) ($theme['slug'] ?? ''));
                        if ($slug === '') {
                            continue;
                        }
                        $themeObject = wp_get_theme($slug);
                        $installed = $themeObject->exists();
                        $active = $installed && $themeObject->get_stylesheet() === $slug;
                        $name = (string) ($theme['name'] ?? ucfirst(str_replace('-', ' ', $slug)));
                        $description = (string) ($theme['description'] ?? '');
                        $screenshot = esc_url((string) ($theme['screenshot'] ?? ''));
                        $zip = esc_url_raw((string) ($theme['zip'] ?? ''));
                        $version = (string) ($theme['version'] ?? '');
                        $industry = sanitize_text_field((string) ($theme['industry'] ?? 'General'));
                        if ($industry === '') {
                            $industry = 'General';
                        }
                        $industryKey = sanitize_key(strtolower(str_replace(' ', '-', $industry)));
                        if ($industryKey === '') {
                            $industryKey = 'general';
                        }
                        $preview = esc_url((string) ($theme['preview'] ?? ''));
                        $recommended = ! empty($theme['recommended']);
                        $packageUnavailable = ! empty($theme['coming_soon']) || $zip === '';
                        $searchBlob = strtolower(trim($name . ' ' . $slug . ' ' . $description . ' ' . $industry));

                        $installUrl = '';
                        if ($zip !== '') {
                            $installUrl = wp_nonce_url(
                                add_query_arg(
                                    [
                                        'action' => self::ACTION_INSTALL_CATALOG_THEME,
                                        'theme' => $slug,
                                        'zip'   => rawurlencode($zip),
                                    ],
                                    admin_url('admin-post.php')
                                ),
                                self::ACTION_INSTALL_CATALOG_THEME
                            );
                        }
                        $activateUrl = wp_nonce_url(
                            add_query_arg(
                                [
                                    'action' => self::ACTION_ACTIVATE_CATALOG_THEME,
                                    'theme' => $slug,
                                ],
                                admin_url('admin-post.php')
                            ),
                            self::ACTION_ACTIVATE_CATALOG_THEME
                        );
                        ?>
                        <div class="h4bs-theme-card" data-industry="<?php echo esc_attr($industryKey); ?>" data-search="<?php echo esc_attr($searchBlob); ?>" style="background:#fff;border:1px solid #d5e1ec;border-radius:10px;padding:14px;box-shadow:0 8px 18px rgba(13,34,56,.06);">
                            <?php if ($screenshot !== '') : ?>
                                <img src="<?php echo esc_url($screenshot); ?>" alt="<?php echo esc_attr($name); ?>" style="display:block;width:100%;height:auto;aspect-ratio:16/10;object-fit:cover;border-radius:8px;border:1px solid #d8e2ec;margin-bottom:10px;">
                            <?php endif; ?>
                            <h2 style="margin:0 0 8px;display:flex;align-items:center;gap:8px;flex-wrap:wrap;">
                                <span><?php echo esc_html($name); ?></span>
                                <?php if ($recommended) : ?>
                                    <span style="font-size:11px;background:#ecf7ef;color:#1e6b32;border:1px solid #b9e6c6;border-radius:999px;padding:2px 8px;"><?php esc_html_e('Recommended', 'help4-builder-suite'); ?></span>
                                <?php endif; ?>
                                <?php if ($packageUnavailable) : ?>
                                    <span style="font-size:11px;background:#fff7e6;color:#7c5700;border:1px solid #f2dbad;border-radius:999px;padding:2px 8px;"><?php esc_html_e('Package Pending', 'help4-builder-suite'); ?></span>
                                <?php endif; ?>
                            </h2>
                            <?php if ($description !== '') : ?>
                                <p style="margin:0 0 10px;color:#445e78;"><?php echo esc_html($description); ?></p>
                            <?php endif; ?>
                            <p style="margin:0 0 10px;color:#5f7389;font-size:12px;">
                                <strong><?php esc_html_e('Slug', 'help4-builder-suite'); ?>:</strong> <?php echo esc_html($slug); ?>
                                <span style="margin-left:8px;"><strong><?php esc_html_e('Industry', 'help4-builder-suite'); ?>:</strong> <?php echo esc_html($industry); ?></span>
                                <?php if ($version !== '') : ?>
                                    <span style="margin-left:8px;"><strong><?php esc_html_e('Version', 'help4-builder-suite'); ?>:</strong> <?php echo esc_html($version); ?></span>
                                <?php endif; ?>
                            </p>
                            <p style="margin:0;display:flex;flex-wrap:wrap;gap:8px;">
                                <?php if ($active) : ?>
                                    <span class="button button-primary" style="pointer-events:none;"><?php esc_html_e('Active', 'help4-builder-suite'); ?></span>
                                <?php elseif ($installed) : ?>
                                    <a class="button button-primary" href="<?php echo esc_url($activateUrl); ?>"><?php esc_html_e('Activate', 'help4-builder-suite'); ?></a>
                                <?php elseif ($packageUnavailable || $installUrl === '') : ?>
                                    <a class="button" href="<?php echo esc_url('https://help4wordpress.com/contact-us/'); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Request Theme Pack', 'help4-builder-suite'); ?></a>
                                <?php else : ?>
                                    <a class="button button-primary" href="<?php echo esc_url($installUrl); ?>"><?php esc_html_e('Install + Activate', 'help4-builder-suite'); ?></a>
                                <?php endif; ?>
                                <?php if ($preview !== '') : ?>
                                    <a class="button" target="_blank" rel="noopener noreferrer" href="<?php echo esc_url($preview); ?>"><?php esc_html_e('Preview', 'help4-builder-suite'); ?></a>
                                <?php endif; ?>
                            </p>
                        </div>
                    <?php endforeach; ?>
                </div>
                <script>
                    (function () {
                        var industry = document.getElementById('h4bs-theme-industry-filter');
                        var search = document.getElementById('h4bs-theme-search');
                        var cards = Array.prototype.slice.call(document.querySelectorAll('.h4bs-theme-card'));
                        if (!industry || !search || cards.length === 0) {
                            return;
                        }
                        var applyFilter = function () {
                            var industryValue = String(industry.value || 'all').toLowerCase();
                            var query = String(search.value || '').trim().toLowerCase();
                            cards.forEach(function (card) {
                                var cardIndustry = String(card.getAttribute('data-industry') || '').toLowerCase();
                                var cardSearch = String(card.getAttribute('data-search') || '').toLowerCase();
                                var industryMatch = industryValue === 'all' || industryValue === cardIndustry;
                                var queryMatch = query === '' || cardSearch.indexOf(query) !== -1;
                                card.style.display = industryMatch && queryMatch ? '' : 'none';
                            });
                        };
                        industry.addEventListener('change', applyFilter);
                        search.addEventListener('input', applyFilter);
                    })();
                </script>
            <?php endif; ?>
        </div>
        <?php
    }

    public function handleInstallCatalogThemeAction(): void
    {
        if (! current_user_can('switch_themes')) {
            wp_die(esc_html__('Unauthorized request.', 'help4-builder-suite'));
        }
        check_admin_referer(self::ACTION_INSTALL_CATALOG_THEME);

        $themeSlug = AdminRequest::queryKey('theme');
        $zipRaw = AdminRequest::queryText('zip');
        $zipUrl = esc_url_raw(rawurldecode($zipRaw));

        if ($themeSlug === '') {
            update_option(self::NOTICE_OPTION, 'Theme catalog install failed: missing theme slug.');
            $this->redirectCatalogPage();
        }
        if ($zipUrl === '') {
            update_option(self::NOTICE_OPTION, 'Theme catalog install failed: missing ZIP URL.');
            $this->redirectCatalogPage();
        }
        if (! $this->isAllowedThemeZipUrl($zipUrl)) {
            update_option(self::NOTICE_OPTION, 'Theme catalog install failed: ZIP URL is not on the Help4 theme package allowlist.');
            $this->redirectCatalogPage();
        }

        require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
        require_once ABSPATH . 'wp-admin/includes/file.php';
        require_once ABSPATH . 'wp-admin/includes/theme.php';

        $upgrader = new Theme_Upgrader(new Automatic_Upgrader_Skin());
        $result = $upgrader->install($zipUrl);
        if (is_wp_error($result)) {
            update_option(
                self::NOTICE_OPTION,
                'Theme catalog install failed: ' . $result->get_error_message()
            );
            $this->redirectCatalogPage();
        }

        if (! wp_get_theme($themeSlug)->exists()) {
            update_option(self::NOTICE_OPTION, 'Theme catalog install failed: installed theme could not be found.');
            $this->redirectCatalogPage();
        }

        switch_theme($themeSlug);
        delete_option(self::THEME_NOTICE_SNOOZE_OPTION);
        update_option(self::NOTICE_OPTION, 'Theme installed and activated: ' . $themeSlug);
        $this->redirectCatalogPage();
    }

    public function handleActivateCatalogThemeAction(): void
    {
        if (! current_user_can('switch_themes')) {
            wp_die(esc_html__('Unauthorized request.', 'help4-builder-suite'));
        }
        check_admin_referer(self::ACTION_ACTIVATE_CATALOG_THEME);

        $themeSlug = AdminRequest::queryKey('theme');
        if ($themeSlug === '') {
            update_option(self::NOTICE_OPTION, 'Theme activation failed: missing theme slug.');
            $this->redirectCatalogPage();
        }

        if (! wp_get_theme($themeSlug)->exists()) {
            update_option(self::NOTICE_OPTION, 'Theme activation failed: theme is not installed.');
            $this->redirectCatalogPage();
        }

        switch_theme($themeSlug);
        delete_option(self::THEME_NOTICE_SNOOZE_OPTION);
        update_option(self::NOTICE_OPTION, 'Theme activated: ' . $themeSlug);
        $this->redirectCatalogPage();
    }

    private function requiredThemeSlug(): string
    {
        $settings = Settings::all();
        return sanitize_key((string) ($settings['required_theme_slug'] ?? 'help4-blank'));
    }

    private function requiredThemeZipUrl(): string
    {
        $settings = Settings::all();
        $configured = esc_url_raw((string) ($settings['required_theme_zip_url'] ?? ''));
        $candidates = [];
        if ($configured !== '') {
            $candidates[] = $configured;
        }
        foreach (self::THEME_ZIP_FALLBACKS as $candidate) {
            $candidates[] = esc_url_raw($candidate);
        }

        foreach (array_values(array_unique($candidates)) as $candidate) {
            $url = esc_url_raw((string) $candidate);
            if ($url !== '' && $this->isAllowedThemeZipUrl($url)) {
                return $url;
            }
        }

        return esc_url_raw(self::DEFAULT_THEME_ZIP_URL);
    }

    private function isRequiredThemeActive(): bool
    {
        $requiredTheme = $this->requiredThemeSlug();
        if ($requiredTheme === '') {
            return true;
        }
        $currentTheme = wp_get_theme();
        return $currentTheme->get_stylesheet() === $requiredTheme;
    }

    /**
     * @return array<int, array{
     *     slug: string,
     *     name: string,
     *     description: string,
     *     zip: string,
     *     screenshot: string,
     *     version: string,
     *     industry: string,
     *     preview: string,
     *     recommended: bool,
     *     coming_soon: bool
     * }>
     */
    private function fetchThemeCatalog(): array
    {
        $catalog = [];
        $endpoints = apply_filters('h4bs_theme_catalog_endpoints', self::CATALOG_ENDPOINTS);
        if (! is_array($endpoints)) {
            $endpoints = self::CATALOG_ENDPOINTS;
        }
        foreach ($endpoints as $endpointCandidate) {
            $endpoint = esc_url_raw((string) $endpointCandidate);
            if ($endpoint === '' || ! wp_http_validate_url($endpoint)) {
                continue;
            }
            $response = wp_remote_get($endpoint, ['timeout' => 12]);
            if (is_wp_error($response)) {
                continue;
            }
            $status = (int) wp_remote_retrieve_response_code($response);
            if ($status < 200 || $status >= 300) {
                continue;
            }
            $body = (string) wp_remote_retrieve_body($response);
            if ($body === '') {
                continue;
            }
            $decoded = json_decode($body, true);
            if (! is_array($decoded)) {
                continue;
            }
            $items = [];
            if (isset($decoded['themes']) && is_array($decoded['themes'])) {
                $items = $decoded['themes'];
            } elseif (array_is_list($decoded)) {
                $items = $decoded;
            }

            foreach ($items as $rawTheme) {
                if (! is_array($rawTheme)) {
                    continue;
                }
                $slug = sanitize_key((string) ($rawTheme['slug'] ?? ''));
                if ($slug === '') {
                    continue;
                }
                $zip = esc_url_raw((string) ($rawTheme['zip'] ?? ($rawTheme['zip_url'] ?? '')));
                $industry = sanitize_text_field((string) ($rawTheme['industry'] ?? ($rawTheme['category'] ?? 'General')));
                if ($industry === '') {
                    $industry = 'General';
                }
                $preview = esc_url_raw((string) ($rawTheme['preview'] ?? ($rawTheme['preview_url'] ?? '')));
                $recommended = ! empty($rawTheme['recommended']);
                $version = sanitize_text_field((string) ($rawTheme['version'] ?? ''));
                $comingSoon = ! empty($rawTheme['coming_soon']);
                if ($zip === '' || ! $this->isAllowedThemeZipUrl($zip)) {
                    $comingSoon = true;
                    $zip = '';
                }
                if (strtolower($version) === 'coming-soon') {
                    $comingSoon = true;
                }
                $catalog[$slug] = [
                    'slug'        => $slug,
                    'name'        => sanitize_text_field((string) ($rawTheme['name'] ?? ucfirst(str_replace('-', ' ', $slug)))),
                    'description' => sanitize_text_field((string) ($rawTheme['description'] ?? '')),
                    'zip'         => $zip,
                    'screenshot'  => esc_url_raw((string) ($rawTheme['screenshot'] ?? '')),
                    'version'     => $version,
                    'industry'    => $industry,
                    'preview'     => $preview,
                    'recommended' => $recommended,
                    'coming_soon' => $comingSoon,
                ];
            }
            if ($catalog) {
                break;
            }
        }

        $requiredSlug = $this->requiredThemeSlug();
        $requiredZip = $this->requiredThemeZipUrl();
        if ($requiredSlug !== '' && $requiredZip !== '' && ! isset($catalog[$requiredSlug])) {
            $catalog[$requiredSlug] = [
                'slug'        => $requiredSlug,
                'name'        => 'Help4 Blank Theme',
                'description' => 'Minimal Help4 base theme for best builder parity and performance.',
                'zip'         => $requiredZip,
                'screenshot'  => '',
                'version'     => '',
                'industry'    => 'General',
                'preview'     => '',
                'recommended' => true,
                'coming_soon' => false,
            ];
        }

        return array_values($catalog);
    }

    private function redirectCatalogPage(): void
    {
        wp_safe_redirect($this->catalogPageUrl());
        exit;
    }

    private function catalogPageUrl(): string
    {
        return admin_url('themes.php?page=' . self::CATALOG_PAGE_SLUG);
    }

    private function isAllowedThemeZipUrl(string $url): bool
    {
        $candidate = esc_url_raw($url);
        if ($candidate === '' || ! wp_http_validate_url($candidate)) {
            return false;
        }

        $scheme = strtolower((string) wp_parse_url($candidate, PHP_URL_SCHEME));
        $host = strtolower((string) wp_parse_url($candidate, PHP_URL_HOST));
        $path = (string) wp_parse_url($candidate, PHP_URL_PATH);

        return $scheme === 'https'
            && in_array($host, self::THEME_PACKAGE_HOSTS, true)
            && (bool) preg_match(
                '#^/(?:help4-beta/)?help4-blank/(?:help4-blank(?:-\d+\.\d+\.\d+)?|latest)\.zip$#i',
                $path
            );
    }

    private function redirectBack(): void
    {
        $fallback = admin_url('admin.php?page=h4bs-settings');
        $referer = wp_get_referer();
        if (! is_string($referer) || $referer === '') {
            $referer = $fallback;
        }
        wp_safe_redirect($referer);
        exit;
    }
}
