<?php

namespace PWH_DCFH\App\Frontend\Request;

use ET_Core_Data_Utils;

if (!defined('ABSPATH')) {
    exit;
}
if (!class_exists('PWH_DCFH_Post_Request')) {
    class PWH_DCFH_Post_Request
    {
        public $contact_form_num = 0;

        public $contact_form_data = [];

        public $temp_files;

        /**
         * Class Constructor
         *
         * @param bool $is_processed
         *
         * @since 1.0.0
         */
        public function __construct($is_processed = true)
        {
            global $et_pb_contact_form_num;
            $this->contact_form_num = $et_pb_contact_form_num;
            if ($is_processed) {
                $this->processed_contact_form_entries();
            }
            pwh_dcfh_email_merge_tags_handler()::fixed_tags_values();
        }

        /**
         * Check is Contact Form Processed
         * @return bool
         * @since 1.0.0
         */
        public function is_contact_form_processed()
        {
            $nonce_result = isset($_POST['_wpnonce-et-pb-contact-form-submitted-'.$this->contact_form_num]) && wp_verify_nonce(sanitize_text_field($_POST['_wpnonce-et-pb-contact-form-submitted-'.$this->contact_form_num]),
                    'et-pb-contact-form-submit');
            if ($nonce_result) {
                if (isset($_POST['et_pb_contactform_submit_'.$this->contact_form_num]) && 'et_contact_proccess' === sanitize_text_field($_POST['et_pb_contactform_submit_'.$this->contact_form_num])) {
                    return true;
                }
                if (isset($_POST['pwh_dcfh_et_pb_contactform_submit_'.$this->contact_form_num]) && 'et_contact_proccess' === sanitize_text_field($_POST['pwh_dcfh_et_pb_contactform_submit_'.$this->contact_form_num])) {
                    return true;
                }
            }

            return false;
        }

        /**
         * Check is Google Recaptcha V2 Success
         * @return bool
         */
        public function is_googlerecaptchav2_success()
        {
            global $et_pb_contact_form_num;
            $is_successed_response = true;
            if (isset($_POST["et_pb_contact_grecaptcha_token_$et_pb_contact_form_num"])) { // phpcs:ignore
                $response = wp_remote_post('https://www.google.com/recaptcha/api/siteverify', [
                    'body' => [
                        'secret' => et_get_option('pwh_dcfh_googlerecaptcha_v2_secretkey'),
                        'response' => sanitize_text_field($_POST["et_pb_contact_grecaptcha_token_$et_pb_contact_form_num"]), // phpcs:ignore
                    ],
                    'timeout' => '60',
                    'redirection' => '5',
                    'httpversion' => '1.0',
                    'blocking' => true,
                    'headers' => [],
                    'cookies' => [],
                ]);
                if (!is_wp_error($response)) {
                    $response_body = wp_remote_retrieve_body($response);
                    $response_code = wp_remote_retrieve_response_code($response);
                    if ($response_code === 200) {
                        $response_data = json_decode($response_body, true);
                        if (!$response_data['success']) {
                            $is_successed_response = false;
                        }
                    } else {
                        $is_successed_response = false;
                    }
                }
            }

            return $is_successed_response;
        }

        /**
         * Check is Cloudflare Turnstile Success
         * @return bool
         */
        public function is_cloudflare_turnstile_success()
        {
            global $et_pb_contact_form_num;
            $is_successed_response = true;
            if (isset($_POST["et_pb_contact_cturnstile_token_$et_pb_contact_form_num"]) && isset($_POST['cf-turnstile-response'])) { // phpcs:ignore
                $response = wp_remote_post('https://challenges.cloudflare.com/turnstile/v0/siteverify', [
                    'body' => [
                        'secret' => et_get_option('pwh_dcfh_turnstile_secretkey'),
                        'response' => sanitize_text_field($_POST['cf-turnstile-response']), // phpcs:ignore
                        'remoteip' => pwh_dcfh_helpers()::get_ip_address()
                    ],
                    'timeout' => '60',
                    'redirection' => '5',
                    'httpversion' => '1.0',
                    'blocking' => true,
                    'headers' => [],
                    'cookies' => [],
                ]);
                if (!is_wp_error($response)) {
                    $response_body = wp_remote_retrieve_body($response);
                    $response_code = wp_remote_retrieve_response_code($response);
                    if ($response_code === 200) {
                        $response_data = json_decode($response_body, true);
                        if (!$response_data['success']) {
                            $is_successed_response = false;
                        }
                    } else {
                        $is_successed_response = false;
                    }
                }
            }

            return $is_successed_response;
        }

        /**
         * Is Honeypot Filled?
         * @return bool
         */
        public function is_honeypot_filled()
        {
            global $et_pb_contact_form_num;
            if (isset($_POST['et_pb_contact_hp_field_'.$et_pb_contact_form_num]) && 'on' === sanitize_text_field($_POST['et_pb_contact_hp_field_'.$et_pb_contact_form_num])) { // phpcs:ignore WordPress.Security.NonceVerification
                return true;
            }

            return false;
        }

        /**
         * Get Referer URL
         * @return string
         * @since 1.1
         */
        public function get_referer_url()
        {
            return isset($_POST['et_pb_contact_field_referer_url']) ? sanitize_text_field($_POST['et_pb_contact_field_referer_url']) : ''; // phpcs:ignore WordPress.Security.NonceVerification
        }

        /**
         * Process Form Entries
         * @since 1.0.0
         */
        protected function processed_contact_form_entries()
        {
            static $form_processed = false;
            $form_raw_fields = [];
            $contact_emails = [];
            $hidden_form_fields = [];
            $process_fields_str = '';
            $sender_email = '';
            $contact_form_num = $this->contact_form_num;
            $nonce_result = isset($_POST['_wpnonce-et-pb-contact-form-submitted-'.$this->contact_form_num]) && wp_verify_nonce(sanitize_text_field($_POST['_wpnonce-et-pb-contact-form-submitted-'.$this->contact_form_num]),
                    'et-pb-contact-form-submit');
            if (!$form_processed && $nonce_result && isset($_POST['et_pb_contactform_submit_'.$contact_form_num]) && empty($_POST['et_pb_contact_et_number_'.$contact_form_num])) {
                $et_utils = ET_Core_Data_Utils::instance();
                $confirmation_request = PWH_DCFH_Confirmation_Email_Request::instance();
                $confirmation_email_field_id = $confirmation_request->confirmation_email_field_id;
                $post_repository = PWH_DCFH_Post_Repository::instance();
                list($y, $m) = pwh_dcfh_file_helpers()::get_subdir(); // phpcs:ignore
                $current_form_fields = isset($_POST["et_pb_contact_email_fields_$contact_form_num"]) ? sanitize_text_field($_POST["et_pb_contact_email_fields_$contact_form_num"]) : null;
                $fields_data_array = json_decode(str_replace('\\', '', $current_form_fields), true);
                $fields_data_array = $fields_data_array ?? [];
                $hidden_data_str = isset($_POST["et_pb_contact_email_hidden_fields_$contact_form_num"]) ? sanitize_text_field($_POST["et_pb_contact_email_hidden_fields_$contact_form_num"]) : null;
                if ($hidden_data_str !== null) {
                    $hidden_form_fields = json_decode(str_replace('\\', '', $hidden_data_str), true);
                    $hidden_form_fields = $hidden_form_fields ?? [];
                }
                if (!empty($fields_data_array)) {
                    if (!empty($hidden_form_fields)) {
                        foreach ($hidden_form_fields as $hidden_field) {
                            $hidden_field_id = 'et_pb_contact_'.$hidden_field.'_'.$contact_form_num;
                            $explode_hidden_label = isset($_POST[$hidden_field_id.'_field_label']) ? explode('|', sanitize_text_field($_POST[$hidden_field_id.'_field_label'])) : $hidden_field;
                            $form_raw_fields[] = [
                                'field_id' => $hidden_field_id,
                                'original_id' => $hidden_field,
                                'field_label' => !empty($explode_hidden_label[0]) ? trim($explode_hidden_label[0]) : '',
                                'field_type' => !empty($explode_hidden_label[1]) ? trim($explode_hidden_label[1]) : 'input',
                            ];
                        }
                    }
                    $form_raw_fields = array_merge($fields_data_array, $form_raw_fields);
                    // Save Query Parameters To Database
                    if ($post_repository->save_queryparams_to_db) {
                        $query_params = $this->get_query_params();
                        $form_raw_fields = array_merge($fields_data_array, $form_raw_fields, $query_params);
                        $fields_data_array = array_merge($fields_data_array, $query_params);
                        pwh_dcfh_db()::update_contact_form_query_params($post_repository->contact_form_id, $query_params);
                    }
                    foreach ($fields_data_array as $value) {
                        $original_field_name = pwh_dcfh_helpers()::sanitize_key($et_utils->array_get($value, 'original_id'));
                        $field_id = $et_utils->array_get($value, 'field_id');
                        $field_type = $et_utils->array_get($value, 'field_type', 'input');
                        $field_label = $et_utils->array_get($value, 'field_label');
                        if ('query' === $field_type) {
                            $field_value = stripslashes($value['value']);
                        } else {
                            $field_value = isset($_POST[$field_id]) ? stripslashes($_POST[$field_id]) : '';   // phpcs:ignore
                        }
                        $field_required = isset($value['required_mark']) ? trim($value['required_mark']) : '';
                        if (in_array($original_field_name, $hidden_form_fields) && isset($_POST["et_pb_contact_{$original_field_name}_$contact_form_num"])) {
                            $field_value = stripslashes($_POST["et_pb_contact_{$original_field_name}_$contact_form_num"]); // phpcs:ignore
                        }
                        if ('et_pb_html_field' !== $field_value) {
                            if ('text' === $field_type) {
                                $field_value = sanitize_textarea_field($field_value);
                            } elseif (is_email($field_value)) {
                                $field_value = sanitize_email($field_value);
                                if (!empty($confirmation_email_field_id) && strtolower($confirmation_email_field_id) === $original_field_name) {
                                    $contact_emails['high_priority_emails'][] = [
                                        'value' => $field_value,
                                        'reqired' => $field_required,
                                    ];
                                }
                                if ('email' === $field_type && 'required' === $field_required) {
                                    $contact_emails['medium_priority_emails'][] = [
                                        'value' => $field_value,
                                        'reqired' => $field_required,
                                    ];
                                } elseif ('required' === $field_required || 'not_required' === $field_required) {
                                    $contact_emails['low_priority_emails'][] = [
                                        'value' => $field_value,
                                        'reqired' => $field_required,
                                    ];
                                }
                            } elseif (isset($_POST[$field_id.'_is_file'])) {
                                $field_type = 'file';
                                $this->temp_files[$original_field_name] = $field_value;
                            } elseif (isset($_POST[$field_id.'_is_signature_pad'])) {
                                $field_type = 'signature_pad';
                                $this->temp_files[$original_field_name] = $field_value;
                            } else {
                                $field_value = sanitize_text_field($field_value);
                            }
                            // If an input type is file and save to database true save files
                            if (('file' === $field_type || 'signature_pad' === $field_type) && $post_repository->save_files_to_db) {
                                $this->contact_form_data[] = [
                                    'id' => $original_field_name,
                                    'label' => $field_label,
                                    'value' => $field_value,
                                    'type' => $field_type,
                                    'subdir' => "$y/$m",
                                    'is_media_library' => (bool)$post_repository->save_files_to_media,
                                ];
                            } // If an input type is not file and save to a database false save
                            elseif ('file' !== $field_type) {
                                $this->contact_form_data[] = [
                                    'id' => $original_field_name,
                                    'label' => $field_label,
                                    'value' => $field_value,
                                    'type' => $field_type
                                ];
                            }
                            $process_fields_str .= $original_field_name.',';
                        }
                    }
                    if (isset($contact_emails['high_priority_emails'])) {
                        $contact_emails = reset($contact_emails['high_priority_emails']);
                        $sender_email = $contact_emails['value'];
                    } elseif (isset($contact_emails['medium_priority_emails'])) {
                        $contact_emails = reset($contact_emails['medium_priority_emails']);
                        $sender_email = $contact_emails['value'];
                    } elseif (isset($contact_emails['low_priority_emails'])) {
                        $contact_emails = reset($contact_emails['low_priority_emails']);
                        $sender_email = $contact_emails['value'];
                    } elseif (preg_match("/\bdcfh_site_userinfo_email\b/", $confirmation_email_field_id) && is_user_logged_in()) {
                        $user_data = wp_get_current_user();
                        if ($user_data) {
                            $sender_email = $user_data->user_email;
                        }
                    }
                    $post_repository->contact_form_data = $this->contact_form_data;
                    $post_repository->contact_form_fields_str = substr($process_fields_str, 0, -1);
                    $post_repository->contact_form_fields = $form_raw_fields;
                    $post_repository->sender_email = $sender_email;
                }
                $form_processed = true;
            }
        }

        /**
         * Get Attachments From Temp Directory
         * @return array
         * @since 1.0.0
         */
        public function get_files_from_temp_dir()
        {
            $attachments = [];
            $tmp_files = $this->temp_files;
            if (!empty($tmp_files)) {
                $upload_tmp_dir = pwh_dcfh_file_helpers()::get_tmp_upload_dir();
                $wp_upload_dir = wp_upload_dir();
                $post_repository = PWH_DCFH_Post_Repository::instance();
                foreach ($tmp_files as $tmp_file) {
                    $files = explode(',', $tmp_file);
                    if (!empty($files) && is_array($files)) {
                        foreach ($files as $file) {
                            $file_temp_dir = path_join($upload_tmp_dir, $file);
                            if (et_()->WPFS()->is_file($file_temp_dir) && et_()->WPFS()->exists($file_temp_dir)) {
                                $attachments['uploaded_dir'][] = $file_temp_dir;
                                if ($post_repository->save_files_to_media) {
                                    $attachments['uploaded_urls'][] = path_join($wp_upload_dir['url'], $file);
                                } else {
                                    $form_upload_dir = pwh_dcfh_file_helpers()::upload_files_to_dir($post_repository->contact_form_id, $file);
                                    $attachments['uploaded_urls'][] = $form_upload_dir['baseurl'];
                                }
                            }
                        }
                    }
                }
            }

            return $attachments;
        }

        /**
         * Move Attachments To Directory
         * @return array
         * @since 1.0.0
         */
        public function move_files_to_form_dir()
        {
            $attachments = [];
            $tmp_files = $this->temp_files;
            if (!empty($tmp_files)) {
                $post_repository = PWH_DCFH_Post_Repository::instance();
                $upload_tmp_dir = pwh_dcfh_file_helpers()::get_tmp_upload_dir();
                foreach ($tmp_files as $tmp_file) {
                    $files = explode(',', $tmp_file);
                    if (!empty($files) && is_array($files)) {
                        foreach ($files as $file_index => $file) {
                            $upload_dir = pwh_dcfh_file_helpers()::upload_files_to_dir($post_repository->contact_form_id, $file);
                            $file_temp_dir = path_join($upload_tmp_dir, $file);
                            if (et_()->WPFS()->is_file($file_temp_dir) && et_()->WPFS()->exists($file_temp_dir)) {
                                if (copy($file_temp_dir, $upload_dir['basedir'])) {
                                    $attachments['basedir'][$file_index] = $upload_dir['basedir'];
                                    $attachments['baseurl'][$file_index] = $upload_dir['baseurl'];
                                }
                            }
                        }
                    }
                }
            }

            return $attachments;

        }

        /**
         * Copy Files To Media Library
         *
         * @param $entry_number
         *
         * @return array
         */
        public function move_files_to_media_library($entry_number)
        {
            $attachments = [];
            $tmp_files = $this->temp_files;
            if (!empty($tmp_files)) {
                require_once(ABSPATH.'wp-admin/includes/image.php');
                require_once(ABSPATH.'wp-admin/includes/media.php');
                $file_title = __('Divi Contact Form Helper', 'pwh-dcfh');
                $upload_tmp_dir = pwh_dcfh_file_helpers()::get_tmp_upload_dir();
                $wp_upload_dir = wp_upload_dir();
                foreach ($tmp_files as $tmp_file) {
                    $files = explode(',', $tmp_file);
                    if (!empty($files) && is_array($files)) {
                        foreach ($files as $file_index => $file) {
                            $file_temp_dir = path_join($upload_tmp_dir, $file);
                            $file_upload_dir = path_join($wp_upload_dir['path'], $file);
                            $file_upload_url = path_join($wp_upload_dir['url'], $file);
                            $file_upload_path = path_join($wp_upload_dir['path'], $file);
                            $filename = pathinfo($file_temp_dir, PATHINFO_FILENAME);
                            $file_type = wp_check_filetype($file);
                            if (et_()->WPFS()->is_file($file_temp_dir) && et_()->WPFS()->exists($file_temp_dir)) {
                                if (copy($file_temp_dir, $file_upload_dir)) {
                                    $attachment_data = [
                                        'post_title' => $filename,
                                        'post_name' => $filename,
                                        'post_content' => $file_title,
                                        'post_excerpt' => $file_title,
                                        'post_mime_type' => $file_type['type'],
                                        'post_parent' => $entry_number,
                                        'guid' => $file_upload_url,
                                        'post_author' => 0,
                                        'post_status' => 'inherit',
                                        'comment_status' => 'closed',
                                        'ping_status' => 'closed'
                                    ];
                                    $attachment_id = wp_insert_attachment($attachment_data, $file_upload_path, $entry_number, true);
                                    if (!is_wp_error($attachment_id)) {
                                        $attach_data = wp_generate_attachment_metadata($attachment_id, $file_upload_path);
                                        wp_update_attachment_metadata($attachment_id, $attach_data);
                                        update_post_meta($attachment_id, '_wp_attachment_image_alt', $file_title);
                                        $attachments['basedir'][$file_index] = $file_upload_path;
                                        $attachments['baseurl'][$file_index] = $file_upload_url;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return $attachments;
        }

        /**
         * Get Query Parameters
         * @return array
         * @since 1.5
         */
        public function get_query_params()
        {
            $data = [];
            $query_string = isset($_SERVER['QUERY_STRING']) ? sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING'])) : '';
            if (!empty($query_string)) {
                $query_params = explode('&', $query_string);
                foreach ($query_params as $query_param) {
                    list($key, $value) = array_map('urldecode', explode('=', $query_param, 2));
                    $id = pwh_dcfh_helpers()::sanitize_key($key);
                    $label = pwh_dcfh_helpers()::sanitize_string($id);
                    $data[] = [
                        'field_id' => $id,
                        'original_id' => $id,
                        'id' => $id,
                        'field_label' => $label,
                        'label' => $label,
                        'value' => $value,
                        'type' => 'query',
                        'field_type' => 'query',
                    ];
                }
            }

            return $data;
        }

        /**
         * Post-Form Data To Endpoint
         * @return void
         */
        public function post_payload_endpoint()
        {
            $post_repository = PWH_DCFH_Post_Repository::instance();
            $endpoint_url = $post_repository->post_payload_endpoint;
            $contact_form_id = $post_repository->contact_form_id;
            if (!empty($endpoint_url) && !empty($contact_form_id)) {
                $raw_data = $_POST; // phpcs:ignore WordPress.Security.NonceVerification
                $processed_data = $this->contact_form_data;
                $entry_number = $post_repository->entry_number;
                $attachments = $post_repository->attachments['baseurl'] ?? [];
                $referer_url = $this->get_referer_url();
                $response = wp_remote_request($endpoint_url, [
                    'method' => 'POST',
                    'body' => [
                        'contact_form_id' => $contact_form_id,
                        'entry_number' => $entry_number,
                        'processed_data' => $processed_data,
                        'attachments' => $attachments,
                        'referer_url' => $referer_url,
                        'ip_address' => pwh_dcfh_helpers()::get_ip_address(),
                        'user_agent' => pwh_dcfh_helpers()::get_user_agent(),
                        'raw_data' => $raw_data,
                    ],
                    'headers' => [
                        'Content-Type' => 'application/x-www-form-urlencoded',
                        'Authorization' => 'Basic '.$contact_form_id,
                        'Token' => 'Bearer '.$contact_form_id,
                    ],
                ]);
                if (is_wp_error($response)) {
                    $response->get_error_message();
                } else {
                    wp_remote_retrieve_body($response);
                }
            }
        }
    }
}