<?php
namespace KadencePatternHub\SureCart\Licensing\Custom;

/**
 * Custom SureCart License Client for Pattern Hub
 *
 * This class is necessary to set project data
 */
class Client {
	/**
	 * The client version
	 *
	 * @var string
	 */
	public $version = '1.0.1';

	/**
	 * The public token for the store.
	 *
	 * @example pt_jzieNYQdE5LMAxksscgU6H4
	 *
	 * @var string
	 */
	public $public_token;

	/**
	 * The Object of License Class
	 *
	 * @var object
	 */
	private $license;

	/**
	 * The endpoint for the licenses.
	 *
	 * @var string
	 */
	protected $license_endpoint = 'v1/public/licenses';

	/**
	 * Set value for valid licnese
	 *
	 * @var bool
	 */
	private $is_valid_license = null;

	/**
	 * The endpoint for the activations.
	 *
	 * @var string
	 */
	protected $activations_endpoint = 'v1/public/activations';

	/**
	 * Initialize the class
	 *
	 * @param string $public_token The public token for the store.
	 */
	public function __construct( $public_token ) {
		$this->public_token = $public_token;
	}
	/**
	 * Retrieve license information by key.
	 *
	 * @param string $license_key The license key.
	 *
	 * @return Object|\WP_Error
	 */
	public function retrieve( $license_key ) {
		$route = trailingslashit( $this->license_endpoint ) . $license_key;
		return $this->send_request( 'GET', $route );
	}
	/**
	 * Validate a license key.
	 *
	 * @param string  $key The license key.
	 * @return Object
	 */
	public function validate( $key ) {
		// get license.
		$license = $this->retrieve( sanitize_text_field( $key ) );
		if ( is_wp_error( $license ) ) {
			if ( 'not_found' === $license->get_error_code() ) {
				if ( apply_filters( 'kadence_cloud_surecart_license_debug', false ) ) {
					error_log( 'This is not a valid license key: ' . $key );
				}
				return false;
			}
			if ( apply_filters( 'kadence_cloud_surecart_license_debug', false ) ) {
				error_log( 'License Check Error: ' . $license->get_error_message() );
			}
			return false;
		}
		if ( empty( $license->id ) ) {
			if ( apply_filters( 'kadence_cloud_surecart_license_debug', false ) ) {
				error_log( 'This is not a valid license. Please double-check it and try again: ' . $key );
			}
			return false;
		}
		if ( 'revoked' === ( isset( $license->status ) ? $license->status : 'revoked' ) ) {
			if ( apply_filters( 'kadence_cloud_surecart_license_debug', false ) ) {
				error_log( 'This license has been revoked. Please re-purchase to obtain a new license: ' . $key );
			}
			return false;
		}

		return $license;
	}
	/**
	 * Check this is a valid license.
	 *
	 * @param string $license_key The license key.
	 *
	 * @return boolean|\WP_Error
	 */
	public function is_valid( $license, $product_id = '' ) {
/*
		Example:
		{
			"id": "71fb928f-0a4a-4a95-a3bb-fef2db51a4e9",
			"object": "license",
			"key": "32daf3fb-f585-4d79-8d72-a2d8de3740c3",
			"status": "inactive",
			"product": "23aeebfa-87a9-4792-bfab-8927be092e5b",
			"current_release": null,
			"created_at": 1673291158,
			"updated_at": 1673291158
		}
		*/
		// validate the license response.
		$is_valid_license = $this->validate_license( $license );
		if ( ! $is_valid_license ) {
			return false;
		}
		if ( isset( $license->product ) && $product_id === $license->product ) {
			return $license->id;
		}

		// return validity.
		return false;
	}
	/**
	 * Is this license active?
	 *
	 * @return boolean
	 */
	public function is_active( $license_id = '', $fingerprint = '', $name = '' ) {
		$activation = $this->create_activation( $license_id, $fingerprint, $name );

		if ( is_wp_error( $activation ) ) {
			return false;
		}

		return ! empty( $activation->id );
	}
	/**
	 * Create an activation for the license.
	 *
	 * @param string $license_id The license id.
	 *
	 * @return object|\WP_Error
	 */
	public function create_activation( $license_id, $fingerprint, $name ) {
		if ( empty( $license_id ) ) {
			return new \WP_Error( 'missing_key', $this->__( 'Please enter a license key' ) );
		}

		// send the activation request.
		$activation = $this->send_request(
			'POST',
			trailingslashit( $this->activations_endpoint ),
			array(
				'activation' => array(
					'fingerprint' => ! empty( $fingerprint ) ? $fingerprint : esc_url_raw( get_site_url() ),
					'name'        => ! empty( $name ) ? $name : get_bloginfo(),
					'license'     => $license_id,
				),
			)
		);

		// error.
		if ( is_wp_error( $activation ) ) {
			return $activation;
		}

		// no id.
		if ( empty( $activation->id ) ) {
			return new \WP_Error( 'could_not_activate', $this->__( 'Could not activate the license.' ) );
		}

		// return the activation.
		return $activation;
	}

