<?php
/**
 * Shared free → Pro sibling deactivate + delete helpers.
 *
 * @package Rsmspark_Shared
 */

defined( 'ABSPATH' ) || exit;

/**
 * Rsmspark_Pro_Free_Swap_Helper
 */
final class Rsmspark_Pro_Free_Swap_Helper {

	/**
	 * Whether the free plugin files (or registry entry) are still present.
	 *
	 * @param string $free_basename Plugin basename, e.g. rsm-directory/rsm-directory.php.
	 * @return bool
	 */
	public static function is_installed( $free_basename ) {
		$free_basename = self::normalize_basename( $free_basename );
		if ( '' === $free_basename ) {
			return false;
		}

		if ( ! function_exists( 'get_plugins' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		if ( file_exists( WP_PLUGIN_DIR . '/' . $free_basename ) ) {
			return true;
		}

		$dir = self::plugin_dir( $free_basename );
		if ( '' !== $dir && is_dir( $dir ) ) {
			return true;
		}

		$plugins = get_plugins();
		return is_array( $plugins ) && array_key_exists( $free_basename, $plugins );
	}

	/**
	 * Deactivate the free sibling if active.
	 *
	 * @param string $free_basename Plugin basename.
	 * @return void
	 */
	public static function deactivate( $free_basename ) {
		$free_basename = self::normalize_basename( $free_basename );
		if ( '' === $free_basename ) {
			return;
		}

		if ( ! function_exists( 'is_plugin_active' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		// Clear ghost active_plugins entries even when the folder is already gone.
		if ( function_exists( 'is_plugin_active' ) && is_plugin_active( $free_basename ) ) {
			deactivate_plugins( $free_basename, true );
		} elseif ( function_exists( 'get_option' ) ) {
			$active = get_option( 'active_plugins', array() );
			if ( is_array( $active ) && in_array( $free_basename, $active, true ) && function_exists( 'deactivate_plugins' ) ) {
				deactivate_plugins( $free_basename, true );
			}
		}
	}

	/**
	 * Delete free sibling files. Returns true only when the folder/main file are gone.
	 *
	 * Never calls delete_plugins() — that helper can exit() with an FTP credentials
	 * form and brick wp-admin while the front end still works. Uses WP_Filesystem
	 * only (no direct is_writable / unlink / rmdir) for Plugin Check compliance.
	 *
	 * @param string $free_basename Plugin basename.
	 * @return bool
	 */
	public static function delete( $free_basename ) {
		$free_basename = self::normalize_basename( $free_basename );
		if ( '' === $free_basename ) {
			return true;
		}

		if ( ! self::is_installed( $free_basename ) ) {
			return true;
		}

		if ( ! function_exists( 'WP_Filesystem' ) ) {
			require_once ABSPATH . 'wp-admin/includes/file.php';
		}

		$dir = self::plugin_dir( $free_basename );
		if ( '' === $dir ) {
			return ! self::is_installed( $free_basename );
		}

		// Prefer direct method — no FTP prompt during activation / plugins_loaded.
		$method = get_filesystem_method( array(), dirname( $dir ) );
		if ( 'direct' !== $method ) {
			return ! self::is_installed( $free_basename );
		}

		ob_start();
		$credentials = request_filesystem_credentials( '', '', false, false, null );
		$ready       = false !== $credentials && WP_Filesystem( $credentials );
		ob_end_clean();

		if ( ! $ready ) {
			return ! self::is_installed( $free_basename );
		}

		global $wp_filesystem;
		if ( ! is_object( $wp_filesystem ) ) {
			return ! self::is_installed( $free_basename );
		}

		$plugins_root = $wp_filesystem->wp_plugins_dir();
		if ( ! is_string( $plugins_root ) || '' === $plugins_root ) {
			return ! self::is_installed( $free_basename );
		}

		$target = trailingslashit( $plugins_root ) . dirname( $free_basename );
		if ( $wp_filesystem->exists( $target ) ) {
			$wp_filesystem->delete( $target, true );
		}

		return ! self::is_installed( $free_basename );
	}

	/**
	 * @param string $free_basename Plugin basename.
	 * @return string Absolute plugin directory or empty.
	 */
	private static function plugin_dir( $free_basename ) {
		$slug = dirname( $free_basename );
		if ( '.' === $slug || '' === $slug || false !== strpos( $slug, '..' ) ) {
			return '';
		}
		return WP_PLUGIN_DIR . '/' . $slug;
	}

	/**
	 * @param string $basename Plugin basename.
	 * @return string
	 */
	private static function normalize_basename( $basename ) {
		$basename = str_replace( '\\', '/', (string) $basename );
		$basename = ltrim( $basename, '/' );
		if ( '' === $basename || false !== strpos( $basename, '..' ) ) {
			return '';
		}
		return $basename;
	}
}
