<?php
/**
* The Reports class.
*
* Used to define functions related with CartBounty API Connections
*
*
* @since      10.9
* @package    CartBounty Pro - Save and recover abandoned carts for WooCommerce
* @subpackage CartBounty Pro - Save and recover abandoned carts for WooCommerce/includes
* @author     Streamline.lv
*/
class CartBounty_Pro_API_Connector{

	/**
	 * Method for establishing API connections
	 *
	 * Uses wp_remote_request() and supports any provider by allowing custom headers,
	 * base paths, query params, and JSON bodies. Returns a consistent structure.
	 *
	 * @since    10.9
	 * @return   Array
	 * @param    string		$api_name				API name
	 * @param    array		$api_access				API access
	 * @param    string		$url_parameters			URL parameters
	 * @param    string		$request_type			Request type e.g. POST, GET
	 * @param    array		$data					Payload that should be sent
	 * @param	 integer	$timeout				Maximum time allowed for connection
	 * @param    array		$extra					Optional overrides:
	 *												- 'headers'   => array of extra headers
	 *												- 'as_array'  => bool, decode JSON as assoc array (default false = object)
	 */
	public function connect( $api_name, $api_access, $url_parameters, $request_type, $data = array(), $timeout = 20, $extra = array() ){
		$method   = strtoupper( $request_type );
		$base_url = isset( $api_access['api_url'] ) ? rtrim( $api_access['api_url'], '/' ) : '';
		$as_array = isset( $extra['as_array'] ) ? (bool) $extra['as_array'] : false;
		$headers = array(
			'Accept'		=> 'application/json',
			'Content-Type'	=> 'application/json',
		);
		$base_path = '';
		$decoded = null;
		$connector = '/';

		if( $api_name == 'activecampaign' ){
			$base_path = '/api/3';
			$headers['Api-Token'] = $api_access['api_key'];

		}elseif( $api_name == 'mailchimp' ){
			$headers['Authorization'] = 'Basic ' . base64_encode( 'user:' . $api_access['api_key'] );

		}elseif( $api_name == 'bulkgate' ){
			$data['application_token'] = $api_access['api_key'];
			$data['application_id'] = $api_access['api_id'];
			$data['application_product'] = 'cartbounty';
		
		}elseif( $api_name == 'getresponse' ){
			$headers['X-Auth-Token'] = 'api-key ' . $api_access['api_key'];
		
		}elseif ( $api_name === 'gtranslate' ){
			$url_parameters .= '&key=' . $api_access['api_key'];
			$connector = '?';
		}

		$url = $base_url . $base_path . $connector . ltrim( $url_parameters, '/' );		

		if( !empty( $extra['headers'] ) && is_array( $extra['headers'] ) ){
			$headers = array_merge( $headers, $extra['headers'] );
		}

		$args = array(
			'method'	=> $method,
			'timeout'	=> $timeout,
			'headers'	=> $headers,
		);

		if( $method === 'GET' ){

			if( !empty( $data ) ){
				$url = add_query_arg( $data, $url );
			}

		}else{

			if( !empty( $data ) ){

				if( $api_name === 'gtranslate' ){
					$args['body'] = $data;

				}else{
					$args['body'] = wp_json_encode( $data );
				}
			}
		}

		$response = wp_remote_request( $url, $args );
		$status_code = (int)wp_remote_retrieve_response_code( $response );
		$raw_body = wp_remote_retrieve_body( $response );

		if( is_string( $raw_body ) && $raw_body !== '' ){
			$decoded = json_decode( $raw_body, $as_array );
		}

		$result = array(
			'status_code'	=> $status_code,
			'response'		=> $decoded,
		);

		return $result;
	}

	/**
	 * Test the API credentials
	 *
	 * @since 	 10.9
	 * @param    string       $recovery				Recovery option
	 * @param    array		  $api_access			API access
	 * @param 	 object 	  $class_object         Class object that has provider-specific logger methods (e.g., $this)
	 * @return	 bool
	 */
	public function credentials_test( string $recovery, $api_access, $class_object ){
		$result = false;
		$timeout = 3;
		$settings = array(
			'getresponse' => array(
				'endpoint' => 'accounts',
				'method'   => 'GET',
				'data'     => array( 'perPage' => 1 ),
				'logger'   => 'log_gr_errors',
			),
			'activecampaign' => array(
				'endpoint' => 'users',
				'method'   => 'GET',
				'data'     => array( 'limit' => 1 ),
				'logger'   => 'log_ac_errors',
			),
			'mailchimp' => array(
				'endpoint' => 'ping',
				'method'   => 'GET',
				'data'     => array(),
				'logger'   => 'log_mc_errors',
			),
			'bulkgate' => array(
				'endpoint' => 'info',
				'method'   => 'POST',
				'data'     => array(),
				'logger'   => 'log_bkg_errors',
			),
		);

		$value = $settings[ $recovery ];
		$response = $this->connect( $recovery, $api_access, $value['endpoint'], $value['method'], $value['data'], $timeout );

		if( (int)$response['status_code'] == 200 ){ //Successful
			$result = true;

		}else{
			$class_object->{ $value['logger'] }( $response['response'] );
		}

		return $result;
	}
}