<?php

namespace IconPress\IconFinder;

use Ink\Framework;


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

/**
 * Class Rest
 * @package IconPress\IconFinder
 */
class Rest
{
	/**
	 * Rest constructor.
	 */
	function __construct()
	{
		add_action( 'rest_api_init', [ $this, 'registerRoutes' ], 195 );
	}

	/**
	 * ICONFINDER ENDPOINTS
	 * These are wrapper endpoints for IconFinder's own endpoints.
	 */
	public static function registerRoutes()
	{
		register_rest_route( Base::ICONFINDER_ENDPOINT_NAMESPACE, '/iconsets', [
			[
				'methods' => \WP_REST_Server::READABLE,
				'callback' => [ get_class(), 'get__IconSets' ],
			]
		] );

		register_rest_route( Base::ICONFINDER_ENDPOINT_NAMESPACE, '/iconsets_icons', [
			[
				'methods' => \WP_REST_Server::READABLE,
				'callback' => [ get_class(), 'get__IconsetsIcons' ],
			]
		] );

		register_rest_route( Base::ICONFINDER_ENDPOINT_NAMESPACE, '/iconsets_icons/search', [
			[
				'methods' => \WP_REST_Server::READABLE,
				'callback' => [ get_class(), 'get__IconSearch' ],
				'args' => [
					'q' => [
						'validate_callback' => [ '\\IconPress\\Helpers\\Validator', 'notEmpty' ],
					],
				],
			]
		] );

		register_rest_route( Base::ICONFINDER_ENDPOINT_NAMESPACE, '/icons', [
			[
				'methods' => \WP_REST_Server::READABLE,
				'callback' => [ get_class(), 'get__IconDetails' ],
				'args' => [
					'id' => [
						'required' => true,
						'type' => 'integer',
						'sanitize_callback' => 'sanitize_text_field',
						'validate_callback' => 'rest_validate_request_arg',
					],
					'type' => [
						'required' => false,
						'type' => 'string',
						'sanitize_callback' => 'sanitize_text_field',
						'validate_callback' => 'rest_validate_request_arg',
					],
				],
			]
		] );
	}

	/**
	 * Get iconsets. Exits with json response on error
	 * @param \WP_REST_Request $wpr
	 * @return array
	 */
	public static function get__IconSets( $wpr )
	{
		$ifApi = Api::getInstance();
		if ( ! $ifApi->isConnected() ) {
			wp_send_json_error( __( "Please authorize the IconFinder application first.", 'iconpress' ) );
		}

		$params['vector'] = '1';
		// Count results
		$params['count'] = $wpr->get_param( 'count' ) ? intval( $wpr->get_param( 'count' ) ) : 10;
		// Premium
		$params['premium'] = self::__sanitizeParam( $wpr->get_param( 'premium' ) );
		// will receive and ID (numeric). The last collection's iconset_id or identifier.
		$params['after'] = $wpr->get_param( 'after' ) ? intval( $wpr->get_param( 'after' ) ) : '';

		$authInfo = \IconPress\Dashboard\Base::getAuthInfo();
		$url = 'https://customers.iconpress.io/index.php?ipif=' . base64_encode( json_encode( [
				'action' => 'iconsets',
				'api_key' => $authInfo['api_key'],
				'site_url' => trailingslashit( get_bloginfo( 'url' ) ),
				'params' => $params,
			] ) );

		$request = wp_remote_get( $url, [ 'timeout' => 25 ] );

		if ( is_wp_error( $request ) ) {
			wp_send_json_error( $request->get_error_messages() );
		}

		$data = wp_remote_retrieve_body( $request );
		$responseData = json_decode( $data, true );
		if ( is_scalar( $responseData ) || ! is_array( $responseData ) ) {
			wp_send_json_error( __( 'Invalid response from server.', 'iconpress' ) );
		}
		if ( isset( $responseData['message'] ) ) {
			wp_send_json_error( $responseData['message'] );
		}

		if ( isset( $responseData['iconsets'] ) ) {
			$count = $params['count'];
			$responseData['iconsets'] = array_map( function ( $iconset, $k ) use ( $count ) {
				// Recreate author object
				$author = $iconset['author'];
				unset( $iconset['author'] );
				$iconset['author_name'] = $author['name'];
				$iconset['author_url'] = "https://www.iconfinder.com/" . ( isset($author['username']) ? $author['username'] : '' );

				if ( $iconset['is_premium'] ) {
					if ( isset( $iconset['prices'][0]['license'] ) ) {
						$iconset['license_name'] = $iconset['prices'][0]['license']['name'];
						$iconset['license_url'] = $iconset['prices'][0]['license']['url'];
					}
				}
				elseif ( isset( $iconset['license'] ) ) {
					$iconset['license_name'] = $iconset['license']['name'];
					if ( isset( $iconset['license']['url'] ) ) {
						$iconset['license_url'] = $iconset['license']['url'];
					}
				}

				// some new styff
				$iconset['type'] = 'iconfinder';
				$iconset['is_last'] = false;

				// some cleanup
				unset( $iconset['categories'] );
				unset( $iconset['published_at'] );
				unset( $iconset['styles'] ); // we'll see in the future if this should be allowed

				if ( $k == ( $count - 1 ) ) {
					$iconset['is_last'] = true;
				}

				return $iconset;

			}, $responseData['iconsets'], array_keys( $responseData['iconsets'] ) );
		}
		return $responseData;
	}

