<?php
/**
 * Lite form-plugin integrations — Pro overlay only.
 *
 * Secure design (rafter-secure-design / auth):
 * - Identity: site visitors submitting third-party forms. No new auth primitive.
 * - AuthZ: This file is absent from the wordpress.org Lite zip. Lite keeps
 *   WP + WooCommerce surfaces. Overlay + license unlocks CF7, WPForms,
 *   Formidable, Fluent, Elementor, and Basic Forms.
 *
 * @package GoogleRecaptcha
 */

namespace GoogleRecaptcha;

use WP_PowerSuite\Captcha\Shared\CaptchaRuntime;
use WP_PowerSuite\Captcha\Shared\SkipRules;
use WP_PowerSuite\Captcha\Shared\WidgetLayoutStyles;

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

final class FormIntegrations {

	private static bool $booted = false;

	private static ?Module $module = null;

	public static function boot( Module $m ): void {
		if ( self::$booted ) {
			return;
		}
		self::$booted = true;
		self::$module = $m;

		$s = $m->getCaptchaSettings();

		if ( ! empty( $s['cf7'] ) && class_exists( 'WPCF7' ) ) {
			add_filter(
				'wpcf7_form_elements',
				static function ( string $content ) use ( $m ): string {
					if ( ( $m->getCaptchaSettings()['site_key'] ?? '' ) === '' ) {
						return $content;
					}
					ob_start();
					$m->renderWidget( 'cf7', $m->unlockSubmitOpts( 'wppsGrCF7Callback', '.wpcf7-submit' ) );
					return self::injectBeforeSubmit( $content, (string) ob_get_clean() );
				},
				20
			);
			add_filter(
				'wpcf7_spam',
				static function ( bool $spam, $submission ) use ( $m ): bool {
					if ( $spam ) {
						return true;
					}
					$settings = $m->getCaptchaSettings();
					$skip     = is_array( $settings['skip_rules'] ?? null ) ? $settings['skip_rules'] : [];
					if ( SkipRules::shouldSkip( $skip ) ) {
						return false;
					}
					$posted = null;
					if ( is_object( $submission ) && method_exists( $submission, 'get_posted_data' ) ) {
						$posted = $submission->get_posted_data();
						$posted = is_array( $posted ) ? $posted : null;
					}
					return ! $m->verifyCaptchaToken( $m->postedCaptchaToken( $posted ), 'cf7' );
				},
				10,
				2
			);
		}

		if ( ! empty( $s['wpforms'] ) && function_exists( 'wpforms' ) ) {
			add_action(
				'wpforms_display_submit_before',
				static function ( $form_data ) use ( $m ): void {
					if ( ! is_array( $form_data ) || empty( $form_data['id'] ) ) {
						return;
					}
					$m->renderWidget( 'wpforms_' . (string) absint( $form_data['id'] ), $m->unlockSubmitOpts( 'wppsGrWPFCallback', '.wpforms-submit' ) );
				},
				10,
				1
			);
			add_filter(
				'wpforms_process_initial_errors',
				static function ( array $errors, array $form_data ) use ( $m ): array {
					$form_id = isset( $form_data['id'] ) ? absint( $form_data['id'] ) : 0;
					if ( $form_id <= 0 ) {
						return $errors;
					}
					if ( ! $m->verifyCaptchaToken( $m->postedCaptchaToken( $form_data ), 'wpforms_' . (string) $form_data['id'] ) ) {
						if ( ! isset( $errors[ $form_id ] ) || ! is_array( $errors[ $form_id ] ) ) {
							$errors[ $form_id ] = [];
						}
						$errors[ $form_id ]['footer'] = $m->captchaErrorMessage( __( 'Please complete the reCAPTCHA verification.', 'wp-powersuite' ), 'wpforms' );
					}
					return $errors;
				},
				10,
				2
			);
		}

		if ( ! empty( $s['formidable'] ) && class_exists( 'FrmFormsController' ) ) {
			add_filter(
				'frm_submit_button_html',
				static function ( $button, $args ) use ( $m ) {
					$form = ( is_array( $args ) && ! empty( $args['form'] ) && is_object( $args['form'] ) ) ? $args['form'] : null;
					if ( $form === null ) {
						return (string) $button;
					}
					$form_id = isset( $form->id ) ? absint( $form->id ) : 0;
					ob_start();
					$m->renderWidget( $form_id > 0 ? 'formidable_' . $form_id : 'formidable_form', $m->unlockSubmitOpts( 'wppsGrFormidableCallback', '.frm_forms .frm_button_submit' ) );
					return (string) ob_get_clean() . $button;
				},
				10,
				2
			);
			add_filter(
				'frm_validate_entry',
				static function ( array $errors, array $values ) use ( $m ): array {
					$form_id = isset( $values['form_id'] ) ? absint( $values['form_id'] ) : 0;
					$action  = $form_id > 0 ? 'formidable_' . $form_id : 'formidable_form';
					if ( ! $m->verifySubmittedToken( $action ) ) {
						$errors['recaptcha'] = $m->captchaErrorMessage( __( 'Please complete the reCAPTCHA verification.', 'wp-powersuite' ), 'formidable' );
					}
					return $errors;
				},
				20,
				2
			);
		}

		if ( ! empty( $s['fluent_forms'] ) && defined( 'FLUENTFORM' ) ) {
			add_action(
				'fluentform/render_item_submit_button',
				static function ( $submit_field, $form = null ) use ( $m ): void {
					unset( $submit_field );
					$form_id = 'form';
					if ( is_object( $form ) && isset( $form->id ) ) {
						$form_id = (string) $form->id;
					}
					$m->renderWidget( 'fluent_' . $form_id, $m->unlockSubmitOpts( 'wppsGrFluentCallback', '.fluentform .ff-btn-submit' ) );
				},
				5,
				2
			);
			add_filter(
				'fluentform/validation_errors',
				static function ( array $errors, array $form_data, $form, array $fields ) use ( $m ): array {
					unset( $fields );
					$form_id = ( is_object( $form ) && isset( $form->id ) ) ? $form->id : '0';
					if ( ! $m->verifyCaptchaToken( $m->postedCaptchaToken( $form_data ), 'fluent_' . $form_id ) ) {
						$errors['recaptcha'] = $m->captchaErrorMessage( __( 'Please complete the reCAPTCHA verification.', 'wp-powersuite' ), 'fluent_forms' );
					}
					return $errors;
				},
				10,
				4
			);
		}

		if ( ! empty( $s['basic_forms'] ) ) {
			add_action(
				'wpps_basic_forms_before_submit',
				static function ( int $form_id, array $settings ) use ( $m ): void {
					if ( ! CaptchaRuntime::basicFormsCaptchaActive( $settings ) ) {
						return;
					}
					if ( ( $settings['captcha_provider'] ?? '' ) !== 'google' ) {
						return;
					}
					$fid  = (int) $form_id;
					$opts = [ 'explicit_only' => true ];
					$gs   = $m->getCaptchaSettings();
					if ( ! empty( $gs['disable_submit'] ) && ( $gs['version'] ?? 'v2' ) === 'v2' ) {
						$m->enqueueRecaptchaScript();
						$cb  = 'wppsGrBfUnlock' . $fid;
						$sel = '.wpps-bf-form[data-form-id="' . $fid . '"] .wpps-bf-submit';
						wp_add_inline_script(
							Module::SCRIPT_HANDLE,
							'function ' . $cb . '(){document.querySelectorAll(' . wp_json_encode( $sel ) . ').forEach(function(el){el.style.setProperty("pointer-events","auto","important");el.style.setProperty("opacity","1","important");});}',
							'before'
						);
						$opts = array_merge( $opts, $m->unlockSubmitOpts( $cb, $sel ) );
					}
					$m->renderWidget( 'basic_forms_' . $fid, $opts );
				},
				10,
				2
			);
			add_filter(
				'wpps_verify_basic_forms_captcha',
				static function ( bool $verified, int $form_id, array $settings ) use ( $m ): bool {
					if ( ! CaptchaRuntime::basicFormsCaptchaActive( $settings ) ) {
						return $verified;
					}
					if ( ( $settings['captcha_provider'] ?? '' ) !== 'google' ) {
						return $verified;
					}
					return $m->verifySubmittedToken( 'basic_forms_' . $form_id );
				},
				10,
				3
			);
			add_action( 'admin_enqueue_scripts', [ $m, 'enqueueRecaptchaInAdminForBasicForms' ], 5 );
		}

		if ( ! empty( $s['elementor_forms'] ) && did_action( 'elementor/loaded' ) ) {
			add_action( 'wp_enqueue_scripts', [ self::class, 'enqueueForElementor' ] );
			add_action( 'wp_footer', [ self::class, 'printElementorInjector' ], 30 );
			add_action(
				'elementor_pro/forms/validation',
				static function ( $record, $ajax_handler ) use ( $m ): void {
					$form_id = '';
					if ( is_object( $record ) && method_exists( $record, 'get_form_settings' ) ) {
						$fs = $record->get_form_settings();
						if ( is_array( $fs ) && isset( $fs['id'] ) ) {
							$form_id = (string) $fs['id'];
						}
					}
					if ( $form_id === '' && isset( $_POST['form_id'] ) ) {
						$form_id = sanitize_text_field( wp_unslash( (string) $_POST['form_id'] ) );
					}
					$settings = $m->getCaptchaSettings();
					$is_v3    = ( $settings['version'] ?? 'v2' ) === 'v3';
					$action   = '';
					if ( $is_v3 ) {
						$action = $form_id !== '' ? 'elementor_' . preg_replace( '/[^a-zA-Z0-9_-]/', '', $form_id ) : 'elementor_form';
					}
					if ( $m->verifySubmittedToken( $action ) ) {
						return;
					}
					$message = $m->captchaErrorMessage( __( 'Please complete the reCAPTCHA verification.', 'wp-powersuite' ), 'elementor_forms' );
					if ( is_object( $ajax_handler ) && method_exists( $ajax_handler, 'add_error' ) ) {
						$ajax_handler->add_error( 'wpps_recaptcha', $message );
					}
				},
				10,
				2
			);
		}
	}

