<?php
/**
 * Disable Keyboard Keys Module
 *
 * Disables specific keyboard shortcuts for selected user roles (content protection).
 *
 * @package DisableKeyboardKeys
 * @since 1.0.0
 */

namespace DisableKeyboardKeys;

use WP_PowerSuite\Core\AbstractModule;
use WP_PowerSuite\Core\ContentProtection;

class Module extends AbstractModule {

	private const MODULE_ID = 'disable-keyboard-keys';
	private const MODULE_VERSION = '1.0.3';
	private const DEFAULT_DISABLED_MESSAGE = 'This function is disabled';

	/** Map setting keys to frontend disabledKeys keys. */
	private const KEY_MAP = [
		'dev_tools' => 'devTools',
		'search'    => 'search',
		'ctrl_c'    => 'ctrlC',
		'ctrl_v'    => 'ctrlV',
		'ctrl_a'    => 'ctrlA',
		'ctrl_u'    => 'ctrlU',
		'ctrl_p'    => 'ctrlP',
		'ctrl_h'    => 'ctrlH',
		'ctrl_l'    => 'ctrlL',
		'ctrl_k'    => 'ctrlK',
		'ctrl_o'    => 'ctrlO',
		'ctrl_e'    => 'ctrlE',
		'ctrl_f3'   => 'ctrlF3',
		'alt_d'     => 'altD',
		'f6'        => 'f6',
		'f12'       => 'f12',
	];

	private ?array $settings_cache = null;

	public function getId(): string {
		return self::MODULE_ID;
	}

	public function getName(): string {
		return __( 'Disable Keyboard Keys', 'wp-powersuite' );
	}

	public function getVersion(): string {
		return self::MODULE_VERSION;
	}

	public function getDescription(): string {
		return __( 'Turn off selected keyboard shortcuts for certain roles to gently discourage copying or inspection on the front end.', 'wp-powersuite' );
	}

	public function getContext(): string|array {
		return 'frontend';
	}

	public function getDefaultSettings(): array {
		$defaults = [
			'roles'              => [],
			'apply_to_visitors'   => true,
			'message'            => self::DEFAULT_DISABLED_MESSAGE,
			'message_position'   => 'top-right',
			'message_duration'   => 3000,
		];
		foreach ( array_keys( self::KEY_MAP ) as $key ) {
			$defaults[ $key ] = false;
		}
		return $defaults;
	}

	protected function registerHooks(): void {
		if ( is_admin() || ! $this->hasAnyKeyEnabled() || ! ContentProtection::couldApplyForConfiguredAudience( $this->getSettings() ) ) {
			return;
		}
		add_action( 'wp', [ $this, 'maybeRegisterContentProtection' ], 1 );
	}

	/**
	 * Register shared content-protection hooks only on normal frontend document requests.
	 */
	public function maybeRegisterContentProtection(): void {
		if ( ! ContentProtection::isBrowsableFrontendRequest() || ! $this->shouldApplyToCurrentUser() ) {
			return;
		}
		add_filter( 'wp_powersuite_content_protection_config', [ $this, 'addConfig' ], 10, 1 );
		ContentProtection::register_enqueue_callback();
	}

	private function resolveDisabledMessage( string $stored ): string {
		$trimmed = trim( $stored );
		if ( $trimmed === '' || $trimmed === self::DEFAULT_DISABLED_MESSAGE ) {
			return __( 'This function is disabled', 'wp-powersuite' );
		}
		return $stored;
	}

	public function addConfig( array $config ): array {
		$settings = $this->getSettings();
		$disabled = [];
		foreach ( self::KEY_MAP as $setting_key => $js_key ) {
			if ( ! empty( $settings[ $setting_key ] ) ) {
				$disabled[ $js_key ] = true;
			}
		}
		if ( ! empty( $disabled ) ) {
			$existing = isset( $config['disabledKeys'] ) && is_array( $config['disabledKeys'] ) ? $config['disabledKeys'] : [];
			$config['disabledKeys'] = array_merge( $existing, $disabled );
			if ( ! isset( $config['messages'] ) || ! is_array( $config['messages'] ) ) {
				$config['messages'] = [];
			}
			$config['messages']['disabledKeys'] = $this->resolveDisabledMessage( (string) ( $settings['message'] ?? self::DEFAULT_DISABLED_MESSAGE ) );
		}
		if ( ! isset( $config['position'] ) ) {
			$config['position'] = $settings['message_position'] ?? 'top-right';
		}
		if ( ! isset( $config['duration'] ) ) {
			$config['duration'] = (int) ( $settings['message_duration'] ?? 3000 );
		}
		return $config;
	}

	/**
	 * True when at least one shortcut option is turned on (avoids registering hooks when nothing is configured).
	 */
	private function hasAnyKeyEnabled(): bool {
		$settings = $this->getSettings();
		foreach ( array_keys( self::KEY_MAP ) as $setting_key ) {
			if ( ! empty( $settings[ $setting_key ] ) ) {
				return true;
			}
		}
		return false;
	}

	private function shouldApplyToCurrentUser(): bool {
		$settings = $this->getSettings();
		if ( ! is_user_logged_in() ) {
			return ! empty( $settings['apply_to_visitors'] );
		}
		$user  = wp_get_current_user();
		$roles = $settings['roles'] ?? [];
		if ( ! is_array( $roles ) || empty( $roles ) ) {
			return false;
		}
		foreach ( $user->roles as $role ) {
			if ( in_array( $role, $roles, true ) ) {
				return true;
			}
		}
		return false;
	}

	private function getSettings(): array {
		if ( $this->settings_cache !== null ) {
			return $this->settings_cache;
		}
		$saved = $this->moduleSettings()->all( [] );
		$this->settings_cache = array_merge( $this->getDefaultSettings(), is_array( $saved ) ? $saved : [] );
		return $this->settings_cache;
	}
}