	/**
	 * Get icons from iconset. Exits with json response on error
	 * @param \WP_REST_Request $wpr
	 * @return array
	 */
	public static function get__IconsetsIcons( $wpr )
	{
		$ifApi = Api::getInstance();
		if ( ! $ifApi->isConnected() ) {
			wp_send_json_error( __( "Please authorize the IconFinder application first.", 'iconpress' ) );
		}

		$collection_identifier = $wpr->get_param( 'collection_identifier' ) ? wp_strip_all_tags( $wpr->get_param( 'collection_identifier' ) ) : '';

		$params['count'] = $wpr->get_param( 'count' ) ? intval( $wpr->get_param( 'count' ) ) : 10;

		// will receive and ID (numeric). The last collection's iconset_id or identifier.
		$params['after'] = $wpr->get_param( 'after' ) ? intval( $wpr->get_param( 'after' ) ) : '';

		$authInfo = \IconPress\Dashboard\Base::getAuthInfo();
		$url = 'https://customers.iconpress.io/index.php?ipif=' . base64_encode( json_encode( [
				'action' => 'iconsets_icons',
				'api_key' => $authInfo['api_key'],
				'site_url' => trailingslashit( get_bloginfo( 'url' ) ),
				'collection_identifier' => $collection_identifier,
				'params' => $params,
			] ) );

		$request = wp_remote_get( $url, [ 'timeout' => 25 ] );

		if ( is_wp_error( $request ) ) {
			wp_send_json_error( $request->get_error_messages() );
		}

		$data = wp_remote_retrieve_body( $request );
		$responseData = json_decode( $data, true );
		if ( is_scalar( $responseData ) || ! is_array( $responseData ) ) {
			wp_send_json_error( __( 'Invalid response from server.', 'iconpress' ) );
		}
		if ( isset( $responseData['message'] ) ) {
			wp_send_json_error( $responseData['message'] );
		}
		return $responseData;
	}

	/**
	 * Retrieve the search results. Exits with json response on error
	 * @param \WP_REST_Request $wpr
	 * @return array
	 */
	public static function get__IconSearch( $wpr )
	{
		$ifApi = Api::getInstance();
		if ( ! $ifApi->isConnected() ) {
			wp_send_json_error( __( "Please authorize the IconFinder application first.", 'iconpress' ) );
		}

		// force vector
		$params['vector'] = '1';
		// premium
		$params['premium'] = self::__sanitizeParam( $wpr->get_param( 'premium' ) );
		// the query
		$params['query'] = wp_strip_all_tags( $wpr->get_param( 'q' ) );

		$params['count'] = $wpr->get_param( 'count' ) ? intval( $wpr->get_param( 'count' ) ) : 10;

		// will receive and ID (numeric). The last collection's iconset_id or identifier.
		$params['offset'] = $wpr->get_param( 'offset' ) ? intval( $wpr->get_param( 'offset' ) ) : '';

		$authInfo = \IconPress\Dashboard\Base::getAuthInfo();
		$url = 'https://customers.iconpress.io/index.php?ipif=' . base64_encode( json_encode( [
				'action' => 'search_icons',
				'api_key' => $authInfo['api_key'],
				'site_url' => trailingslashit( get_bloginfo( 'url' ) ),
				'params' => $params,
			] ) );

		$request = wp_remote_get( $url, [ 'timeout' => 25 ] );

		if ( is_wp_error( $request ) ) {
			wp_send_json_error( $request->get_error_messages() );
		}

		$data = wp_remote_retrieve_body( $request );
		$responseData = json_decode( $data, true );
		if ( is_scalar( $responseData ) || ! is_array( $responseData ) ) {
			wp_send_json_error( __( 'Invalid response from server.', 'iconpress' ) );
		}
		if ( isset( $responseData['message'] ) ) {
			wp_send_json_error( $responseData['message'] );
		}
		return $responseData;
	}

