<?php
namespace SabaiApps\Directories\Component\Captcha;

use SabaiApps\Directories\Component\AbstractComponent;
use SabaiApps\Directories\Component\Display;
use SabaiApps\Directories\Component\Entity;
use SabaiApps\Directories\Component\FrontendSubmit\FrontendSubmitComponent;

class CaptchaComponent extends AbstractComponent implements IApis, Display\IElements {

	const VERSION = '2.0.6', PACKAGE = 'directories-pro';

	public static function description() {
		return 'Adds a captcha field to forms.';
	}

	public function captchaGetApiNames() {
		return array( 'captcha_recaptcha2', 'captcha_recaptcha3', 'captcha_hcaptcha', 'captcha_cloudflare_turnstile' );
	}

	public function captchaGetApi( $name ) {
		switch ( $name ) {
			case 'captcha_recaptcha2':
				return new Api\ReCaptcha2Api( $this->_application, $name );
			case 'captcha_recaptcha3':
				return new Api\ReCaptcha3Api( $this->_application, $name );
			case 'captcha_hcaptcha':
				return new Api\HCaptchaApi( $this->_application, $name );
			case 'captcha_cloudflare_turnstile':
				return new Api\CloudflareTurnstileApi( $this->_application, $name );
		}
	}

	public function displayGetElementNames( Entity\Model\Bundle $bundle ) {
		return array( 'captcha_captcha' );
	}

	public function displayGetElement( $name ) {
		return new DisplayElement\CaptchaDisplayElement( $this->_application, $name );
	}

	public function onFormBuildFrontendSubmitLoginOrRegister( array &$form ) {
		// For <v1.4
		if ( defined( 'DRTS_RECAPTCHA_DISABLE' )
			&& DRTS_RECAPTCHA_DISABLE
		) {
			return;
		}

		if ( $this->_application->Filter( 'captcha_disable', false ) ) {
			return;
		}

		if ( ! $enable = ! isset( $this->_config['enable'] ) || $this->_config['enable'] ) {
			return;
		}

		if ( $captcha_form = $this->_application->Captcha_Apis_form( 'login', 'login[login][submit]' ) ) {
			$form['login']['captcha'] = array( '#weight' => 98 ) + $captcha_form;
		}
		if ( isset( $form['register']['register']['submit'] )
			&& ( $captcha_form = $this->_application->Captcha_Apis_form( 'register', 'register[register][submit]' ) )
		) {
			$form['register']['captcha'] = array( '#weight' => FrontendSubmitComponent::REGISTER_FORM_FIELD_WEIGHT_SUBMIT - 1 ) + $captcha_form;
		}
		if ( isset( $form['guest']['continue'] )
			&& ( $captcha_form = $this->_application->Captcha_Apis_form( 'guest', 'guest[continue]' ) )
		) {
			$form['guest']['captcha'] = array( '#weight' => 98 ) + $captcha_form;
		}
	}

	public function onDirectoryAdminSettingsFormFilter( &$form ) {
		// Moved from Directory to System component
		$this->onSystemAdminSettingsFormFilter( $form );
	}

	public function onSystemAdminSettingsFormFilter( &$form ) {
		$apis              = array( '' => __( '— Select —', 'directories-pro' ) );
		$api_settings_form = array();
		foreach ( array_keys( $this->_application->Captcha_Apis( false ) ) as $api_name ) {
			$api               = $this->_application->Captcha_Apis_impl( $api_name );
			$apis[ $api_name ] = $api->captchaApiInfo( 'label' );
			if ( ! $api->captchaApiIsEnabled() ) {
				$apis_disabled[] = $api_name;
			}
			$api_settings                   = isset( $this->_config['api_settings'][ $api_name ] ) ? $this->_config['api_settings'][ $api_name ] : array();
			$api_settings                  += (array) $api->captchaApiInfo( 'default_settings' );
			$api_settings_form[ $api_name ] = array(
				'#states' => array(
					'visible' => array(
						'[name="' . $this->_name . '[enable]"]' => array(
							'type'  => 'checked',
							'value' => true,
						),
						'[name="' . $this->_name . '[api]"]' => array( 'value' => $api_name ),
					),
				),
			) + $api->captchaApiSettingsForm( $api_settings, array( 'fields', $this->_name, 'api_settings' ) );
		}
		$form['fields'][ $this->_name ] = array(
			'#component'   => $this->_name,
			'#tab'         => 'Security',
			'#title'       => __( 'Bot Protectection Settings', 'directories-pro' ),
			'enable'       => array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Enable bot protection', 'directories-pro' ),
				'#default_value' => ! isset( $this->_config['enable'] ) || $this->_config['enable'],
				'#horizontal'    => true,
			),
			'api'          => array(
				'#type'             => 'select',
				'#title'            => __( 'Bot protection API', 'directories-pro' ),
				'#options'          => $apis,
				'#options_disabled' => $apis_disabled,
				'#default_value'    => isset( $this->_config['api'] ) ? $this->_config['api'] : null,
				'#horizontal'       => true,
				'#states'           => array(
					'visible' => array(
						'[name="' . $this->_name . '[enable]"]' => array(
							'type'  => 'checked',
							'value' => true,
						),
					),
				),
			),
			'api_settings' => $api_settings_form,
		);
	}

	public static function events() {
		return array(
			// Make sure the callback is called after FrontendSubmit component
			'directoryadminsettingsformfilter' => 99,
		);
	}
}
