<?php
/**
 * SiteTools
 *
 * @package CommonFrameworkPlugin
 */

namespace CommonFrameworkPlugin;

use FacetWP;

/**
 * SiteTools class
 * Handles various administrative actions such as cache clearing and database cleanup.
 */
class SiteTools extends \CommonFrameworkPlugin\Module {

	/**
	 * Determines if the module can register.
	 *
	 * @return bool True if the module can register.
	 */
	public function can_register() {
		return true;
	}

	/**
	 * Registers hooks for various administrative actions.
	 *
	 * @return void
	 */
	public function register() {
		add_action( 'admin_post_clean_cache_wp_rocket', [ $this, 'clean_cache_wp_rocket' ] );
		add_action( 'admin_post_preload_caches_wp_rocket', [ $this, 'preload_caches_wp_rocket' ] );
		add_action( 'admin_post_broadcast_product_facets', [ $this, 'broadcast_product_facets' ] );
		add_action( 'admin_post_flush_elementor_styles', [ $this, 'flush_elementor_styles' ] );
	}

	/**
	 * Cleans the cache using WP Rocket.
	 *
	 * @return void
	 */
	public function clean_cache_wp_rocket() {
		$this->run_in_site_context(
			function () {
				if ( function_exists( 'rocket_clean_domain' ) ) {
					rocket_clean_domain();
				}
			}
		);

		$this->redirect_to_tools_page( 'clean_cache_wp_rocket' );
	}

	/**
	 * Preloads the caches using WP Rocket.
	 *
	 * @return void
	 */
	public function preload_caches_wp_rocket() {
		$this->run_in_site_context(
			function () {
				if ( function_exists( 'run_rocket_sitemap_preload' ) ) {
					run_rocket_sitemap_preload();
				}
			}
		);

		$this->redirect_to_tools_page( 'preload_caches_wp_rocket' );
	}

	/**
	 * Broadcasts product facets by saving them into a file.
	 *
	 * @return void
	 */
	public function broadcast_product_facets() {
		if ( ! file_exists( COMMON_FRAMEWORK_PLUGIN_PATH . 'templates' ) ) {
			mkdir( COMMON_FRAMEWORK_PLUGIN_PATH . 'templates' );
		}
		if ( ! file_exists( COMMON_FRAMEWORK_PLUGIN_PATH . 'templates/facets' ) ) {
			mkdir( COMMON_FRAMEWORK_PLUGIN_PATH . 'templates/facets' );
		}

		$fwp = \FacetWP::instance();
		$facets = $fwp->helper->settings['facets'];
		foreach ( $facets as $facet ) {
			$pattern = '/pf_/i';
			if ( preg_match( $pattern, $facet['name'] ) ) {
				$json = json_encode( $facet );
				$file = fopen( COMMON_FRAMEWORK_PLUGIN_PATH . 'templates/facets/' . $facet['name'] . '.json', 'w' );
				fwrite( $file, $json );
				fclose( $file );
			}
		}

		$this->redirect_to_tools_page( 'broadcast_product_facets' );
	}

	/**
	 * Flushes Elementor styles by clearing its cache.
	 *
	 * @return void
	 */
	public function flush_elementor_styles() {
		if ( did_action( 'elementor/loaded' ) ) {
			$this->run_in_site_context(
				function () {
					\Elementor\Plugin::instance()->files_manager->clear_cache();
				}
			);
		}

		$this->redirect_to_tools_page( 'flush_elementor_styles' );
	}

	/**
	 * Redirects to the tools page after performing an action.
	 *
	 * @param string $action The action performed.
	 * @return void
	 */
	public function redirect_to_tools_page( $action ) {
		if ( empty( $_POST['action'] ) || $_POST['action'] !== $action ) {
			wp_redirect( get_home_url() );
			exit();
		}

		$redirect_url = get_site_url() . '/wp-admin/admin.php?page=cf_tools';
		wp_safe_redirect( $redirect_url );
		exit();
	}

	/**
	 * Executes a callback function within the context of each site in a multisite setup.
	 *
	 * @param callable $callback The callback function to run.
	 * @param mixed    ...$args  Additional arguments to pass to the callback.
	 * @return void
	 */
	private function run_in_site_context( callable $callback, ...$args ) {
		// TODO: Perhaps extend this to run tools on external connections via REST?
		if ( is_multisite() ) {
			$sites = get_sites();
			foreach ( $sites as $site ) {
				switch_to_blog( $site->blog_id );
				$callback( ...$args );
				restore_current_blog();
			}
		} else {
			$callback();
		}
	}
}
