<?php
/**
 * Platform boot hooks: early module bootstrap and core integrations.
 *
 * @package WP_PowerSuite\Core
 * @since 1.0.0
 */

namespace WP_PowerSuite\Core;

use WP_PowerSuite\Bootstrap\Kernel;
use WP_PowerSuite\Captcha\Shared\ElementorWppsScStubField;

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

/**
 * Registers early and post-kernel platform boot behavior.
 *
 * - {@see registerEarly()}: plugins_loaded priority 1 (backup zlib guard).
 * - {@see onBoot()}: fired via {@see 'wp_powersuite_boot'} after modules load.
 */
final class BootServiceProvider {

	/**
	 * Register hooks that must run before the main plugin kernel boots.
	 */
	public static function registerEarly(): void {
		add_action( 'plugins_loaded', [ self::class, 'bootLongAjaxHardening' ], 1 );
		add_action( 'plugins_loaded', [ self::class, 'loadBackupEarlyBootstrap' ], 1 );
		add_action( 'plugins_loaded', [ self::class, 'loadEmailSmtpEarlyBootstrap' ], 1 );
		add_action( 'wp_powersuite_boot', [ self::class, 'onBoot' ], 10, 2 );
	}

	/**
	 * Shared zlib/no-cache early guard for Backup and AI Alt Text long AJAX ticks.
	 */
	public static function bootLongAjaxHardening(): void {
		if ( ! class_exists( LongAjaxResponse::class, true ) ) {
			return;
		}

		LongAjaxResponse::bootEarly();
	}

	/**
	 * Core integrations after ModuleManager has booted.
	 *
	 * @param Kernel $kernel Kernel instance.
	 * @param Plugin $plugin Plugin instance.
	 */
	public static function onBoot( Kernel $kernel, Plugin $plugin ): void {
		unset( $kernel, $plugin );

		self::registerElementorStubField();
		self::registerTemporaryLoginSelfDeactivationGuard();
		self::ensureTemporaryLoginAjaxHandlers();
	}

	/**
	 * Load backup early-bootstrap when the module is enabled.
	 *
	 * Enabled state is read via {@see OptionStore} (respects {@see NetworkScope}).
	 */
	public static function loadBackupEarlyBootstrap(): void {
		if ( ! defined( 'WP_POWERSUITE_MODULES_DIR' ) ) {
			return;
		}

		$early = WP_POWERSUITE_MODULES_DIR . 'backup-restore' . DIRECTORY_SEPARATOR . 'early-bootstrap.php';
		if ( ! is_readable( $early ) ) {
			return;
		}

		if ( ! function_exists( 'wp_powersuite_bootstrap_for_lifecycle' ) || ! wp_powersuite_bootstrap_for_lifecycle() ) {
			return;
		}

		if ( ! class_exists( OptionStore::class, true ) ) {
			return;
		}

		if ( ! OptionStore::getInstance()->isModuleEnabled( 'backup-restore' ) ) {
			return;
		}

		require_once $early;
	}

	/**
	 * Register SMTP phpmailer_init before the module kernel boots when enabled.
	 */
	public static function loadEmailSmtpEarlyBootstrap(): void {
		if ( ! defined( 'WP_POWERSUITE_MODULES_DIR' ) ) {
			return;
		}

		$early = WP_POWERSUITE_MODULES_DIR . 'email-smtp' . DIRECTORY_SEPARATOR . 'early-bootstrap.php';
		if ( ! is_readable( $early ) ) {
			return;
		}

		if ( ! function_exists( 'wp_powersuite_bootstrap_for_lifecycle' ) || ! wp_powersuite_bootstrap_for_lifecycle() ) {
			return;
		}

		if ( ! class_exists( OptionStore::class, true ) ) {
			return;
		}

		if ( ! OptionStore::getInstance()->isModuleEnabled( 'email-smtp' ) ) {
			return;
		}

		require_once $early;
	}

	/**
	 * When Simple CAPTCHA does not register the real Elementor field, register a no-op field
	 * so legacy "Simple CAPTCHA" form rows do not still render a challenge.
	 */
	private static function registerElementorStubField(): void {
		add_action( 'elementor_pro/forms/fields/register', [ ElementorWppsScStubField::class, 'registerIfNeeded' ], 5, 1 );
	}

