<?php

namespace IconPress\IconFinder;

use IconPress\Base;
use Ink\Notices\UserNotice;

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

//#! Initialize the class
$ifApi = Api::getInstance();

//#! Cleanup if not connected
//#! @see \IconPress\Dashboard\Base::checkStatus()
add_action( 'iconpress/dashboard/not-connected', [ $ifApi, 'cleanup' ] );


/**
 * Class IconFinderApi
 * @package IconPressPro\Integrations
 */
class Api
{
	/**
	 * Holds the reference to the instance of this class
	 * @var null|\IconPress\IconFinder\Api
	 */
	private static $_instance = null;

	const NONCE_ACTION = 'iconfinder_authorize';
	const NONCE_NAME = 'iconfinder_pro_nonce';
	private $_nonce = '';

//<editor-fold desc=":: SINGLETON ::">
	private function __construct()
	{
		//#! Check the IconFinder API response for authorization code
		add_action( 'init', [ $this, 'checkResponseAuthorizationCode' ] );
		add_action( 'wp_ajax_disconnect_if_api', [ $this, 'ajax_disconnect' ] );
	}

	/**
	 * Retrieve the reference to the instance of this class
	 * @return Api|null
	 */
	public static function getInstance()
	{
		if ( empty( self::$_instance ) || ! ( self::$_instance instanceof self ) ) {
			self::$_instance = new self;
		}
		return self::$_instance;
	}

//</editor-fold desc=":: SINGLETON ::">

	/**
	 * Remove stored options
	 * @param bool $hideNotices
	 */
	public function cleanup( $hideNotices = false )
	{
		$authInfo = \IconPress\Dashboard\Base::getAuthInfo();
		if ( empty( $authInfo ) || ! $authInfo['connected'] || empty( $authInfo['api_key'] ) ) {
			return;
		}

		$url = 'https://customers.iconpress.io/index.php?ipif=' . base64_encode( json_encode( [
				'action' => 'deauthorize',
				'api_key' => $authInfo['api_key'],
				'site_url' => trailingslashit( get_bloginfo( 'url' ) ),
				//#! Always the integrations page
				'redirect' => add_query_arg( [ 'page' => Base::PLUGIN_SLUG . '_integrations' ], admin_url( 'admin.php' ) ),
			] ) );
		$request = wp_remote_get( $url );

		if ( is_wp_error( $request ) ) {
			UserNotice::add( '<strong>[IconFinder API]</strong> ' . $request->get_error_message(), UserNotice::TYPE_ERROR, false );
			return;
		}

		$response = wp_remote_retrieve_body( $request );

		if ( empty( $response ) ) {
			if ( ! $hideNotices ) {
				UserNotice::add( '<strong>[IconFinder API]</strong> ' . __( 'No response from server.', 'iconpress' ), UserNotice::TYPE_ERROR, false );
			}
			return;
		}

		$responseData = json_decode( $response, true );
		if ( ! is_array( $responseData ) || ! isset( $responseData['success'] ) ) {
			if ( ! $hideNotices ) {
				UserNotice::add( '<strong>[IconFinder API]</strong> ' . __( 'Invalid response from server.', 'iconpress' ), UserNotice::TYPE_ERROR, false );
			}
			return;
		}

		$options = get_option( 'iconpress_iconfinder' );
		$options['access_token'] = '';
		update_option( 'iconpress_iconfinder', $options );
		delete_transient( 'iconpress_iconfinder_user_details' );
	}

	/**
	 * Check to see whether or not the user has been authenticated
	 * @return bool
	 */
	public function isConnected()
	{
		$options = get_option( 'iconpress_iconfinder' );
		return ( isset( $options['access_token'] ) && ! empty( $options['access_token'] ) );
	}

	/**
	 * Disconnect from IconFinder API
	 */
	public function ajax_disconnect()
	{
		if ( 'POST' != strtoupper( $_SERVER['REQUEST_METHOD'] ) ) {
			wp_send_json_error( __( 'Invalid Request.', 'iconpress' ) );
		}
		if ( ! isset( $_POST[self::NONCE_NAME] ) || ! wp_verify_nonce( $_POST[self::NONCE_NAME], self::NONCE_ACTION ) ) {
			wp_send_json_error( __( 'Invalid nonce.', 'iconpress' ) );
		}
		if ( ! isset( $_POST['disconnect_if_api'] ) ) {
			wp_send_json_error( __( 'Invalid Request.', 'iconpress' ) );
		}
		if ( $_POST['disconnect_if_api'] ) {
			$this->cleanup();
			wp_send_json_success( __( 'Disconnected', 'iconpress' ) );
		}
		wp_send_json_error( __( 'Invalid Request.', 'iconpress' ) );
	}