	/**
	 * @param \WP_REST_Request $wpr
	 */
	public static function get__IconDetails( $wpr )
	{
		if ( $wpr instanceof \WP_REST_Request ) {

			$ifApi = Api::getInstance();
			if ( ! $ifApi->isConnected() ) {
				wp_send_json_error( __( "Please authorize the IconFinder application first.", 'iconpress' ) );
			}

			$authInfo = \IconPress\Dashboard\Base::getAuthInfo();
			$url = 'https://customers.iconpress.io/index.php?ipif=' . base64_encode( json_encode( [
					'action' => 'icon_details',
					'api_key' => $authInfo['api_key'],
					'site_url' => trailingslashit( get_bloginfo( 'url' ) ),
					'icon_id' => (int)$wpr->get_param( 'id' ),
					'type' => wp_strip_all_tags( $wpr->get_param( 'type' ) ),
				] ) );

			$request = wp_remote_get( $url, [ 'timeout' => 25 ] );

			if ( is_wp_error( $request ) ) {
				wp_send_json_error( $request->get_error_messages() );
			}

			$data = wp_remote_retrieve_body( $request );
			$responseData = json_decode( $data, true );
			if ( is_scalar( $responseData ) || ! is_array( $responseData ) ) {
				wp_send_json_error( __( 'Invalid response from server.', 'iconpress' ) );
			}
			if ( isset( $responseData['message'] ) ) {
				wp_send_json_error( $responseData['message'] );
			}

			//#! Filtered result when $type is provided and is equal to "author_license"
			wp_send_json_success( $responseData );
		}
		wp_send_json_error( __( 'Sorry, invalid request.', 'iconpress' ) );
	}

	/**
	 * Retrieve user details from iconfinder
	 * @return array
	 */
	public static function iconfinder_getUserDetails()
	{
		$ifApi = Api::getInstance();
		$logger = Framework::getInstance( 'iconpress' )->getLogger();

		if ( $ifApi->isConnected() ) {

			$authInfo = \IconPress\Dashboard\Base::getAuthInfo();
			if( !isset($authInfo['api_key']) ) {
				return;
			}

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

			if ( is_wp_error( $request ) ) {
				$logger->write( __METHOD__ . '()', $request->get_error_message(), $logger::ERROR );
				return [];
			}

			$data = wp_remote_retrieve_body( $request );
			if ( empty( $data ) ) {
				$logger->write( __METHOD__ . '()', __( 'No data retrieved from server.', 'iconpress' ), $logger::ERROR );
				return [];
			}

			$responseData = json_decode( $data, true );
			if ( is_scalar( $responseData ) || ! is_array( $responseData ) ) {
				$logger->write( __METHOD__ . '()', __( 'Invalid response from server.', 'iconpress' ), $logger::ERROR );
				return [];
			}

			if ( isset( $responseData['message'] ) ) {
				$logger->write( __METHOD__ . '()', $responseData['message'], $logger::ERROR );
				return [];
			}

			set_transient( 'iconpress_iconfinder_user_details', $responseData, 24 * 3600 );

			return $responseData;
		}
		return [];
	}


	/**
	 * Sanitize special "premium" param
	 * @param string|int $param Possible values: "all", 0, 1
	 * @return int|string
	 */
	private static function __sanitizeParam( $param )
	{
		if ( $param == 'all' ) {
			return wp_strip_all_tags( $param );
		}
		else {
			return intval( $param );
		}
	}
}

//#! Initialize the class
new Rest();
