<?php
/**
 * Performance Module
 *
 * Applies optional front-end optimizations based on Theme Options.
 *
 * @package Kutby
 * @since   1.0.0
 */

declare(strict_types=1);

namespace Kutby\Performance;

use Kutby\Contracts\ModuleInterface;
use Kutby\ThemeOptions\Manager;

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

/**
 * Class Performance
 */
final class Performance implements ModuleInterface {

	/**
	 * Register hooks.
	 *
	 * @return void
	 */
	public function register(): void {
		add_action( 'init', array( $this, 'apply' ), 5 );
	}

	/**
	 * {@inheritdoc}
	 */
	public function boot(): void {}

	/**
	 * Apply performance switches.
	 *
	 * @return void
	 */
	public function apply(): void {
		$opts = Manager::get_group( 'performance' );

		if ( ! empty( $opts['disable_emojis'] ) ) {
			$this->disable_emojis();
		}

		if ( ! empty( $opts['disable_embeds'] ) ) {
			$this->disable_embeds();
		}

		if ( ! empty( $opts['disable_xmlrpc'] ) ) {
			add_filter( 'xmlrpc_enabled', '__return_false' );
		}

		if ( ! empty( $opts['disable_dashicons'] ) ) {
			add_action( 'wp_enqueue_scripts', array( $this, 'dequeue_dashicons' ), 100 );
		}

		if ( ! empty( $opts['disable_gutenberg_css'] ) ) {
			add_action( 'wp_enqueue_scripts', array( $this, 'dequeue_block_css' ), 100 );
		}

		if ( ! empty( $opts['remove_query_strings'] ) ) {
			add_filter( 'script_loader_src', array( $this, 'remove_version_query' ), 15 );
			add_filter( 'style_loader_src', array( $this, 'remove_version_query' ), 15 );
		}

		if ( ! empty( $opts['lazy_load'] ) ) {
			add_filter( 'wp_lazy_loading_enabled', '__return_true' );
		}

		if ( ! empty( $opts['preload_fonts'] ) ) {
			add_action( 'wp_head', array( $this, 'preload_fonts' ), 2 );
		}
	}

	/**
	 * Disable emoji scripts and styles.
	 *
	 * @return void
	 */
	private function disable_emojis(): void {
		remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
		remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
		remove_action( 'wp_print_styles', 'print_emoji_styles' );
		remove_action( 'admin_print_styles', 'print_emoji_styles' );
		remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
		remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
		remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
		add_filter( 'emoji_svg_url', '__return_false' );
	}

	/**
	 * Disable oEmbed discovery and scripts.
	 *
	 * @return void
	 */
	private function disable_embeds(): void {
		remove_action( 'wp_head', 'wp_oembed_add_discovery_links' );
		remove_action( 'wp_head', 'wp_oembed_add_host_js' );
		add_action(
			'wp_footer',
			static function (): void {
				wp_deregister_script( 'wp-embed' );
			}
		);
	}

	/**
	 * Dequeue Dashicons for non-logged-in users.
	 *
	 * @return void
	 */
	public function dequeue_dashicons(): void {
		if ( ! is_user_logged_in() ) {
			wp_dequeue_style( 'dashicons' );
		}
	}

	/**
	 * Dequeue core block library CSS on frontend.
	 *
	 * @return void
	 */
	public function dequeue_block_css(): void {
		wp_dequeue_style( 'wp-block-library' );
		wp_dequeue_style( 'wp-block-library-theme' );
		wp_dequeue_style( 'global-styles' );
		wp_dequeue_style( 'classic-theme-styles' );
	}

	/**
	 * Strip ?ver= from asset URLs.
	 *
	 * @param string $src Asset URL.
	 * @return string
	 */
	public function remove_version_query( string $src ): string {
		if ( strpos( $src, 'ver=' ) ) {
			$src = remove_query_arg( 'ver', $src );
		}

		return $src;
	}

	/**
	 * Preload local font files that match the active asset pipeline.
	 *
	 * @return void
	 */
	public function preload_fonts(): void {
		/**
		 * Filter list of font source keys (under assets/fonts/…).
		 *
		 * @since 1.0.0
		 *
		 * @param array<int, string> $fonts Font relative paths.
		 */
		$fonts = apply_filters(
			'kutby_preload_fonts',
			array(
				'fonts/tajawal/tajawal-arabic-400.woff2',
				'fonts/tajawal/tajawal-arabic-700.woff2',
			)
		);

		foreach ( $fonts as $font ) {
			$url = \Kutby\Assets\AssetManifestManager::font_url( (string) $font );
			if ( null === $url || '' === $url ) {
				continue;
			}

			$type = str_ends_with( (string) $font, '.woff2' ) ? 'font/woff2' : 'font/woff';

			printf(
				'<link rel="preload" href="%s" as="font" type="%s" crossorigin>' . "\n",
				esc_url( $url ),
				esc_attr( $type )
			);
		}
	}
}
