<?php
/**
 * Cache module — Heartbeat control
 *
 * Three independent toggles (frontend / admin dashboard / post editor) so
 * the user can keep autosave working while killing pointless heartbeats on
 * the public site.
 *
 * Modes:
 *   - 'enabled'  : default WP behaviour (15s admin, 60s frontend)
 *   - 'throttle' : force 60s
 *   - 'disabled' : deregister the script entirely (no admin-ajax.php hits)
 *
 * @package BlaminhorEssentials
 */

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

class Blaminhor_Essentials_Cache_Heartbeat {

	/** @var Blaminhor_Essentials_Module_Cache */
	private $parent;

	public function __construct( Blaminhor_Essentials_Module_Cache $parent ) {
		$this->parent = $parent;
	}

	public function register_hooks() {
		// Frontend: deregister early so no JS reaches the page.
		add_action( 'wp_enqueue_scripts', array( $this, 'maybe_deregister_frontend' ), 99 );
		// Admin: filter the settings shipped to wp.heartbeat (interval).
		add_filter( 'heartbeat_settings', array( $this, 'filter_settings' ), 10, 1 );
		// Editor / list-table: deregister entirely if the user opted out.
		add_action( 'admin_enqueue_scripts', array( $this, 'maybe_deregister_admin' ), 99 );
	}

	public function maybe_deregister_frontend() {
		if ( is_admin() ) {
			return;
		}
		$mode = $this->parent->get_setting( 'heartbeat_frontend', 'disabled' );
		if ( 'disabled' === $mode ) {
			wp_deregister_script( 'heartbeat' );
		}
	}

	public function maybe_deregister_admin( $hook ) {
		// Only act on disabled mode; throttle is implemented in filter_settings().
		// We must NOT deregister on the post editor unless the user explicitly
		// disabled it — autosave depends on it.
		$is_editor   = in_array( $hook, array( 'post.php', 'post-new.php' ), true );
		$mode_admin  = $this->parent->get_setting( 'heartbeat_admin', 'throttle' );
		$mode_editor = $this->parent->get_setting( 'heartbeat_edit', 'enabled' );

		$mode = $is_editor ? $mode_editor : $mode_admin;
		if ( 'disabled' === $mode ) {
			wp_deregister_script( 'heartbeat' );
		}
	}

	/**
	 * Throttle to 60s when the user picked 'throttle'. Default WP intervals
	 * are 15s in the editor and 60s elsewhere; pushing them to 60s on
	 * "admin" matches WP Rocket's tested setting.
	 *
	 * @param array $settings Heartbeat settings array.
	 * @return array
	 */
	public function filter_settings( $settings ) {
		if ( ! is_array( $settings ) ) {
			return $settings;
		}

		// We can't tell here whether we're in the editor (no $hook). The
		// safest behaviour is: throttle if either applicable mode is
		// 'throttle'. The user can set both explicitly.
		$mode_admin  = $this->parent->get_setting( 'heartbeat_admin', 'throttle' );
		$mode_editor = $this->parent->get_setting( 'heartbeat_edit', 'enabled' );

		if ( 'throttle' === $mode_admin || 'throttle' === $mode_editor ) {
			$settings['interval']        = 60;
			$settings['minimalInterval'] = 60;
		}

		return $settings;
	}
}