	/**
	 * Validate the license response
	 *
	 * @param Object|\WP_Error $license The license response.
	 *
	 * @return \WP_Error|boolean
	 */
	public function validate_license( $license ) {
		if ( is_wp_error( $license ) ) {
			if ( $license->get_error_code( 'not_found' ) ) {
				return new \WP_Error( $license->get_error_code(), $this->__( 'This license key is not valid. Please double check it and try again.' ) );
			}
			return $license;
		}

		// if we have a key and the status is not revoked.
		if ( ! empty( $license->key ) && isset( $license->status ) && 'revoked' !== $license->status ) {
			return true;
		}

		return false;
	}
	/**
	 * API Endpoint
	 *
	 * @return string
	 */
	public function endpoint() {
		// allow a constant to be set.
		if ( defined( 'SURECART_LICENSING_ENDPOINT' ) ) {
			return trailingslashit( SURECART_LICENSING_ENDPOINT );
		}

		// filterable endpoint.
		return trailingslashit( apply_filters( 'surecart_licensing_endpoint', 'https://api.surecart.com' ) );
	}

	/**
	 * Send request to remote endpoint
	 *
	 * @param  array  $method The method for the request.
	 * @param  string $route The route.
	 * @param array  $body The body to send.
	 * @param bool   $blocking Is this a blocking request.
	 *
	 * @return array|WP_Error   Array of results including HTTP headers or WP_Error if the request failed.
	 */
	public function send_request( $method = 'POST', $route = '', $body = null, $blocking = true ) {
		$headers = array(
			'X-SURECART-WP-LICENSING-SDK-VERSION' => $this->version,
			'Accept'                              => 'application/json',
		);

		if ( ! empty( $this->public_token ) ) {
			$headers['Authorization'] = "Bearer $this->public_token";
		}

		$response = wp_remote_request(
			$this->endpoint() . $route,
			array(
				'headers'  => $headers,
				'method'   => $method,
				'timeout'  => 30,
				'blocking' => $blocking,
				'body'     => $body,
			)
		);

		if ( is_wp_error( $response ) ) {
			return $response;
		}

		$response_code = wp_remote_retrieve_response_code( $response );
		$response_body = json_decode( wp_remote_retrieve_body( $response ) );

		if ( ! in_array( $response_code, array( 200, 201 ), true ) ) {
			if ( 404 === $response_code ) {
				return new \WP_Error( 'not_found', $this->__( 'Not found' ) );
			}

			if ( ! empty( $response_body->code ) && ! empty( $response_body->message ) ) {
				return new \WP_Error( $response_body->code, esc_html( $response_body->message ) );
			}
			return new \WP_Error( 'error', $this->__( 'Unknown error occurred, Please try again.' ) );
		}

		return $response_body;
	}

	/**
	 * Check if the current server is localhost
	 *
	 * @return boolean
	 */
	public function is_local_server() {
		$is_local = in_array( $_SERVER['REMOTE_ADDR'], array( '127.0.0.1', '::1' ), true );
		return apply_filters( 'surecart_licensing_is_local', $is_local );
	}

	/**
	 * Translate function __()
	 *
	 * @param string $text The text string.
	 */
	public function __( $text ) {
		return call_user_func( '__', $text, 'kadence-cloud-surecart-license' );
	}
}
