<?php

namespace WPProofShield\Integration;

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


use WPProofShield\Security\RequestVerifier;
use WPProofShield\Support\FeatureAccess\FeatureAccess;
use WPProofShield\Support\Settings;
use WPProofShield\Support\UiLanguage;

final class CommentGuard {

	public function __construct(
		private Settings $settings,
		private RequestVerifier $verifier,
		private FeatureAccess $feature_access
	) {
	}

	public function register(): void {
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueueAssets' ) );
		add_action( 'comment_form_after_fields', array( $this, 'renderFields' ) );
		add_action( 'comment_form_logged_in_after', array( $this, 'renderFields' ) );
		add_filter( 'preprocess_comment', array( $this, 'preprocessComment' ), 1 );
	}

	public function enqueueAssets(): void {
		if ( ! $this->settings->isEnabled( 'enabled_comments' ) ) {
			return;
		}

		if ( ! is_singular() || ! comments_open() ) {
			return;
		}

		$pow_css_path = WPSH_DIR . 'assets/css/pow-client.css';
		$pow_js_path  = WPSH_DIR . 'assets/js/pow-client.js';
		$pow_worker_path = WPSH_DIR . 'assets/js/pow-worker.js';
		$pow_css_ver  = is_readable( $pow_css_path ) ? (string) filemtime( $pow_css_path ) : WPSH_VERSION;
		$pow_js_ver   = is_readable( $pow_js_path ) ? (string) filemtime( $pow_js_path ) : WPSH_VERSION;
		$pow_worker_ver = is_readable( $pow_worker_path ) ? (string) filemtime( $pow_worker_path ) : WPSH_VERSION;
		$pow_worker_url = (string) add_query_arg( 'ver', $pow_worker_ver, WPSH_URL . 'assets/js/pow-worker.js' );

		wp_enqueue_style( 'wpsh-pow-client', WPSH_URL . 'assets/css/pow-client.css', array(), $pow_css_ver );
		wp_enqueue_script( 'wpsh-pow-client', WPSH_URL . 'assets/js/pow-client.js', array(), $pow_js_ver, true );
		$language = UiLanguage::current( $this->settings );
		wp_localize_script(
			'wpsh-pow-client',
			'WPSH_CONFIG',
			array(
				'restUrl'           => esc_url_raw( rest_url( 'wpshield/v1/challenge' ) ),
				'restNonce'         => wp_create_nonce( 'wp_rest' ),
				'workerUrl'         => esc_url_raw( $pow_worker_url ),
				'showDebugUi'       => $this->settings->isEnabled( 'logging_enabled' ) || ( defined( 'WP_DEBUG' ) && WP_DEBUG ),
				'language'          => $language,
				'messages'          => UiLanguage::powMessages( $language ),
				'dynamicDomSupport' => false,
				'branding'          => array(
					'logoUrl' => esc_url_raw( $this->powLogoUrl() ),
				),
				'contexts'          => array(
					array(
						'ctx'      => 'comment',
						'selector' => 'form.comment-form, form#commentform, form[action*="wp-comments-post.php"]',
					),
				),
			)
		);
	}

	public function renderFields(): void {
		if ( ! $this->settings->isEnabled( 'enabled_comments' ) ) {
			return;
		}
		echo '<input type="hidden" name="wpsh_pow" value="" />';
		echo '<input type="hidden" name="wpsh_ctr" value="" />';
		echo '<input type="hidden" name="wpsh_hash" value="" />';
		$hp = $this->honeypotProfile( array( 'author', 'email', 'url', 'comment', 'comment_post_ID', 'comment_parent', 'submit' ) );
		echo '<input type="text" name="' . esc_attr( $hp['name'] ) . '" value="" autocomplete="new-password" autocapitalize="none" spellcheck="false" inputmode="none" aria-label="' . esc_attr( $hp['label'] ) . '" aria-hidden="true" placeholder="' . esc_attr( $hp['placeholder'] ) . '" data-required="1" style="position:absolute;left:-9999px;opacity:0;" tabindex="-1" />';
	}

	public function preprocessComment( array $comment_data ): array {
		if ( ! $this->settings->isEnabled( 'enabled_comments' ) ) {
			return $comment_data;
		}

		$result = $this->verifier->verify( 'comment', true );
		if ( is_wp_error( $result ) ) {
			wp_die( esc_html( $result->get_error_message() ), esc_html__( 'Blocked', 'proofshield' ), array( 'response' => 403 ) );
		}

		return $comment_data;
	}

	private function powLogoUrl(): string {

		foreach ( array( 'assets/images/proofshield-free.png', 'assets/images/logo-free.png', 'assets/images/logo.png', 'assets/images/proofshield-mark.png' ) as $relative ) {
			$absolute_path = WPSH_DIR . $relative;
			if ( is_readable( $absolute_path ) ) {
				$version = (string) filemtime( $absolute_path );
				return (string) add_query_arg( 'ver', $version, WPSH_URL . $relative );
			}
		}

		return '';
	}

	/**
	 * @param array<int,string> $reserved
	 * @return array{name:string,label:string,placeholder:string}
	 */
	private function honeypotProfile( array $reserved = array() ): array {

		$profiles    = array(
			array(
				'name'        => 'address_line2',
				'label'       => 'Address line 2',
				'placeholder' => 'Address line 2 *',
			),
			array(
				'name'        => 'contact_fax',
				'label'       => 'Fax number',
				'placeholder' => 'Fax number *',
			),
			array(
				'name'        => 'company_website',
				'label'       => 'Company website',
				'placeholder' => 'Company website *',
			),
			array(
				'name'        => 'middle_name',
				'label'       => 'Middle name',
				'placeholder' => 'Middle name *',
			),
			array(
				'name'        => 'secondary_phone',
				'label'       => 'Secondary phone',
				'placeholder' => 'Secondary phone *',
			),
			array(
				'name'        => 'vat_number',
				'label'       => 'VAT number',
				'placeholder' => 'VAT number *',
			),
			array(
				'name'        => 'department_code',
				'label'       => 'Department code',
				'placeholder' => 'Department code *',
			),
			array(
				'name'        => 'office_extension',
				'label'       => 'Office extension',
				'placeholder' => 'Office extension *',
			),
		);
		$reservedMap = array_fill_keys( array_map( 'strtolower', $reserved ), true );
		foreach ( $profiles as $profile ) {
			if ( ! isset( $reservedMap[ strtolower( (string) $profile['name'] ) ] ) ) {
				return $profile;
			}
		}

		return $profiles[0];
	}
}
