<?php

class STM_Theme_Downloads {

	protected static $download_error;

	protected static function get_freemius_provider() {
		$providers = array(
			'consulting' => array(
				'is_build_callback'   => 'consulting_is_freemius_build',
				'is_active_callback'  => 'consulting_freemius_license_is_active',
				'fs_callback'         => 'consulting_fs',
				'allowed_prefixes'    => array( 'consulting/' ),
			),
			'motors'     => array(
				'is_build_callback'   => 'motors_is_freemius_build',
				'is_active_callback'  => 'motors_freemius_license_is_active',
				'fs_callback'         => 'motors_fs',
				'allowed_prefixes'    => array( 'motors/' ),
			),
		);

		$current_theme = '';

		if ( defined( 'STM_THEME_SLUG' ) ) {
			$current_theme = strtolower( (string) STM_THEME_SLUG );
		}

		if ( ! empty( $current_theme ) && isset( $providers[ $current_theme ] ) ) {
			$preferred = array( $current_theme => $providers[ $current_theme ] );
			unset( $providers[ $current_theme ] );
			$providers = array_merge( $preferred, $providers );
		}

		foreach ( $providers as $provider ) {
			if (
				empty( $provider['is_build_callback'] ) ||
				empty( $provider['is_active_callback'] ) ||
				empty( $provider['fs_callback'] ) ||
				! function_exists( $provider['is_build_callback'] ) ||
				! function_exists( $provider['is_active_callback'] ) ||
				! function_exists( $provider['fs_callback'] )
			) {
				continue;
			}

			$is_build  = call_user_func( $provider['is_build_callback'] );
			$is_active = call_user_func( $provider['is_active_callback'] );

			if ( $is_build && $is_active ) {
				return $provider;
			}
		}

		return false;
	}

	public static function init() {
		add_filter( 'upgrader_package_options', [ self::class, 'stm_upgrader_package_options' ] );
		add_filter( 'upgrader_pre_download', [ self::class, 'stm_upgrader_pre_download' ], 10, 2 );
	}

	public static function api_request( $method, $path, $options = [] ) {
		$options = wp_parse_args( $options, [
			'token' => STM_Theme_Info::get_activation_token(),
		] );
		$res = wp_remote_request( STM_LICENSE_API_URL . '/' . ltrim( $path, '/' ), [
			'method' => $method,
			'headers' => [
				'Accept' => 'application/json',
				'Authorization' => 'Bearer ' . $options['token'],
				'X-Wordpress-Site' => get_site_url(),
				'X-Stylemix-Item' => get_template(),
			],
		] );

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

		$code   = wp_remote_retrieve_response_code( $res );
		$return = json_decode( wp_remote_retrieve_body( $res ), true );

		if ( 200 !== $code ) {
			$message = ! empty( $return['message'] )
				? $return['message']
				: "HTTP error occurred with status: $code and no message from server.";
			return new WP_Error( 'http_error', $message );
		}

		return $return;
	}

	public static function stm_upgrader_package_options( $options ) {
		// this is not our case
		if ( ! isset( $options['package'] ) || strpos( $options['package'], 'downloads://' ) !== 0 ) {
			return $options;
		}

		$cdn_base = 'https://dl.gpltimes.com/file/gpltimes/masterstudy';
		$file     = str_replace( 'downloads://', '', $options['package'] );

		
		if ( strpos( $file, 'masterstudy/demos/' ) === 0 ) {
			$options['package'] = $cdn_base . '/demos/' . basename( $file );
			return $options;
		}

		$slug               = preg_replace( '/-[\d.]+$/', '', basename( $file, '.zip' ) );
		$options['package'] = $cdn_base . '/plugins/' . $slug . '.zip';

		return $options;
	}

	protected static function can_use_freemius_downloads( $file ) {
		$provider = self::get_freemius_provider();

		return ! empty( $provider ) && self::is_freemius_file_allowed( $file, $provider );
	}

	protected static function is_freemius_file_allowed( $file, $provider = false ) {
		if ( false !== strpos( $file, '..' ) || 0 === strpos( $file, '/' ) ) {
			return false;
		}

		if ( ! preg_match( '/^[a-z0-9_\-\/.]+\.zip$/i', $file ) ) {
			return false;
		}

		$allowed_prefixes = array(
			'revslider/',
			'js_composer/',
		);

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

		foreach ( $allowed_prefixes as $prefix ) {
			if ( 0 === strpos( $file, $prefix ) ) {
				return true;
			}
		}

		return false;
	}

	protected static function resolve_freemius_download_url( $file ) {
		$provider    = self::get_freemius_provider();
		$credentials = self::get_freemius_credentials( $provider );

		if ( is_wp_error( $credentials ) ) {
			self::$download_error = $credentials;
			return '';
		}

		$res = wp_remote_get( add_query_arg( 'file', $file, STM_LICENSE_API_URL . '/freemius-download-url' ), [
			'headers' => array_merge(
				array(
					'Accept'           => 'application/json',
					'X-Wordpress-Site' => get_site_url(),
					'X-Stylemix-Item'  => get_template(),
				),
				$credentials
			),
		] );

		if ( is_wp_error( $res ) ) {
			self::$download_error = $res;
			return '';
		}

		$code = wp_remote_retrieve_response_code( $res );
		$body = wp_remote_retrieve_body( $res );

		if ( 200 === $code ) {
			return $body;
		}

		$json = json_decode( $body, true );

		self::$download_error = new WP_Error(
			$code,
			! empty( $json['message'] ) ? $json['message'] : "HTTP error occurred with status: $code and no message while resolving Freemius download URL."
		);

		return '';
	}

	protected static function get_freemius_credentials( $provider = false ) {
		if ( empty( $provider ) ) {
			$provider = self::get_freemius_provider();
		}

		if ( empty( $provider ) || empty( $provider['fs_callback'] ) || ! function_exists( $provider['fs_callback'] ) ) {
			return new WP_Error( 'freemius_not_loaded', 'Freemius is not loaded.' );
		}

		$fs      = call_user_func( $provider['fs_callback'] );
		$site    = method_exists( $fs, 'get_site' ) ? $fs->get_site() : null;
		$license = method_exists( $fs, '_get_license' ) ? $fs->_get_license() : null;

		if ( ! is_object( $site ) || empty( $site->id ) || empty( $site->public_key ) || empty( $site->secret_key ) ) {
			return new WP_Error( 'freemius_install_missing', 'Freemius install data is missing.' );
		}

		if ( ! is_object( $license ) || empty( $license->id ) || empty( $license->secret_key ) ) {
			return new WP_Error( 'freemius_license_missing', 'Freemius license data is missing.' );
		}

		return array(
			'X-Freemius-Install-ID'         => $site->id,
			'X-Freemius-Install-Public-Key' => $site->public_key,
			'X-Freemius-Install-Secret-Key' => $site->secret_key,
			'X-Freemius-License-ID'         => $license->id,
			'X-Freemius-License-Secret-Key' => $license->secret_key,
		);
	}

	public static function stm_upgrader_pre_download( $res, $package ) {
		if ( is_wp_error( self::$download_error ) ) {
			$error = self::$download_error;
			self::$download_error = null;

			return $error;
		}

		return $res;
	}

}
