<?php

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

$cf7sr_hc_key    = get_option( 'cf7sr_hc_key' );
$cf7sr_hc_secret = get_option( 'cf7sr_hc_secret' );

if ( empty( $cf7sr_hc_key ) || empty( $cf7sr_hc_secret ) || is_admin() ) {
    return;
}

function enqueue_cf7sr_hcaptcha_script() {
    global $cf7sr_hcaptcha_on;
    if ( ! $cf7sr_hcaptcha_on ) {
        return;
    }
    $cf7sr_script_url = 'https://js.hcaptcha.com/1/api.js?onload=cf7srLoadHcaptcha&render=explicit';
    $language = get_option( 'cf7sr_hc_language' );
    if ( ! empty( $language ) && ! empty( CF7SR_LANGUAGES[ $language ] ) ) {
        $cf7sr_script_url .= '&hl=' . $language;
    }
    $cf7sr_hc_key = get_option( 'cf7sr_hc_key' );
    ?>
    <script type="text/javascript">
        var hcaptchaIds = [];

        var cf7srLoadHcaptcha = function() {
            var widgets = document.querySelectorAll('.cf7sr-g-hcaptcha');
            for (var i = 0; i < widgets.length; ++i) {
                var widget = widgets[i];
                hcaptchaIds.push(
                    hcaptcha.render(widget.id, {
                        'sitekey' : <?php echo wp_json_encode( $cf7sr_hc_key ); ?>
                    })
                );
            }
        };

        function cf7srResetHcaptcha() {
            for (var i = 0; i < hcaptchaIds.length; i++) {
                hcaptcha.reset(hcaptchaIds[i]);
            }
        }

        document.querySelectorAll('.wpcf7').forEach(function(element) {
            element.addEventListener('wpcf7invalid', cf7srResetHcaptcha);
            element.addEventListener('wpcf7mailsent', cf7srResetHcaptcha);
            element.addEventListener('invalid.wpcf7', cf7srResetHcaptcha);
            element.addEventListener('mailsent.wpcf7', cf7srResetHcaptcha);
        });
    </script>
    <script src="<?php echo esc_url( $cf7sr_script_url ); ?>" async defer></script>
    <?php
}
add_action( 'wp_footer', 'enqueue_cf7sr_hcaptcha_script' );

function cf7sr_hcaptcha_wpcf7_form_elements( $form ) {
    $form = do_shortcode( $form );
    return $form;
}
add_filter( 'wpcf7_form_elements', 'cf7sr_hcaptcha_wpcf7_form_elements' );

function cf7sr_hcaptcha_shortcode( $atts ) {
    global $cf7sr_hcaptcha_on;
    $cf7sr_hcaptcha_on       = true;
    $cf7sr_hc_key   = get_option( 'cf7sr_hc_key' );
    $cf7sr_theme = ! empty( $atts['theme'] ) && 'dark' == $atts['theme'] ? 'dark' : 'light';
    $cf7sr_size  = ! empty( $atts['size'] ) && 'compact' == $atts['size'] ? 'compact' : 'normal';

    $cf7sr_id       = 'cf7sr-' . uniqid();

    return '<div id="' . $cf7sr_id . '" class="cf7sr-g-hcaptcha" data-theme="' . esc_attr( $cf7sr_theme ) . '" data-size="' . esc_attr( $cf7sr_size ) . '" data-sitekey="' . esc_attr( $cf7sr_hc_key )
        . '"></div><span class="wpcf7-form-control-wrap cf7sr-hcaptcha" data-name="cf7sr-hcaptcha"><input type="hidden" name="cf7sr-hcaptcha" value="" class="wpcf7-form-control"></span>';
}
add_shortcode( 'cf7sr-hcaptcha', 'cf7sr_hcaptcha_shortcode' );

function cf7sr_verify_hcaptcha( $result, $tags ) {
    if ( ! class_exists( 'WPCF7_Submission' ) ) {
        return $result;
    }

    $_wpcf7 = ! empty( $_POST['_wpcf7'] ) ? absint( $_POST['_wpcf7'] ) : 0;
    if ( empty( $_wpcf7 ) ) {
        return $result;
    }

    $submission = WPCF7_Submission::get_instance();
    $data       = $submission->get_posted_data();

    $cf7_text  = do_shortcode( '[contact-form-7 id="' . $_wpcf7 . '"]' );
    $cf7sr_hc_key = get_option( 'cf7sr_hc_key' );
    if ( false === strpos( $cf7_text, $cf7sr_hc_key ) ) {
        return $result;
    }

    $message = get_option( 'cf7sr_hc_message' );
    if ( empty( $message ) ) {
        $message = 'Invalid captcha';
    }

    if (empty( $data['h-captcha-response'])) {
        $result->invalidate(
            array(
                'type' => 'captcha',
                'name' => 'cf7sr-hcaptcha',
            ),
            $message
        );
        return $result;
    }

    $cf7sr_hc_secret = get_option( 'cf7sr_hc_secret' );
    $url          = 'https://api.hcaptcha.com/siteverify?secret=' . $cf7sr_hc_secret . '&response=' . $data['h-captcha-response'];
    $request      = wp_remote_get( $url );
    $body         = wp_remote_retrieve_body( $request );
    $response     = json_decode( $body );
    if ( ! ( isset( $response->success ) && 1 == $response->success ) ) {
        $result->invalidate(
            array(
                'type' => 'captcha',
                'name' => 'cf7sr-hcaptcha',
            ),
            $message
        );
    }

    return $result;
}
add_filter( 'wpcf7_validate', 'cf7sr_verify_hcaptcha', 30, 2 );
