<?php
/**
 * This file handles all the AJAX requests and produces response accordingly.
 *
 * @package object-data-sync-for-salesforce\Handler
 */

namespace MoSfSyncSalesforce\Handler;

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

use MoSfSyncSalesforce\API\Salesforce;
use MoSfSyncSalesforce\Customer;
use MoSfSyncSalesforce\Helper\Plugin_Constants;
use MoSfSyncSalesforce\Helper\Instance;
use MoSfSyncSalesforce\Services\Utils;

/**
 * This class provides all the functionalities to handle the various AJAX requests.
 */
class Ajax_Handler {
	use Instance;

	/**
	 * Instance of Salesforce class.
	 *
	 * @var Salesforce
	 */
	private $salesforce;

	/**
	 * Instance of Object_Sync_Sf_To_Wp class.
	 *
	 * @var Object_Sync_Sf_To_Wp
	 */
	private $object_sync_sf_to_wp;

	/**
	 * Creates instance of the class.
	 *
	 * @return __CLASS__
	 */
	public static function instance() {
		if ( is_null( self::$instance ) ) {
			self::$instance                       = new self();
			self::$instance->salesforce           = new Salesforce();
			self::$instance->object_sync_sf_to_wp = new Object_Sync_Sf_To_Wp();
		}
		return self::$instance;
	}

