<?php

namespace WPSN\Core;

defined('ABSPATH') || exit;

/**
 * AJAX Mode
 *
 * Many WP SEO Next tools support an optional "live" mode that uses admin-ajax.php.
 * On some shared hosts this can cause HTTP 503 / rate limiting.
 *
 * This helper centralizes the global switch to disable all WP SEO Next AJAX calls
 * and to prevent loading AJAX-heavy admin scripts.
 */
final class AjaxMode
{
    /**
     * Settings key path.
     */
    public const SETTINGS_PATH = 'performance.admin.ajax_enabled';

    /**
     * When enabled, WP SEO Next avoids fully booting on unrelated admin-ajax.php
     * requests (e.g. core heartbeat), which can reduce 503 “server busy” errors
     * on shared hosting.
     */
    public const LITE_BOOT_SETTINGS_PATH = 'performance.admin.ajax_lite_boot';

    /**
     * Constant override (wp-config.php): define('WPSN_DISABLE_AJAX', true);
     */
    public const CONST_DISABLE = 'WPSN_DISABLE_AJAX';

    /**
     * Constant override (wp-config.php): define('WPSN_DISABLE_AJAX_LITE_BOOT', true);
     */
    public const CONST_DISABLE_LITE_BOOT = 'WPSN_DISABLE_AJAX_LITE_BOOT';

    /**
     * @return bool
     */
    public static function isEnabled(?Settings $settings = null): bool
    {
        $enabled = false;

        if ($settings) {
            $enabled = (bool) $settings->get(self::SETTINGS_PATH, false);
        } else {
            // Best-effort fallback: read raw option when Settings container is not available.
            $raw = get_option(\WPSN\Admin\SettingsRepository::OPTION_NAME);
            if (is_array($raw)) {
                $enabled = !empty($raw['performance']['admin']['ajax_enabled']);
            }
        }

        // Runtime override.
        if (defined(self::CONST_DISABLE) && (bool) constant(self::CONST_DISABLE)) {
            $enabled = false;
        }

        /**
         * Filter: allow integrations to force-enable/disable.
         *
         * @param bool $enabled
         */
        $enabled = (bool) apply_filters('wpsn/ajax/enabled', $enabled);

        return $enabled;
    }

    /**
     * @return bool
     */
    public static function isLiteBootEnabled(?Settings $settings = null): bool
    {
        $enabled = true;

        if ($settings) {
            $enabled = (bool) $settings->get(self::LITE_BOOT_SETTINGS_PATH, true);
        } else {
            // Best-effort fallback: read raw option when Settings container is not available.
            $raw = get_option(\WPSN\Admin\SettingsRepository::OPTION_NAME);
            if (is_array($raw)
                && isset($raw['performance'])
                && is_array($raw['performance'])
                && isset($raw['performance']['admin'])
                && is_array($raw['performance']['admin'])
                && array_key_exists('ajax_lite_boot', $raw['performance']['admin'])) {
                $enabled = !empty($raw['performance']['admin']['ajax_lite_boot']);
            }
        }

        // Runtime override.
        if (defined(self::CONST_DISABLE_LITE_BOOT) && (bool) constant(self::CONST_DISABLE_LITE_BOOT)) {
            $enabled = false;
        }

        /**
         * Filter: allow integrations to force-enable/disable.
         *
         * @param bool $enabled
         */
        $enabled = (bool) apply_filters('wpsn/ajax/lite_boot', $enabled);

        return $enabled;
    }

    /**
     * Script handles that use admin-ajax.php (live mode).
     *
     * If AJAX is disabled globally, we avoid loading these scripts entirely.
     *
     * @return string[]
     */
    public static function ajaxScriptHandles(): array
    {
        return [
            // Tools / pages
            'wpsn-audit',
            'wpsn-bulk-admin',
            'wpsn-bulk-table-import',
            'wpsn-drift-monitor',
            // NOTE: wpsn-gsc-admin also contains non-AJAX helpers (checkbox selection, queue form wiring).
            // We keep it loaded even when AJAX is globally disabled; the live/AJAX UI is hidden anyway.
            'wpsn-media-admin',
            'wpsn-network-profiles',
            'wpsn-404-suggest',
            'wpsn-schema-validator-admin',
            'wpsn-serp-gap-admin',
            // NOTE: wpsn-template-tokens-admin is required for non-AJAX Template tester UX (context switching).
            // The live/AJAX submit is optional and guarded in JS.
        ];
    }

    /**
     * @return bool
     */
    public static function isWpsnAjaxAction(string $action): bool
    {
        return strpos($action, 'wpsn_') === 0;
    }
}