	/**
	 * Authorize the Application
	 * @return string
	 */
	public function getAuthorizeLink()
	{
		$authInfo = \IconPress\Dashboard\Base::getAuthInfo();
		if ( empty( $authInfo ) || ! $authInfo['connected'] || empty( $authInfo['api_key'] ) ) {
			return '#';
		}

		return 'https://customers.iconpress.io/iconfinder-authorize-client?ipif=' . base64_encode( json_encode( [
				'action' => 'authorize',
				'response_type' => 'code',
				'scope' => 'user,purchased',
				'state' => wp_create_nonce( self::NONCE_ACTION ),
				'api_key' => $authInfo['api_key'],
				'site_url' => trailingslashit( get_bloginfo( 'url' ) ),
				//#! Always the integrations page
				'redirect' => add_query_arg( [ 'page' => Base::PLUGIN_SLUG . '_integrations' ], admin_url( 'admin.php' ) ),
			] ) );
	}

	/**
	 * Retrieve the link to deauthorize the application
	 * @return string
	 */
	public function getDeauthorizeLink()
	{
		$authInfo = \IconPress\Dashboard\Base::getAuthInfo();
		if ( empty( $authInfo ) || ! $authInfo['connected'] || empty( $authInfo['api_key'] ) ) {
			return '#';
		}

		return 'https://customers.iconpress.io/index?ipif=' . base64_encode( json_encode( [
				'action' => 'deauthorize',
				'api_key' => $authInfo['api_key'],
				'site_url' => trailingslashit( get_bloginfo( 'url' ) ),
				//#! Always the integrations page
				'redirect' => add_query_arg( [ 'page' => Base::PLUGIN_SLUG . '_integrations' ], admin_url( 'admin.php' ) ),
			] ) );
	}

	/**
	 * Retrieve the authorization code and request an access token.
	 * Save data to db
	 * Redirect to plugin's Add Icons page
	 */
	public function checkResponseAuthorizationCode()
	{
		//#! Ensure the state is the same as the one we've sent
		$state = ( isset( $_REQUEST['state'] ) ? sanitize_text_field( $_REQUEST['state'] ) : '' );
		if ( ! empty( $state ) && wp_verify_nonce( $state, self::NONCE_ACTION ) ) {
			//#! Get access token
			$accessToken = $this->requestAccessToken();
			if ( ! empty( $accessToken ) ) {
				//#! Set the access token
				$optData = get_option( 'iconpress_iconfinder', [] );
				$optData['access_token'] = $accessToken;
				update_option( 'iconpress_iconfinder', $optData );
			}

			//#! Redirect to the plugin's page
			$url = add_query_arg( [ 'page' => \IconPress\Base::PLUGIN_SLUG . '_integrations' ], admin_url( 'admin.php' ) );
			wp_redirect( $url );
			exit;
		}
	}

	/**
	 * Request an access token based on the provided $code
	 * @return bool|mixed
	 */
	public function requestAccessToken()
	{
		$authInfo = \IconPress\Dashboard\Base::getAuthInfo();

		$url = 'https://customers.iconpress.io/index.php?ipif=' . base64_encode( json_encode( [
				'action' => 'access_token',
				'api_key' => $authInfo['api_key'],
				'site_url' => trailingslashit( get_bloginfo( 'url' ) ),
			] ) );

		$request = wp_remote_get( $url );
		if ( is_wp_error( $request ) ) {
			UserNotice::add( '<strong>[IconFinder API]</strong> ' . $request->get_error_message(), UserNotice::TYPE_ERROR, false );
			return false;
		}

		$response = wp_remote_retrieve_body( $request );

		if ( empty( $response ) ) {
			UserNotice::add( '<strong>[IconFinder API]</strong> ' . __( 'No response from server.', 'iconpress' ), UserNotice::TYPE_ERROR, false );
			return false;
		}

		$responseData = json_decode( $response, true );
		if ( ! is_array( $responseData ) || ! isset( $responseData['access_token'] ) ) {
			UserNotice::add( '<strong>[IconFinder API]</strong> ' . __( 'Invalid response from server.', 'iconpress' ), UserNotice::TYPE_ERROR, false );
			return false;
		}

		return $responseData['access_token'];
	}
}