	/**
	 * Function that handles all AJAX request & sends response.
	 *
	 * @return void
	 */
	public function mo_sf_sync_set_settings() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( 'You do not have sufficient permissions to perform this action.' );
			exit;
		}

		if ( isset( $_POST['_wpnonce'] ) ) {

			if ( isset( $_POST['integration_trial_request'] ) && check_ajax_referer( 'mo_sf_sync_ajax_submit' ) ) {
				set_transient( 'mo_sf_sync_integration_trial_notice_dismiss_time', true, 604800 );
				wp_send_json_success( true );
			}

			if ( isset( $_POST['trial_request'] ) && check_ajax_referer( 'mo_sf_sync_ajax_submit' ) ) {
				set_transient( 'mo_sf_sync_normal_trial_notice_dismiss_time', true, 604800 );
				wp_send_json_success( true );
			}

			if ( isset( $_POST['object'] ) && check_ajax_referer( 'mo_sf_sync_ajax_submit' ) ) {
				$res = $this->salesforce->mo_sf_sync_get_fields( sanitize_text_field( wp_unslash( $_POST['object'] ) ) );
				if ( in_array( $res, Plugin_Constants::SALESFORCE_AUTH_ERROR_MESSAGES, true ) ) {
					wp_send_json_error( array( 'error_description' => $res ) );
				}
				if ( is_wp_error( $res ) ) {
					wp_send_json_error( implode( ', ', $res->get_error_messages() ) );
				} else {
					wp_send_json_success( $res );
				}
			}

			if ( isset( $_POST['wp_object'] ) && check_ajax_referer( 'mo_sf_sync_ajax_submit' ) ) {
				$wp_object = sanitize_text_field( wp_unslash( $_POST['wp_object'] ) );

				$wp_object_fields      = $this->object_sync_sf_to_wp->mo_sf_sync_get_wp_obj_fields( $wp_object );
				$wp_object_fields_keys = array();

				foreach ( $wp_object_fields as $key => $value ) {
					$wp_object_fields_keys[] = $value['key'];
				}

				if ( is_wp_error( $wp_object_fields ) ) {
					wp_send_json( implode( ',', $wp_object_fields->get_error_messages() ) );
				} else {
					wp_send_json_success( $wp_object_fields_keys );
				}
			}

			if ( isset( $_POST['query'] ) && check_ajax_referer( 'mo_sf_sync_ajax_submit' ) ) {
				$users = new \WP_User_Query(
					array(
						'search'         => '*' . sanitize_text_field( wp_unslash( $_POST['query'] ) ) . '*',
						'search_columns' => array(
							'user_login',
							'user_nicename',
							'user_email',
							'user_url',
						),
						'number'         => 10,
					)
				);
				$users = $users->get_results();
				wp_send_json_success( $users );
			}
		}

		if ( ! isset( $_POST['option'] ) || ! isset( $_POST['_wpnonce'] ) || ! isset( $_POST['tab'] ) ) {
			wp_send_json_error( 'Invalid Request' );
		}

		$option = sanitize_text_field( wp_unslash( $_POST['option'] ) );
		check_ajax_referer( $option );
		$this->mo_sf_sync_handle_ajax_request( $option );
	}

	/**
	 * Routes AJAX requests to their appropriate handler functions based on the option parameter.
	 *
	 * @param string $option The AJAX action option from $_POST to be processed.
	 *
	 * @return void
	 */
	private function mo_sf_sync_handle_ajax_request( $option ) {
		switch ( $option ) {
			case 'mo_sf_sync_contact_us_query_option':
				$map = array();
				
				// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification done in mo_sf_sync_set_settings function.
				if ( isset( $_POST['data'] ) ) {
					// phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- Nonce verification done in mo_sf_sync_set_settings function,sanitization and unslash are done using custom function.
					$map = Utils::mo_sf_sync_sanitize_and_index( $_POST['data'] );
				}
				
				$this->mo_sf_sync_get_support( $map );
				break;
		}
	}

	/**
	 * Function that handles the authorization flow through manual app or a pre-connected app.
	 *
	 * @param array $postdata The $_POST data array containing the input field values.
	 * @return void
	 */
	public function mo_sf_sync_handle_config_object_save( $postdata ) {
		if ( ! isset( $postdata['client_id'] ) || empty( $postdata['client_id'] ) ) {
			$data['env_link']              = esc_url_raw( $postdata['env_link'] );
			$data['env_select']            = sanitize_text_field( $postdata['env_select'] );
			$data['app_type']              = 'preconnected';
			if ( empty( $data['env_link'] ) ) {
				Utils::mo_sf_sync_show_error_message( 'Save Unsuccessful because no Environment selected' );
			}
			set_transient( Plugin_Constants::TRANSIENT_CONFIG_OBJECT, $data );
			Utils::mo_sf_sync_save_settings( Plugin_Constants::CONFIG_OBJECT, $data );
			Utils::mo_sf_sync_show_success_message( 'Selected Environment Saved Successfully !' );
		} else {
			$data['env_link']              = esc_url_raw( $postdata['env_link'] );
			$data['env_select']            = sanitize_text_field( $postdata['env_select'] );
			$data['client_id']             = sanitize_text_field( $postdata['client_id'] );
			$data['client_secret']         = sanitize_text_field( $postdata['client_secret'] );
			$data['client_secret']         = Authorization_Handler::mo_sf_sync_encrypt_data( $data['client_secret'], hash( 'sha256', $data['client_id'] ) );
			$data['redirect_uri']          = esc_url_raw( $postdata['redirect_uri'] );
			$data['app_type']              = 'manual';
			set_transient( Plugin_Constants::TRANSIENT_CONFIG_OBJECT, $data );
			Utils::mo_sf_sync_save_settings( Plugin_Constants::CONFIG_OBJECT, $data );
			delete_option( Plugin_Constants::CONNECTION_TYPE );
			Utils::mo_sf_sync_show_success_message( 'Configuration Saved Successfully !' );
		}
	}

	/**
	 * Function that handles the feature request/contact us form.
	 *
	 * @param array $map The map of the data received from the form.
	 * @return void
	 */
	public function mo_sf_sync_get_support( $map ) {
		$email = isset( $map['mo_sf_sync_contact_us_email'] ) ? $map['mo_sf_sync_contact_us_email'] : '';
		$query = isset( $map['mo_sf_sync_contact_us_query'] ) ? $map['mo_sf_sync_contact_us_query'] : '';
		if ( empty( $email ) || empty( $query ) ) {
			wp_send_json_error( 'Empty email or query' );
		} else {
			$support  = new Customer();
			$response = $support->mo_sf_sync_submit_contact_us( $email, '', $query, false );
			if ( 'Query submitted.' === $response ) {
				wp_send_json_success( $response );
			} else {
				wp_send_json_error( $response );
			}
		}
	}
}
