<?php
/**
 * Form Validation
 */

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! class_exists( 'OPL_Form_Validation' ) ) {

	class OPL_Form_Validation {

		/**
		 * The single instance of OPL_Form_Validation
		 *
		 * @var     object
		 * @access  private
		 */
		private static $_instance = null;

		/**
		 * Instance.
		 *
		 * @static
		 * @return OPL_Form_Validation - instance.
		 */
		public static function instance() {
			if ( is_null( self::$_instance ) ) {
				self::$_instance = new self();
			}
			return self::$_instance;
		}

		/**
		 * Constructor function.
		 *
		 * @access  public
		 * @return  void
		 */
		public function __construct() {
            $this->load_validation_setup();
        }

        public function load_validation_setup() {

            $form_validation_method = get_theme_mod( 'opl_popup_form_validation_method', opl_form_validation_default_value() );

            if ( 'google_recaptcha' === $form_validation_method ) {
                require_once OPL_PATH . 'includes/validation/google-recaptcha.php';
            } else if ( 'cloudflare_turnstile' === $form_validation_method ) {
                require_once OPL_PATH . 'includes/validation/cloudflare-turnstile.php';
            }
        }

        /**
         * Render validation
         */
        public static function should_render_validation($type) {
            return self::opl_is_form_validation_enabled() && get_theme_mod('opl_popup_form_validation_method', opl_form_validation_default_value()) === $type;
        }

        /**
		 * Check if form validation is enabled
		 *
		 * @return bool
         */
		public static function opl_is_form_validation_enabled() {

			$form_validation_enable = get_theme_mod( 'opl_popup_form_validation_method', opl_form_validation_default_value() );

			if ( !empty($form_validation_enable) ) {
				return true;
			} else {
				return false;
			}
		}

        /**
		 * Validates reCAPTCHA
		 *
		 * @since 1.1.0
		 * @access public
		 */
		public static function recaptcha_validate( $response, $remote_ip = '' ) {

			if ( empty( $remote_ip ) ) {
				$remote_ip = $_SERVER['REMOTE_ADDR'];
			}

			$response = wp_remote_post(
				'https://www.google.com/recaptcha/api/siteverify',
				array(
					'body' => array(
						'secret'   => 'v3' == get_option( 'owp_recaptcha_version' ) ? get_option( 'owp_recaptcha3_secret_key' ) : get_option( 'owp_recaptcha_secret_key' ),
						'response' => $response,
						'remoteip' => $remote_ip,
					),
				)
			);

			$response_code = wp_remote_retrieve_response_code( $response );
			$response_body = wp_remote_retrieve_body( $response );

			if ( 200 == $response_code ) {

				$result = json_decode( $response_body, true );

				if ( $result['success'] ) {
					return true;
				}

                $error_code = reset( $result['error-codes'] );
				return new WP_Error( $error_code, self::get_validation_error_message( $error_code, 'reCaptcha' ) );
			}

			return new WP_Error( 'recaptcha-not-reachable', 'Unable to reach the reCaptcha server.' );
		}

        public static function turnstile_validate( $response, $remote_ip = '' ) {

			if ( empty( $remote_ip ) ) {
				if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
					$remote_ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
				} else {
					$remote_ip = $_SERVER['REMOTE_ADDR'];
				}
			}

			$response = wp_remote_post(
				'https://challenges.cloudflare.com/turnstile/v0/siteverify',
				array(
					'body' => array(
						'secret'   => get_option( 'owp_turnstile_secret_key' ),
						'response' => $response,
						'remoteip' => $remote_ip,
					),
				)
			);

			$response_code = wp_remote_retrieve_response_code( $response );
			$response_body = wp_remote_retrieve_body( $response );

			if ( 200 == $response_code ) {

				$result = json_decode( $response_body, true );

				if ( $result['success'] ) {
					return true;
				}

                $error_code = reset( $result['error-codes'] );
				return new WP_Error( $error_code, self::get_validation_error_message( $error_code, 'Turnstile' ) );
			}

			return new WP_Error( 'bad-request', 'Unable to reach the Turnstile server.' );
		}

        public static function get_validation_error_message( $error_code, $type ) {
            switch ( $error_code ) {
                case 'missing-input-secret':
                case 'invalid-input-secret':
                    return sprintf( __( 'Invalid %s secret key.', 'ocean-popup-login' ), $type );
                case 'missing-input-response':
                case 'invalid-input-response':
                    return __( 'Please check the box to prove that you are not a robot.', 'ocean-popup-login' );
                case 'timeout-or-duplicate':
                    return __( 'The token has expired. Please reload the page and try again.', 'ocean-popup-login' );
                case 'bad-request':  // For Turnstile
                case 'recaptcha-not-reachable':  // For reCAPTCHA
                default:
                    return sprintf( __( 'Unable to reach the %s server.', 'ocean-popup-login' ), $type );
            }
        }

        public static function is_woocommerce_login_request() {

			$is_woo_login = false;

			if (class_exists( 'WooCommerce' )) {
				return $is_woo_login;
			}

			if (!function_exists('wc_get_var')) {
				return $is_woo_login;
			}

			$login_nonce = wc_get_var($_REQUEST['woocommerce-login-nonce'], wc_get_var($_REQUEST['_wpnonce'], ''));
			if ($login_nonce && wp_verify_nonce($login_nonce, 'woocommerce-login')) {
				$is_woo_login = true;
			}

			$lostpass_nonce = wc_get_var($_REQUEST['woocommerce-lost-password-nonce'], wc_get_var($_REQUEST['_wpnonce'], ''));
			if ($lostpass_nonce && wp_verify_nonce($lostpass_nonce, 'lost_password')) {
				$is_woo_login = true;
			}

			$resetpass_nonce = wc_get_var($_REQUEST['woocommerce-reset-password-nonce'], wc_get_var($_REQUEST['_wpnonce'], ''));
			if ($resetpass_nonce && wp_verify_nonce($resetpass_nonce, 'reset_password')) {
				$is_woo_login = true;
			}

			return apply_filters('opl_is_woocommerce_login_request', $is_woo_login);
		}

        public static function is_targeted_login_request() {

            $form_validation_method = get_theme_mod( 'opl_popup_form_validation_method', opl_form_validation_default_value() );

			$is_default_login_request = stripos($_SERVER["REQUEST_URI"], strrchr(wp_login_url(), '/')) !== false;
			$is_woocommerce_login_request = self::is_woocommerce_login_request();

            $validation_default_login = false;
            $validation_other_login   = false;
            $is_targeted = false;

            if ( 'google_recaptcha' === $form_validation_method ) {
                $validation_default_login = get_theme_mod('opl_popup_recaptcha_enable_on_default_login', false);
			    $validation_other_login   = get_theme_mod('opl_popup_recaptcha_enable_on_other_login_forms', false);
            } else if ( 'cloudflare_turnstile' === $form_validation_method ) {
                $validation_default_login = get_theme_mod('opl_popup_turnstile_enable_on_default_login', false);
			    $validation_other_login   = get_theme_mod('opl_popup_turnstile_enable_on_other_login_forms', false);
            }

			if ($is_default_login_request && $validation_default_login) {
				$is_targeted = true;
			}

			if ($is_woocommerce_login_request && $validation_other_login) {
				$is_targeted = true;
			}

			return apply_filters('opl_form_validation_targeted_login_request', $is_targeted);
		}
    }

	OPL_Form_Validation::instance();
}
