<?php
/**
 * Shared runtime guards for captcha modules (load scope, admin screens, integrations).
 *
 * @package WP_PowerSuite\Captcha\Shared
 * @since 1.5.1
 */

namespace WP_PowerSuite\Captcha\Shared;

use WP_PowerSuite\Core\OptionStoreModuleSettingsRepository;

/**
 * Keeps captcha modules from registering hooks or assets outside their configured scope.
 */
final class CaptchaRuntime {

	/** @var list<string> */
	private const POWERSUITE_ADMIN_PAGES = [
		'powersuite',
		'powersuite-performance',
		'powersuite-settings',
		'powersuite-license',
		'powersuite-basic-forms',
	];

	/** @var list<string> */
	private const MAGIC_LOGIN_ACTIONS = [
		'wpps_ml',
		'wpps_ml_code',
		'wpps_ml_verify',
		'wpps_ml_register',
	];

	/**
	 * Magic Login owns wp-login.php for these actions; password-login CAPTCHA must not render.
	 */
	public static function isMagicLoginLoginScreen(): bool {
		if ( ! class_exists( OptionStoreModuleSettingsRepository::class, false ) ) {
			return false;
		}
		if ( ! OptionStoreModuleSettingsRepository::isModuleEnabled( 'magic-login' ) ) {
			return false;
		}

		global $pagenow;
		if ( ! isset( $pagenow ) || 'wp-login.php' !== $pagenow ) {
			return (bool) apply_filters( 'wp_powersuite_is_magic_login_login_screen', false );
		}

		$action = isset( $_REQUEST['action'] ) ? sanitize_key( wp_unslash( (string) $_REQUEST['action'] ) ) : 'login';
		$actions = apply_filters( 'wp_powersuite_magic_login_login_actions', self::MAGIC_LOGIN_ACTIONS );
		if ( ! is_array( $actions ) ) {
			$actions = self::MAGIC_LOGIN_ACTIONS;
		}

		return in_array( $action, $actions, true )
			|| (bool) apply_filters( 'wp_powersuite_is_magic_login_login_screen', false );
	}

	/**
	 * Whether wp-login (or Woo auth forms) need provider scripts/styles.
	 *
	 * @param array<string, mixed> $settings Normalized module settings.
	 */
	public static function needsWpLoginScreenAssets( array $settings ): bool {
		if ( ! empty( $settings['protect_login'] ) || ! empty( $settings['protect_registration'] ) || ! empty( $settings['protect_password_reset'] ) ) {
			return true;
		}
		if ( ! class_exists( 'WooCommerce', false ) ) {
			return false;
		}

		return ! empty( $settings['woo_login'] ) || ! empty( $settings['woo_registration'] ) || ! empty( $settings['woo_lost_password'] );
	}

	/**
	 * Whether any WooCommerce integration toggle is on.
	 *
	 * @param array<string, mixed> $settings Normalized module settings.
	 */
	/**
	 * Whether any front-end protection toggle is enabled (scripts/hints may be needed).
	 *
	 * @param array<string, mixed> $settings Normalized module settings.
	 */
	public static function hasAnyFrontendProtection( array $settings ): bool {
		$core = ! empty( $settings['protect_login'] )
			|| ! empty( $settings['protect_registration'] )
			|| ! empty( $settings['protect_password_reset'] )
			|| ! empty( $settings['protect_comments'] );

		$woo = self::hasWooCommerceIntegration( $settings );

		$forms = ! empty( $settings['basic_forms'] )
			|| ! empty( $settings['cf7'] )
			|| ! empty( $settings['wpforms'] )
			|| ! empty( $settings['formidable'] )
			|| ! empty( $settings['fluent_forms'] )
			|| ! empty( $settings['elementor_forms'] );

		$extended = ! empty( $settings['integration_gravity'] )
			|| ! empty( $settings['integration_jetpack'] )
			|| ! empty( $settings['integration_bbpress'] )
			|| ! empty( $settings['integration_buddypress'] )
			|| ! empty( $settings['integration_ultimate_member'] )
			|| ! empty( $settings['integration_memberpress'] )
			|| ! empty( $settings['integration_edd'] )
			|| ! empty( $settings['integration_pmp'] )
			|| ! empty( $settings['integration_mc4wp'] );

		return $core || $woo || $forms || $extended;
	}

	public static function hasWooCommerceIntegration( array $settings ): bool {
		if ( ! class_exists( 'WooCommerce', false ) ) {
			return false;
		}

		return ! empty( $settings['woo_login'] )
			|| ! empty( $settings['woo_registration'] )
			|| ! empty( $settings['woo_lost_password'] )
			|| ! empty( $settings['woo_checkout'] )
			|| ! empty( $settings['woo_reviews'] );
	}

	/**
	 * Whether admin CSS/JS for module settings or Basic Forms preview should load.
	 *
	 * @param array<string, mixed> $settings Normalized module settings.
	 */
	public static function shouldEnqueueAdminAssets( array $settings ): bool {
		if ( ! is_admin() ) {
			return false;
		}
		if ( self::isPowerSuiteAdminScreen() ) {
			return true;
		}

		return ! empty( $settings['basic_forms'] ) && self::isBasicFormsAdminScreen();
	}

	/**
	 * PowerSuite plugin admin pages (module modals, settings, Basic Forms).
	 */
	public static function isPowerSuiteAdminScreen(): bool {
		$page = self::currentAdminPage();

		return $page !== '' && in_array( $page, self::POWERSUITE_ADMIN_PAGES, true );
	}

	/**
	 * Basic Forms editor / list screen only.
	 */
	public static function isBasicFormsAdminScreen(): bool {
		return self::currentAdminPage() === 'powersuite-basic-forms';
	}

	/**
	 * Basic Forms per-form captcha is enabled for a supported provider.
	 *
	 * @param array<string, mixed> $form_settings Form settings from Basic Forms.
	 */
	public static function basicFormsCaptchaActive( array $form_settings ): bool {
		if ( empty( $form_settings['enable_spam_protection'] ) ) {
			return false;
		}
		$provider = $form_settings['captcha_provider'] ?? '';

		return $provider === 'google' || $provider === 'turnstile';
	}

	/**
	 * Whether another captcha module is enabled with API keys configured.
	 * Used for admin guidance when multiple providers are active.
	 *
	 * @param string $other_module_id Module ID to check (e.g. cloudflare-turnstile).
	 */
	public static function isSiblingCaptchaConfigured( string $other_module_id ): bool {
		if ( ! class_exists( OptionStoreModuleSettingsRepository::class, false ) ) {
			return false;
		}
		if ( ! OptionStoreModuleSettingsRepository::isModuleEnabled( $other_module_id ) ) {
			return false;
		}
		$raw = OptionStoreModuleSettingsRepository::forModule( $other_module_id )->all( [] );
		if ( ! is_array( $raw ) ) {
			return false;
		}

		return trim( (string) ( $raw['site_key'] ?? '' ) ) !== '' && trim( (string) ( $raw['secret_key'] ?? '' ) ) !== '';
	}

	private static function currentAdminPage(): string {
		if ( ! is_admin() || ! isset( $_GET['page'] ) ) {
			return '';
		}

		return sanitize_key( wp_unslash( (string) $_GET['page'] ) );
	}
}
