<?php
 
/**
 * =============================================================================
 * @package         Blue Raven (Free Version)
 * @Plugin URI      https://enterrahost.com/plugins/blue-raven
 * 
 * @Author          EnterraHost
 * @Author URI      https://enterrahost.com
 * @License         GPL-2.0-or-later
 *  
 * @Copyright       (c) 2025 EnterraHost
 * @Contents        Blue Raven Form Submission 
 *
 * =============================================================================
 * 
 * || INDEX:
 * ||   - SUBMIT BLUE RAVEN FORM
 * ||   - BOT VERIFICATION
 * ||   
 * =============================================================================
 */

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

/*
============================================================
    SUBMIT BLUE RAVEN FORM
============================================================
*/

function BlueRaven_submitForm($post_data){
    $raw_data = $post_data['form_data'];

    if (is_string($raw_data)) {
        parse_str($raw_data, $fields);
    } elseif (is_array($raw_data)) {
        $fields = $raw_data;
    } else {
        $fields = [];
    }
    
    $form_id = sanitize_text_field($post_data['form_id']);
    $siteName = get_bloginfo('name');
    $siteEmail = get_option('admin_email');
    
    // =========== Get Mail Details =========== //
       
    global $wpdb;

    $shortcode_key = 'blueRaven_Form id="' . esc_attr($form_id) . '"';
    $messages_table_name = $wpdb->prefix . 'BlueRavenMessages';

    // =========== Query the DB for the row with the matching shortcode string =========== //
    
    $table = esc_sql($messages_table_name);
    $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM `$table` WHERE shortcode = %s", $shortcode_key), ARRAY_A);
    if (!$row) return 'No Form found.';
    
    // =========== Message Response =========== //
        
    $messages_json = $row['messages'] ?? '{}';
    $messages_array = json_decode($messages_json, true);
    
    $success_message = (!empty($messages_array['success'])) ? $messages_array['success'] : 'Thank you for contacting us, We will get back to you as soon as possible.';
    $error_message   = (!empty($messages_array['error']))   ? $messages_array['error']   : 'Unfortunately your message failed to send, Please give us a call.';
    $bot_message     = (!empty($messages_array['bot']))     ? $messages_array['bot']     : 'Unfortunately your message didn’t pass our bot prevention measures.';
    $missing_message = (!empty($messages_array['missing'])) ? $messages_array['missing'] : 'Unfortunately your message is missing some required fields.';

    // =========== Missing Feilds =========== //
        
    $required_fields = $post_data['required_fields'] ?? [];
    $missing_fields = [];

    foreach ($required_fields as $field_key) {
        $value = isset($fields[$field_key]) ? $fields[$field_key] : null;

        if ($value === null || trim($value) === '') {
            $missing_fields[] = $field_key;
        }
    }

    if (!empty($missing_fields)) {
        wp_send_json_error($missing_message);
    }

    // =========== Bot Check =========== //
    
    $bot_config = json_decode($row['bot_prevention'] ?? '{}', true);
    $token = sanitize_text_field(wp_unslash($_POST['captcha_token'] ?? ''));
    if (!BlueRaven_handle_bot_verification($bot_config, $token)) {
        wp_send_json_error($bot_message);
    }
    
    // =========== Prepare values for frontend =========== //
    
    $email_to = !empty($row['email_to']) ? esc_attr($row['email_to']) : $siteEmail;
    $email_from = !empty($row['email_from']) ? esc_attr($row['email_from']) : $siteEmail;
    $subject = !empty($row['subject']) ? sanitize_text_field($row['subject']) : "New Message from $siteName";
    $template = $row['template'] ?? ''; $message;

    // =========== Build Message =========== //

    if (empty(trim($template))) {
        // Build message line by line (plain text)
        $message_lines = [];
        foreach ($fields as $key => $value) {
            $nice_key = ucwords(str_replace('_', ' ', $key));
            $message_lines[] = "{$nice_key}: " . trim($value);
        }
        $message = implode("\n", $message_lines);
    } else {
        // Replace placeholders in template
        foreach ($fields as $key => $value) {

            $template = str_replace('[' . $key . ']', trim($value), $template);
        }
        $message = $template;
    }

    // =========== Reply To =========== //
    
    $raw_reply_to = $row['reply_to'] ?? '';
    $reply_to = $raw_reply_to;
    if (preg_match('/\[(.*?)\]/', $raw_reply_to, $match)) {
        $field_key = $match[1];
        $reply_to = $fields[$field_key] ?? '';
    }

    // =========== Headers =========== //

    $headers = [
        'From: ' . $siteName . ' <' . $email_from . '>',
        'Reply-To: ' . $reply_to,
        'Content-Type: text/plain; charset=UTF-8'
    ];
    
    // =========== SEND =========== //
        
    if (wp_mail($email_to, $subject, $message, $headers)) {
        wp_send_json_success($success_message);
    } else {
        wp_send_json_error($error_message);
    }
}

