<?php
/**
 * Fail-closed policy for temporary-login sessions on code-execution sinks.
 *
 * Temporary Login still grants the chosen WordPress role (including
 * manage_options) so vendors can do normal admin work. These sinks persist
 * after the link expires, so they stay blocked for that browser session.
 *
 * @package WP_PowerSuite\Core
 */

namespace WP_PowerSuite\Core;

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

final class TemporarySessionGuard {

	public const DENIED_CODE = 'temporary_session_denied';

	/**
	 * Admin page slugs that write or run site-persistent code.
	 *
	 * @var list<string>
	 */
	private const BLOCKED_PAGES = [
		'powersuite-code-snippet',
		'powersuite-email-delivery',
	];

	/**
	 * Module IDs that persist code or mail routing after the invite ends.
	 *
	 * @var list<string>
	 */
	private const BLOCKED_MODULES = [
		'code-snippet',
		'wp-config-editor',
		'header-footer-code',
		'alpine-js-enqueue',
		'quick-debug-toggle',
		'email-smtp',
	];

	/**
	 * AJAX actions that write those sinks (toggle/save are checked by module ID).
	 *
	 * @var list<string>
	 */
	private const BLOCKED_AJAX = [
		'wp_powersuite_config_editor_get',
		'wp_powersuite_config_editor_save',
		'wp_powersuite_config_editor_backup',
		'wp_powersuite_debug_toggle',
		'wpps_cs_save_snippet',
		'wpps_cs_delete_snippet',
		'wpps_cs_toggle_snippet',
		'wpps_cs_restore_revision',
		'wpps_email_delivery_test_connection',
		'wpps_email_delivery_test_email',
		'wpps_email_delivery_connection_form',
		'wpps_email_delivery_domain_health',
		'wpps_email_delivery_overview_stats',
		'wpps_email_delivery_tab',
		'wp_powersuite_config_import',
		'wp_powersuite_config_load_preset',
		'wp_powersuite_config_save_preset',
		'wp_powersuite_config_export',
		'wp_powersuite_clear_all_data',
		'wp_powersuite_reset_to_defaults',
		'wp_powersuite_clear_inactive_data',
		'wp_powersuite_config_delete_preset',
	];

	public static function isActive(): bool {
		$forced = apply_filters( 'wp_powersuite_is_temporary_session', null );
		if ( is_bool( $forced ) ) {
			return $forced;
		}

		if ( ! is_user_logged_in() ) {
			return false;
		}

		if ( ! class_exists( \TemporaryLogin\Module::class, false ) ) {
			return false;
		}

		if ( ! class_exists( ModuleManager::class, false ) ) {
			return false;
		}

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

		return $module->isCurrentBrowserTempSession( get_current_user_id() );
	}

	public static function blocksAdminPage( string $page ): bool {
		return in_array( sanitize_key( $page ), self::BLOCKED_PAGES, true );
	}

	public static function blocksModule( string $module_id ): bool {
		return in_array( sanitize_key( $module_id ), self::BLOCKED_MODULES, true );
	}

	public static function blocksAjaxAction( string $action ): bool {
		return in_array( sanitize_key( $action ), self::BLOCKED_AJAX, true );
	}

	public static function deniedMessage(): string {
		return __( 'Temporary login sessions cannot change how mail is sent or how code runs on this site. Ask the site owner to make that change with a normal administrator account.', 'wp-powersuite' );
	}

	/**
	 * Stop a temporary session at a persistence sink. Does not return when active.
	 */
	public static function abortIfActive(): void {
		if ( ! self::isActive() ) {
			return;
		}

		if ( function_exists( 'wp_doing_ajax' ) && wp_doing_ajax() ) {
			self::denyJson();
		}

		self::denyAdminPage();
	}

	/**
	 * @return array{message: string, code: string}
	 */
	public static function deniedPayload(): array {
		return [
			'message' => self::deniedMessage(),
			'code'    => self::DENIED_CODE,
		];
	}

	public static function denyAdminPage(): void {
		wp_die(
			esc_html( self::deniedMessage() ),
			esc_html__( 'Access Denied', 'wp-powersuite' ),
			[ 'response' => 403 ]
		);
	}

	public static function denyJson(): void {
		wp_send_json_error( self::deniedPayload() );
	}
}
