<?php
/**
 * BaseCloud Boost — Multisite Compatibility
 *
 * @package BaseCloud\Boost\Compatibility
 */

declare( strict_types=1 );

namespace BaseCloud\Boost\Compatibility;

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

use BaseCloud\Boost\Core\Cache_Purge;

/**
 * Handles WordPress Multisite support.
 */
class Multisite_Compat {

	/**
	 * Boot multisite compatibility.
	 *
	 * @return void
	 */
	public function boot(): void {
		if ( ! is_multisite() ) {
			return;
		}

		add_action( 'switch_blog', [ $this, 'on_blog_switch' ], 10, 2 );
		add_action( 'delete_blog', [ $this, 'on_delete_blog' ] );
		add_action( 'wp_uninitialize_site', [ $this, 'on_delete_blog_modern' ] );
	}

	/**
	 * Handle blog switching.
	 *
	 * @param int $new_blog_id New blog ID.
	 * @param int $old_blog_id Previous blog ID.
	 * @return void
	 */
	public function on_blog_switch( int $new_blog_id, int $old_blog_id ): void {
		// No action needed — cache paths are URL-based and handle multi-domains correctly.
	}

	/**
	 * Purge cache when a blog is deleted (legacy action).
	 *
	 * @param int $blog_id Blog ID.
	 * @return void
	 */
	public function on_delete_blog( int $blog_id ): void {
		$site = get_site( $blog_id );
		if ( $site instanceof \WP_Site ) {
			$this->purge_site_cache( (string) $site->domain, (string) $site->path );
		}
	}

	/**
	 * Purge cache when a blog is deleted (WP 5.1+ action).
	 *
	 * @param \WP_Site $old_site Deleted site object.
	 * @return void
	 */
	public function on_delete_blog_modern( \WP_Site $old_site ): void {
		$this->purge_site_cache( (string) $old_site->domain, (string) $old_site->path );
	}

	/**
	 * Delete every cached page for a network site.
	 *
	 * The page cache is stored by URL — BCBOOST_CACHE_DIR/{scheme}/{host}{path}/… —
	 * not by blog ID, so a deleted site's pages are removed by matching its domain
	 * and path under both scheme folders.
	 *
	 * @param string $domain Site domain (host).
	 * @param string $path   Site path (e.g. "/" or "/subsite/").
	 * @return void
	 */
	private function purge_site_cache( string $domain, string $path ): void {
		$domain = strtolower( preg_replace( '/[^a-z0-9.\-:]/i', '', $domain ) ?? '' );
		if ( '' === $domain ) {
			return;
		}
		$path = rtrim( $path, '/' );

		foreach ( [ 'http', 'https' ] as $scheme ) {
			$dir = BCBOOST_CACHE_DIR . $scheme . '/' . $domain . $path;
			if ( ! is_dir( $dir ) ) {
				continue;
			}
			$iterator = new \RecursiveIteratorIterator(
				new \RecursiveDirectoryIterator( $dir, \FilesystemIterator::SKIP_DOTS ),
				\RecursiveIteratorIterator::CHILD_FIRST
			);
			foreach ( $iterator as $item ) {
				/** @var \SplFileInfo $item */
				$item->isDir() ? @rmdir( $item->getPathname() ) : @unlink( $item->getPathname() );
			}
			@rmdir( $dir );
		}
	}

	/**
	 * Purge all cache across network (super admin only).
	 *
	 * @return void
	 */
	public function handle_network_purge(): void {
		if ( ! is_super_admin() ) {
			return;
		}
		( new Cache_Purge() )->purge_all();
	}
}