	/**
	 * Prevent deactivating WP PowerSuite while the current session was started via a temp link.
	 *
	 * Disable (not recommended): `add_filter( 'wpps_tl_block_self_deactivation', '__return_false' );`
	 */
	private static function registerTemporaryLoginSelfDeactivationGuard(): void {
		add_action( 'admin_init', [ self::class, 'blockTemporaryLoginSelfDeactivation' ], 1 );
	}

	/**
	 * Ensure Temporary Login AJAX handlers exist even when manifest cache lags behind meta.json.
	 */
	private static function ensureTemporaryLoginAjaxHandlers(): void {
		if ( ! wp_doing_ajax() ) {
			return;
		}

		$action = isset( $_REQUEST['action'] ) ? sanitize_key( wp_unslash( (string) $_REQUEST['action'] ) ) : '';
		if ( $action === '' || ( $action !== 'tl_admin' && ! str_starts_with( $action, 'tl_' ) ) ) {
			return;
		}

		if ( ! OptionStore::getInstance()->isModuleEnabled( 'temporary-login' ) ) {
			return;
		}

		$module_manager = ModuleManager::getInstance();
		if ( $module_manager->getModule( 'temporary-login' ) instanceof \TemporaryLogin\Module ) {
			return;
		}

		try {
			$module_manager->loadModule( 'temporary-login' );
		} catch ( \Throwable $e ) {
			error_log( 'WP PowerSuite: temporary-login AJAX bootstrap failed: ' . $e->getMessage() );
		}
	}

	/**
	 * Block plugin self-deactivation/delete for active temporary-login browser sessions.
	 */
	public static function blockTemporaryLoginSelfDeactivation(): void {
		if ( ! OptionStore::getInstance()->isModuleEnabled( 'temporary-login' ) ) {
			return;
		}

		if ( ! is_user_logged_in() || ! current_user_can( 'activate_plugins' ) ) {
			return;
		}

		$user_id = get_current_user_id();
		if ( ! apply_filters( 'wpps_tl_block_self_deactivation', true, $user_id ) ) {
			return;
		}

		$has_temp_session = false;
		if ( class_exists( 'TemporaryLogin\\Module' ) ) {
			$tl_module = ModuleManager::getInstance()->getModule( 'temporary-login' );
			if ( $tl_module instanceof \TemporaryLogin\Module ) {
				$has_temp_session = $tl_module->isCurrentBrowserTempSession( $user_id );
			}
		}

		if ( ! $has_temp_session || ! defined( 'WP_POWERSUITE_PLUGIN_BASENAME' ) ) {
			return;
		}

		$basename    = WP_POWERSUITE_PLUGIN_BASENAME;
		$message     = wp_kses_post(
			__( 'You cannot deactivate WP PowerSuite while your session was started with a temporary login link. Log out to end the session, ask the site owner to revoke the link, or have someone who signed in with a normal password change plugins.', 'wp-powersuite' )
		);
		$title       = esc_html__( 'Cannot deactivate plugin', 'wp-powersuite' );
		$wp_die_args = [ 'response' => 403, 'back_link' => true ];

		$blocked_actions = [ 'deactivate', 'delete-plugin' ];

		if ( isset( $_GET['action'], $_GET['plugin'], $_GET['_wpnonce'] ) && in_array( sanitize_text_field( wp_unslash( $_GET['action'] ) ), $blocked_actions, true ) ) {
			$plugin       = sanitize_text_field( wp_unslash( $_GET['plugin'] ) );
			$nonce_action = $_GET['action'] === 'delete-plugin' ? 'delete-plugin_' . $plugin : 'deactivate-plugin_' . $plugin;
			if ( $plugin === $basename && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), $nonce_action ) ) {
				wp_die( $message, $title, $wp_die_args );
			}
			return;
		}

		if ( isset( $_POST['action'], $_POST['checked'], $_POST['_wpnonce'] ) && $_POST['action'] === 'deactivate-selected' && is_array( $_POST['checked'] ) ) {
			$nonce   = sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) );
			$bulk_ok = wp_verify_nonce( $nonce, 'bulk-plugins' );
			if ( ! $bulk_ok && function_exists( 'is_network_admin' ) && is_network_admin() ) {
				$bulk_ok = wp_verify_nonce( $nonce, 'bulk-plugins-network' );
			}
			if ( ! $bulk_ok ) {
				return;
			}
			$checked = array_map( 'sanitize_text_field', wp_unslash( $_POST['checked'] ) );
			if ( in_array( $basename, $checked, true ) ) {
				wp_die( $message, $title, $wp_die_args );
			}
		}
	}
}