/*
============================================================
   BOT VERIFICATION
============================================================
*/

function BlueRaven_handle_bot_verification($bot_config, $token) {
    $provider = $bot_config['provider'] ?? 'none';
    $site_key = $bot_config['site_key'] ?? '';
    $secret_key = $bot_config['secret_key'] ?? '';

    switch ($provider) {
        case 'recaptcha':
            return BlueRaven_verify_recaptcha($token, $secret_key);
        case 'hcaptcha':
            return BlueRaven_verify_hcaptcha($token, $secret_key);
        case 'turnstile':
            return BlueRaven_verify_turnstile($token, $secret_key);
        case 'friendlycaptcha':
            return BlueRaven_verify_friendlycaptcha($token, $secret_key);
        case 'none':
        default:
            return true;
    }
}
    
    ## =========== Cloudflare Turnstile =========== ##

function BlueRaven_verify_turnstile($token, $secret_key) {
    $response = wp_remote_post('https://challenges.cloudflare.com/turnstile/v0/siteverify', [
        'body' => [
            'secret'   => $secret_key,
            'response' => $token,
            'remoteip' => isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '',
        ]
    ]);
    return is_wp_error($response) ? false : !empty(json_decode(wp_remote_retrieve_body($response), true)['success']);
}

    ## =========== Google reCAPTCHA (v2/v3) =========== ##
    
function BlueRaven_verify_recaptcha($token, $secret_key) {
    if (empty($token) || empty($secret_key)) return false;
    $ip = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '';
    $res = wp_remote_post('https://www.google.com/recaptcha/api/siteverify', ['body' => ['secret' => $secret_key, 'response' => $token, 'remoteip' => $ip], 'timeout' => 10]);
    return is_wp_error($res) ? false : !empty(json_decode(wp_remote_retrieve_body($res), true)['success']);
}


    ## =========== hCaptcha =========== ##
    
function BlueRaven_verify_hcaptcha($token, $secret_key) {
    if (empty($token) || empty($secret_key)) return false;
    $ip = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '';
    $res = wp_remote_post('https://hcaptcha.com/siteverify', ['body' => ['secret' => $secret_key, 'response' => $token, 'remoteip' => $ip], 'timeout' => 10]);
    return is_wp_error($res) ? false : !empty(json_decode(wp_remote_retrieve_body($res), true)['success']);
}


    ## =========== Friendly Captcha =========== ##
    
function BlueRaven_verify_friendlycaptcha($token, $secret_key) {
    if (empty($token) || empty($secret_key)) return false;
    $response = wp_remote_post('https://api.friendlycaptcha.com/api/v1/siteverify', ['headers' => ['Content-Type' => 'application/json'], 'body' => json_encode(['secret' => $secret_key, 'solution' => $token]), 'timeout' => 10]);
    if (is_wp_error($response)) return false;
    $body = json_decode(wp_remote_retrieve_body($response), true);
    return !empty($body['success']);
}
