<?php
/**
 * Query string optimizer.
 *
 * Removes version query strings (?ver=) from CSS and JS URLs
 * so CDNs and proxies can cache them properly.
 *
 * @package MonitorCat\Modules\Speed\Optimizer
 */

declare(strict_types=1);

namespace MonitorCat\Modules\Speed\Optimizer;

defined( 'ABSPATH' ) || exit;

use MonitorCat\Settings;

/**
 * Removes version query strings from static resource URLs.
 */
final class QueryStringOptimizer {

	/**
	 * Plugin settings.
	 *
	 * @var Settings
	 */
	private Settings $settings;

	/**
	 * Constructor.
	 *
	 * @param Settings $settings Plugin settings.
	 */
	public function __construct( Settings $settings ) {
		$this->settings = $settings;
	}

	/**
	 * Register hooks if the optimization is enabled.
	 */
	public function boot(): void {
		if ( ! $this->settings->get( 'speed.optimize_query_strings', true ) ) {
			return;
		}

		if ( is_admin() ) {
			return;
		}

		add_filter( 'style_loader_src', array( $this, 'remove_version_query' ), 999 );
		add_filter( 'script_loader_src', array( $this, 'remove_version_query' ), 999 );
	}

	/**
	 * Remove the version query string from a resource URL.
	 *
	 * Preserves URLs that don't have a 'ver' parameter (e.g. Google Fonts).
	 *
	 * @param string $src The resource URL.
	 * @return string The URL without the ver query string.
	 */
	public function remove_version_query( string $src ): string {
		if ( empty( $src ) ) {
			return $src;
		}

		$parsed = wp_parse_url( $src );

		if ( ! isset( $parsed['query'] ) ) {
			return $src;
		}

		parse_str( $parsed['query'], $params );

		// Only remove if the only param is 'ver', or remove 'ver' from multiple params.
		if ( isset( $params['ver'] ) ) {
			unset( $params['ver'] );

			if ( empty( $params ) ) {
				// Remove the query string entirely.
				return remove_query_arg( 'ver', $src );
			}
		}

		return $src;
	}
}