	public static function enqueueForElementor(): void {
		$mod = self::module();
		if ( $mod === null || is_admin() || ! self::requestMayContainElementorForm() ) {
			return;
		}
		$mod->enqueueRecaptchaScript();
		$s = $mod->getCaptchaSettings();
		if ( ! empty( $s['disable_submit'] ) && ( $s['version'] ?? 'v2' ) === 'v2' ) {
			$mod->enqueueDisableSubmitScript();
		}
	}

	public static function printElementorInjector(): void {
		$m = self::module();
		if ( $m === null ) {
			return;
		}
		if ( ! wp_script_is( Module::SCRIPT_HANDLE, 'enqueued' ) && ! wp_script_is( Module::SCRIPT_HANDLE, 'done' ) ) {
			return;
		}
		$settings = $m->getCaptchaSettings();
		$site_key = isset( $settings['site_key'] ) ? (string) $settings['site_key'] : '';
		if ( $site_key === '' ) {
			return;
		}
		if ( SkipRules::shouldSkip( is_array( $settings['skip_rules'] ?? null ) ? $settings['skip_rules'] : [] ) ) {
			return;
		}
		WidgetLayoutStyles::printFrontEndOnce();
		$version              = isset( $settings['version'] ) ? (string) $settings['version'] : 'v2';
		$theme                = isset( $settings['theme'] ) ? (string) $settings['theme'] : 'light';
		$disable_submit       = ! empty( $settings['disable_submit'] ) && $version === 'v2';
		$elementor_unlock_raw = 'form.elementor-form button[type="submit"], form.elementor-form input[type="submit"], form.elementor-form .elementor-button[type="submit"]';
		$elementor_unlock_css = preg_replace( '/[^#\.a-zA-Z0-9 _\-:,]/', '', $elementor_unlock_raw );
		?>
<script>
(function () {
	var SITE_KEY = <?php echo wp_json_encode( $site_key ); ?>;
	var VERSION  = <?php echo wp_json_encode( $version ); ?>;
	var THEME    = <?php echo wp_json_encode( $theme ); ?>;
	var DISABLE_SUBMIT = <?php echo $disable_submit ? 'true' : 'false'; ?>;

	function inject(form) {
		if (!form || form.dataset.wppsRecaptchaInjected === '1') { return; }
		var submit = form.querySelector('button[type="submit"], input[type="submit"], .elementor-button[type="submit"]');
		if (!submit) { return; }
		var wrap = document.createElement('div');
		wrap.className = 'wpps-elementor-recaptcha elementor-field-group';
		wrap.style.margin = '0 0 1.25em 0';
		var formIdInput = form.querySelector('input[name="form_id"]');
		var formAction = 'elementor_form';
		if (formIdInput && formIdInput.value) {
			formAction = 'elementor_' + String(formIdInput.value).replace(/[^a-zA-Z0-9_-]/g, '');
		}
		if (VERSION === 'v3') {
			var input = document.createElement('input');
			input.type = 'hidden';
			input.name = 'g-recaptcha-response';
			input.className = 'wpps-recaptcha-v3-token';
			input.setAttribute('data-action', formAction);
			wrap.appendChild(input);
		} else {
			var widget = document.createElement('div');
			widget.className = 'g-recaptcha wpps-g-recaptcha-v2';
			widget.setAttribute('data-sitekey', SITE_KEY);
			widget.setAttribute('data-theme', THEME);
			widget.setAttribute('data-size', 'normal');
			if (DISABLE_SUBMIT) {
				widget.setAttribute('data-callback', 'wppsGrElementorCallback');
			}
			wrap.appendChild(widget);
			if (DISABLE_SUBMIT && <?php echo wp_json_encode( $elementor_unlock_css ); ?>) {
				var st = document.createElement('style');
				st.textContent = <?php echo wp_json_encode( $elementor_unlock_css ); ?> + '{pointer-events:none!important;opacity:0.5!important;}';
				document.head.appendChild(st);
			}
			if (window.grecaptcha && typeof grecaptcha.ready === 'function') {
				grecaptcha.ready(function () {
					if (typeof window.wppsGrecaptchaV2Init === 'function') {
						window.wppsGrecaptchaV2Init();
					}
				});
			}
		}
		submit.parentNode.insertBefore(wrap, submit);
		form.dataset.wppsRecaptchaInjected = '1';
	}

	function scan() {
		document.querySelectorAll('form.elementor-form').forEach(inject);
	}

	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', scan);
	} else {
		scan();
	}
	if (window.jQuery) {
		window.jQuery(document).on('elementor/popup/show', scan);
	}
	window.addEventListener('load', scan);
})();
</script>
		<?php
	}

	private static function requestMayContainElementorForm(): bool {
		if ( ! is_singular() ) {
			return false;
		}
		$post_id = get_queried_object_id();
		if ( $post_id <= 0 ) {
			return false;
		}
		$content = (string) get_post_field( 'post_content', $post_id );
		if ( strpos( $content, 'elementor-form' ) !== false || strpos( $content, '[elementor-template' ) !== false ) {
			return true;
		}
		$elementor_data = (string) get_post_meta( $post_id, '_elementor_data', true );
		return $elementor_data !== '' && ( strpos( $elementor_data, '"form_fields"' ) !== false || strpos( $elementor_data, '"form_name"' ) !== false );
	}

	private static function injectBeforeSubmit( string $html, string $inject ): string {
		if ( $inject === '' ) {
			return $html;
		}
		if ( preg_match( '/<input\b[^>]*\btype\s*=\s*["\']submit["\'][^>]*\/?>/i', $html ) ) {
			return (string) preg_replace(
				'/(<input\b[^>]*\btype\s*=\s*["\']submit["\'][^>]*\/?>)/i',
				$inject . '$1',
				$html,
				1
			);
		}
		if ( preg_match( '/<button\b[^>]*\btype\s*=\s*["\']submit["\'][^>]*>/i', $html ) ) {
			return (string) preg_replace(
				'/(<button\b[^>]*\btype\s*=\s*["\']submit["\'][^>]*>)/i',
				$inject . '$1',
				$html,
				1
			);
		}
		if ( stripos( $html, '</form>' ) !== false ) {
			return (string) preg_replace( '/(<\/form>)/i', $inject . '$1', $html, 1 );
		}
		return $html . $inject;
	}

	private static function module(): ?Module {
		return self::$module;
	}
}
