<?php

/**
 * Heartbeat Control Module
 *
 * Controls WordPress heartbeat API frequency across admin, editor, and frontend
 * to reduce server load and improve admin performance.
 *
 * @package ProRank\SEO\Modules\Performance
 * @since   2.1.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Modules\Performance;

use ProRank\SEO\Modules\BaseModule;

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


/**
 * HeartbeatControlModule class
 *
 * Hooks into WordPress heartbeat API to throttle or disable the interval
 * based on user-configured settings. Reads from prorank_database_settings
 * via the unified BaseModule::get_setting() path.
 *
 * Settings used:
 *   heartbeat_control   (bool)  – master toggle
 *   heartbeat_frequency  (int)  – interval in seconds (15, 30, 60, 120, 300; 0 = disable)
 */


class HeartbeatControlModule extends BaseModule {

    /**
     * Required tier for this module
     */
    protected string $feature_tier = 'free';

    /**
     * Constructor
     */
    public function __construct() {
        $this->slug        = 'heartbeat_control';
        $this->name        = 'Heartbeat Control';
        $this->description = 'Control WordPress heartbeat API frequency to reduce server load';
        $this->parent_slug = 'performance';
    }

    /**
     * Initialize module hooks
     *
     * @return void
     */
    public function init_hooks(): void {
        if ( ! $this->is_heartbeat_control_enabled() ) {
            return;
        }

        $frequency = (int) $this->get_setting( 'heartbeat_frequency', 60 );

        // Frequency 0 means disable heartbeat entirely
        if ( $frequency === 0 ) {
            add_action( 'init', [ $this, 'deregister_heartbeat' ], 1 );
            return;
        }

        // Throttle the heartbeat interval
        add_filter( 'heartbeat_settings', function ( array $settings ) use ( $frequency ): array {
            $settings['interval'] = max( 15, min( $frequency, 600 ) ); // Clamp 15-600s
            return $settings;
        } );
    }

    /**
     * Deregister the heartbeat script entirely
     *
     * Runs on 'init' so wp_scripts is available.
     * We keep heartbeat alive on post editor screens to avoid autosave breakage.
     *
     * @return void
     */
    public function deregister_heartbeat(): void {
        global $pagenow;

        // Never disable heartbeat on the post editor – autosave + lock rely on it
        $editor_pages = [ 'post.php', 'post-new.php' ];
        if ( is_admin() && in_array( $pagenow, $editor_pages, true ) ) {
            return;
        }

        wp_deregister_script( 'heartbeat' );
    }

    /**
     * Check if heartbeat control is enabled
     *
     * @return bool
     */
    private function is_heartbeat_control_enabled(): bool {
        $value = $this->get_setting( 'heartbeat_control', false );

        if ( is_string( $value ) ) {
            return in_array( strtolower( $value ), [ 'true', '1', 'yes', 'on' ], true );
        }

        return (bool) $value;
    }
}
