<?php

namespace SugarCalendarBookings\Antispam\Captcha;

/**
 * Cloudflare Turnstile verifier.
 *
 * @since 1.5.0
 */
final class Turnstile extends AbstractCaptchaVerifier {

	public const CATEGORY                = 'turnstile';
	public const ENDPOINT_URL            = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
	public const SECRET_OPTION_KEY       = 'antispam.turnstile.secret_key';
	public const SECRET_FILTER_NAME      = 'sugar_calendar_bookings_antispam_turnstile_secret_key';
	public const SITE_KEY_OPTION_KEY     = 'antispam.turnstile.site_key';
	public const THEME_OPTION_KEY        = 'antispam.turnstile.theme';
	public const FAIL_MESSAGE_OPTION_KEY = 'antispam.turnstile.fail_message';

	public const SCRIPT_HANDLE  = 'scbookings-booking-form-turnstile';
	public const SCRIPT_API_URL = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
	public const CONFLICT_HOSTS = [
		'challenges.cloudflare.com/turnstile',
	];

	/**
	 * Detect Cloudflare's test-key response via the explicit metadata flag.
	 *
	 * Turnstile's test-key responses echo `hostname: "example.com"`, but
	 * `example.com` is an RFC 2606 reserved-for-documentation domain that
	 * Cloudflare does not claim ownership of as a test-key sentinel — a
	 * site legitimately hosted on it could match. `metadata.result_with_testing_key`
	 * is Cloudflare's documented, explicit signal and is set if and only if a
	 * test key was used, so we read it instead of the echoed hostname.
	 *
	 * That is why `TEST_KEY_HOSTNAME` is intentionally not declared on this
	 * class — see the constant's docblock on AbstractCaptchaVerifier for the
	 * two acceptable shapes.
	 *
	 * @since 1.5.0
	 *
	 * @param object $decoded Decoded JSON response.
	 *
	 * @return bool
	 */
	protected function is_test_key_response( object $decoded ): bool {

		return ! empty( $decoded->metadata->result_with_testing_key );
	}

	/**
	 * Frontend config for the localized booking-form payload.
	 *
	 * @since 1.5.0
	 *
	 * @return array
	 */
	public function get_frontend_config(): array {

		return [
			'site_key' => $this->get_site_key(),
			'theme'    => $this->get_theme(),
		];
	}

	/**
	 * Default fail message for Turnstile.
	 *
	 * @since 1.5.0
	 *
	 * @return string
	 */
	public function get_fail_message_default(): string {

		return esc_html__( 'Cloudflare Turnstile verification failed, please try again later.', 'sugar-calendar-bookings-scheduling-appointments-lite' );
	}
}
