<?php
/**
 * This class is responsible manage all jupiter templates
 * it will communicate with artbees API and get list of templates , install them or remove them.
 *
 * @author       Artbees <info@artbees.net>
 * @copyright    Artbees LTD (c)
 *
 * @link         http://artbees.net
 * @since        1.0
 * @version      1.0
 */

class JupiterX_Control_Panel_Install_Template {


	private $layer_slider_slug = 'layerslider';

	private $theme_name;

	public function setThemeName( $theme_name ) {
		$this->theme_name = $theme_name;
	}

	public function getThemeName() {
		return $this->theme_name;
	}

	private $api_url;

	public function setApiURL( $api_url ) {
		$this->api_url = $api_url;
	}

	public function getApiURL() {
		return $this->api_url;
	}

	private $template_id;

	public function setTemplateID( $template_id ) {
		$this->template_id = $template_id;
	}

	public function getTemplateID() {
		return intval( $this->template_id );
	}

	private $template_name;

	public function setTemplateName( $template_name ) {
		$this->template_name = $template_name;
	}

	public function getTemplateName() {
		return strtolower( $this->template_name );
	}

	private $template_file_name;

	public function setTemplateFileName( $template_file_name ) {
		$this->template_file_name = $template_file_name;
	}

	public function getTemplateFileName() {
		return $this->template_file_name;
	}

	private $template_remote_address;

	public function setTemplateRemoteAddress( $template_remote_address ) {
		$this->template_remote_address = $template_remote_address;
	}

	public function getTemplateRemoteAddress() {
		return $this->template_remote_address;
	}

	private $template_content_file_name;

	public function setTemplateContentFileName( $template_content_file_name ) {
		$this->template_content_file_name = $template_content_file_name;
	}

	public function getTemplateContentFileName() {
		return $this->template_content_file_name;
	}

	private $widget_file_name;

	public function setWidgetFileName( $widget_file_name ) {
		$this->widget_file_name = $widget_file_name;
	}

	public function getWidgetFileName() {
		return $this->widget_file_name;
	}

	/**
	 * Settings filename.
	 *
	 * @since 1.0
	 * @var string
	 */
	private $settings_file_name;

	/**
	 * Set Settings filename.
	 *
	 * @since 1.0
	 * @param string $settings_file_name Settings filename.
	 */
	public function set_settings_file_name( $settings_file_name ) {
		$this->settings_file_name = $settings_file_name;
	}

	/**
	 * Get Settings filename.
	 *
	 * @since 1.0
	 * @return string Settings filename.
	 */
	public function get_settings_file_name() {
		return $this->settings_file_name;
	}

	private $upload_dir;

	public function setUploadDir( $upload_dir ) {
		$this->upload_dir = $upload_dir;
	}

	public function getUploadDir() {
		return $this->upload_dir;
	}

	private $base_path;

	public function setBasePath( $base_path ) {
		$this->base_path = $base_path;
	}

	public function getBasePath() {
		return $this->base_path;
	}

	private $base_url;

	public function setBaseUrl( $base_url ) {
		$this->base_url = $base_url;
	}

	public function getBaseUrl() {
		return $this->base_url;
	}

	private $message;

	public function setMessage( $message ) {
		$this->message = $message;
	}

	public function getMessage() {
		return $this->message;
	}

	private $system_test_env;

	public function setSystemTestEnv( $system_test_env ) {
		$this->system_test_env = $system_test_env;
	}

	public function getSystemTestEnv() {
		return $this->system_test_env;
	}

	private $ajax_mode;

	public function setAjaxMode( $ajax_mode ) {
		$this->ajax_mode = $ajax_mode;
	}

	public function getAjaxMode() {
		return $this->ajax_mode;
	}
	/**
	 * Construct.
	 * it will add_actions if class created on ajax mode.
	 *
	 * @param bool $system_text_env if you want to create an instance of this method for phpunit it should be true
	 * @param bool $ajax_mode       if you need this method as ajax mode set true
	 */
	public function __construct( $system_test_env = false, $ajax_mode = true ) {
		$menu_items_access = get_site_option( 'menu_items' );

		if ( is_multisite() && ! isset( $menu_items_access['plugins'] ) && ! current_user_can( 'manage_network_plugins' ) ) {
			return;
		}

		@set_time_limit( 0 );

		$this->setThemeName( 'jupiterx' );
		$this->setSystemTestEnv( $system_test_env );
		$this->setAjaxMode( $ajax_mode );

		$this->setApiURL( 'http://artbees.net/api/v2/' );

		$this->setUploadDir( wp_upload_dir() );
		$this->setBasePath( $this->getUploadDir()['basedir'] . '/jupiterx_templates/' );
		$this->setBaseUrl( $this->getUploadDir()['baseurl'] . '/jupiterx_templates/' );

		$this->setTemplateContentFileName( 'theme_content.xml' );
		$this->setWidgetFileName( 'widget_data.wie' );
		$this->set_settings_file_name( 'settings.json' );
		global $wpdb;

		if ( ! defined( 'JupiterX_LOAD_IMPORTERS' ) ) {
			define( 'JupiterX_LOAD_IMPORTERS', true );
		}

		if ( $this->getAjaxMode() == true ) {
			add_action( 'wp_ajax_abb_template_lazy_load', array( &$this, 'loadTemplatesFromApi' ) );
			add_action( 'wp_ajax_abb_install_template_procedure', array( &$this, 'install_template_procedure' ) );

			// Action only for importing theme content with Server-Sent Event.
			add_action( 'wp_ajax_abb_install_template_sse', array( &$this, 'import_theme_content_sse' ) );

			add_action( 'wp_ajax_abb_get_templates_categories', array( &$this, 'getTemplateCategoryListFromApi' ) );
			add_action( 'wp_ajax_abb_restore_latest_db', array( &$this, 'restoreLatestDB' ) );
			add_action( 'wp_ajax_abb_is_restore_db', array( &$this, 'isRestoreDB' ) );

			add_action( 'wp_ajax_abb_uninstall_template', array( &$this, 'uninstallTemplate' ) );
			add_action( 'wp_ajax_abb_get_template_psd_link', array( &$this, 'get_template_psd_link' ) );
		}
	}
	public function install_template_procedure() {
		$template_id = (isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : 0);
		$this->setTemplateID( $template_id );
		$template_name = (isset( $_POST['template_name'] ) ? $_POST['template_name'] : null);
		$import_media  = (isset( $_POST['import_media'] ) ? $_POST['import_media'] : false);
		$type          = (isset( $_POST['type'] ) ? $_POST['type'] : null);
		if ( is_null( $template_name ) || is_null( $type ) ) {
			$this->message( 'System problem at installing , please contact support', false );
			return false;
		}

		switch ( $type ) {
			case 'preparation':
				$this->preparation( $template_name );
				break;
			case 'backup_db':
				$this->backupDB();
				break;
			case 'backup_media_records':
				$this->backup_media_records();
				break;
			case 'restore_media_records':
				$this->restore_media_records();
				break;
			case 'reset_db':
				$this->resetDB();
				break;
			case 'upload':
				$this->uploadTemplateToServer( $template_name );
				break;
			case 'unzip':
				$this->unzipTemplateInServer( $template_name );
				break;
			case 'validate':
				$this->validateTemplateFiles( $template_name );
				break;
			case 'plugin':
				$this->installRequiredPlugins( $template_name );
				break;
			case 'theme_content':
				$this->importThemeContent( $template_name, $import_media );
				break;
			case 'setup_pages':
				$this->setUpPages( $template_name );
				break;
			case 'plugins_content':
				$this->import_plugins_content( $template_name );
				break;
			case 'settings':
				$this->import_settings( $template_name );
				break;
			case 'menu_locations':
				$this->importMenuLocations( $template_name );
				break;
			case 'theme_widget':
				$this->importThemeWidgets( $template_name );
				break;
			case 'finalize':
				$this->finalizeImporting( $template_name );
				break;
		}
	}
	public function reinitializeData( $template_name ) {
		try {
			if ( empty( $template_name ) ) {
				throw new Exception( 'Choose template first' );
			}
			$this->setTemplateName( $template_name );
			if (
				file_exists( $this->getAssetsAddress( 'template_content_path', $this->getTemplateName() ) ) == false ||
				file_exists( $this->getAssetsAddress( 'widget_path', $this->getTemplateName() ) ) == false ||
				file_exists( $this->getAssetsAddress( 'settings_path', $this->getTemplateName() ) ) == false
			) {
				throw new Exception( "Some template assets are missing Template Name : $template_name, Contact support." );
			} else {
				return true;
			}
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}
	}

	/**
	 * Reinitilize Template file is exist or not for SEE request.
	 *
	 * @since 1.0
	 *
	 * @throws Exception If template name empty.
	 * @throws Exception If template file is not exist.
	 *
	 * @param  string $template_name The template name will be imported.
	 * @param  string $template_id   The template ID will be imported.
	 * @return boolean               File status.
	 */
	public function reinitialize_data_sse( $template_name, $template_id ) {
		try {

			// Check template name and ID.
			if ( empty( $template_name ) || empty( $template_id ) ) {
				throw new Exception( 'Choose template first!' );
			}

			$this->setTemplateName( $template_name );
			$this->setTemplateID( $template_id );

			// Check template file exist or not.
			if ( false === file_exists( $this->getAssetsAddress( 'template_content_path', $this->getTemplateName() ) ) ) {
				throw new Exception( 'Template content does not exist - Contact support.' );
			}

			return true;
		} catch ( Exception $e ) {
			$this->message_sse( $e->getMessage(), true );
			exit;
		}
	}

	/**
	 * Method that is resposible to pass plugin list to UI base on lazy load condition.
	 *
	 * @param str $_POST[from]  from number.
	 * @param str $_POST[count] how many.
	 *
	 * @return bool will return boolean status of action , all message is setted to $this->message()
	 */
	public function loadTemplatesFromApi() {
		try {
			$from              = (isset( $_POST['from'] ) ? $_POST['from'] : null);
			$count             = (isset( $_POST['count'] ) ? $_POST['count'] : null);
			$template_id       = (isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : 0);
			$template_name     = (isset( $_POST['template_name'] ) ? $_POST['template_name'] : null);
			$template_category = (isset( $_POST['template_category'] ) ? $_POST['template_category'] : null);
			if ( is_null( $from ) || is_null( $count ) ) {
				throw new Exception( 'System problem , please contact support', 1001 );
				return false;
			}
			$getTemplateListArgs = [
				'pagination_start'  => $from,
				'pagination_count'  => $count,
				'template_category' => $template_category,
				'template_name'     => $template_name,
				'template_id'       => $template_id,
			];
			$list_of_templates = $this->getTemplateListFromApi( $getTemplateListArgs );

			if ( ! is_array( $list_of_templates ) ) {
				throw new Exception( 'Template list is not what we expected' );
			}

			if ( jupiterx_is_pro() ) {
				foreach ( $list_of_templates as $index => $template ) {
					$list_of_templates[ $index ]->free_template = '1';
				}
			}

			$db_manager = new JupiterX_Control_Panel_Database_Manager();
			$backups    = $db_manager->is_restore_db();
			$this->message(
				'Successfull', true, array(
					'templates' => $list_of_templates,
					'backups'   => $backups,
				)
			);
			return true;

		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}
	}
	public function preparation( $template_name ) {
		try {
			$this->message( 'All is ready.', true );
			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}
	}
	public function backupDB() {
		try {
			$db_manager  = new JupiterX_Control_Panel_Database_Manager();
			$dm_response = $db_manager->backup_db();
			if ( false == $dm_response ) {
				throw new Exception( $db_manager->get_error_message() );
			}

			$this->message( 'Backup created.', true );
			return true;

		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}
	}
	public function backup_media_records() {
		try {
			$db_manager = new JupiterX_Control_Panel_Database_Manager();

			$dm_response = $db_manager->backup_media_records();

			if ( false == $dm_response ) {
				throw new Exception( $db_manager->get_error_message() );
			}
			$this->message( 'Media records backup created.', true );
			return true;

		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}
	}
	public function restore_media_records() {
		try {
			$db_manager = new JupiterX_Control_Panel_Database_Manager();

			$dm_response = $db_manager->restore_media_records();

			if ( false == $dm_response ) {
				throw new Exception( $db_manager->get_error_message() );
			}
			$this->message( 'Media records restored successfully', true );
			return true;

		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}
	}
	public function isRestoreDB() {
		try {
			$db_manager = new JupiterX_Control_Panel_Database_Manager();
			$result     = $db_manager->is_restore_db();
			if ( is_array( $result ) ) {
				$this->message( 'Successfull', true, $result );
				return true;
			} else {
				throw new Exception( 'Result is not what we expected' );
			}
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}
	}
	public function restoreLatestDB() {
		try {
			$db_manager = new JupiterX_Control_Panel_Database_Manager();
			$return     = $db_manager->restore_latest_db();
			if ( false == $return ) {
				throw new Exception( $db_manager->get_error_message() );
			}
			JupiterX_Control_Panel_Helpers::prevent_cache_plugins();
			$this->message( 'Restore completed!', true );
			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}
	}
	public function resetDB() {
		try {
			$tables = array(
				'comments',
				'commentmeta',
				'links',
				// 'options',
				'postmeta',
				'posts',
				'term_relationships',
				'termmeta',
				'terms',
				'term_taxonomy',
			);

			include_once ABSPATH . 'wp-admin/includes/plugin.php';
			if ( jupiterx_is_callable( 'SitePress' ) ) {
				$tables[] = 'icl_translations';
			}

			$this->resetWordpressDatabase( $tables, array(), false );
			$this->message( 'Database reseted', true );

			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );

			return false;
		}
	}
	public function uploadTemplateToServer( $template_name ) {
		try {
			$this->setTemplateName( $template_name );
			$getTemplateName = $this->getTemplateName();
			if ( empty( $getTemplateName ) ) {
				throw new Exception( 'Choose one template first' );
			}
			$url                = $this->getTemplateDownloadLink( $this->getTemplateName(), 'download' );
			$template_file_name = $this->getTemplateDownloadLink( $this->getTemplateName(), 'filename' );
			$this->setTemplateRemoteAddress( $url );
			if ( filter_var( $url, FILTER_VALIDATE_URL ) === false ) {
				throw new Exception( 'Template source URL is not validate' );
			}
			JupiterX_Control_Panel_Helpers::upload_from_url( $this->getTemplateRemoteAddress(), $template_file_name, $this->getBasePath() );
			$this->message( 'Uploaded to server', true );
			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}
	}
	public function unzipTemplateInServer( $template_name ) {
		try {
			$this->setTemplateName( $template_name );
			$getTemplateName = $this->getTemplateName();
			if ( empty( $getTemplateName ) ) {
				throw new Exception( 'Choose one template first' );
			}

			$response = $this->getTemplateDownloadLink( $this->getTemplateName(), 'filename' );

			$this->setTemplateFileName( $response );

			$jupiterx_filesystem = new JupiterX_Filesystem(
				array(
					'context' => $this->getBasePath(),
				)
			);

			if ( $jupiterx_filesystem->get_error_code() ) {
				throw new Exception( $jupiterx_filesystem->get_error_message() );
				return false;
			}

			if ( ! $jupiterx_filesystem->exists( $this->getBasePath() . $this->getTemplateName() ) ) {
				JupiterX_Control_Panel_Helpers::un_zip( $this->getBasePath() . $this->getTemplateFileName(), $this->getBasePath() );
			} else {
				if ( $jupiterx_filesystem->rmdir( $this->getBasePath() . $this->getTemplateName(), true ) ) {
					JupiterX_Control_Panel_Helpers::un_zip( $this->getBasePath() . $this->getTemplateFileName(), $this->getBasePath() );
				}
			}

			$jupiterx_filesystem->delete( $this->getBasePath() . $this->getTemplateFileName() );

			$this->message( 'Completed', true );

			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );

			return false;
		}
	}
	public function validateTemplateFiles( $template_name ) {
		try {
			if ( empty( $template_name ) ) {
				throw new Exception( 'Choose template first' );
			}

			$jupiterx_filesystem = new JupiterX_Filesystem(
				array(
					'context' => $this->getBasePath(),
				)
			);

			if ( $jupiterx_filesystem->get_error_code() ) {
				throw new Exception( $jupiterx_filesystem->get_error_message() );
				return false;
			}

			$this->setTemplateName( $template_name );
			if (
				$jupiterx_filesystem->exists( $this->getAssetsAddress( 'template_content_path', $this->getTemplateName() ) ) == false ||
				$jupiterx_filesystem->exists( $this->getAssetsAddress( 'widget_path', $this->getTemplateName() ) ) == false ||
				$jupiterx_filesystem->exists( $this->getAssetsAddress( 'settings_path', $this->getTemplateName() ) ) == false
			) {
				throw new Exception( "Some template assets are missing Template Name : $template_name, Contact support." );
			} else {
				$this->message( 'Completed', true );
				return true;
			}
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );

			return false;
		}
	}
	public function installRequiredPlugins( $template_name ) {
		$this->reinitializeData( $template_name );
		try {
			$plugins = $this->getSettingsData( $template_name );

			if ( is_array( $plugins['options']['jupiterx_support_plugins'] ) == false || count( $plugins['options']['jupiterx_support_plugins'] ) <= 0 ) {
				throw new Exception( 'Plugin set have wrong structure' );
			}

			$plugin_manager = new JupiterX_Control_Panel_Plugin_Manager();
			$missed_plugins = [];

			foreach( $plugins['options']['jupiterx_support_plugins'] as $plugin ) {
				$plugin_basename = $plugin_manager->get_plugin_basename_by_slug( $plugin );
				if ( is_wp_error( validate_plugin( $plugin_basename ) ) ) {
					$missed_plugins[] = $plugin;
				}
			}

			if ( ! current_user_can( 'install_plugins' ) && ! empty( $missed_plugins ) ) {
				$missed_plugins_html = '<strong>' . implode( '</strong><strong>', $missed_plugins ) . '</strong>';

				$message = sprintf(
					esc_html__( 'You are using a sub site and you are not allowed to install a new plugin.
					Please install required plugins that listed below via your %s Network Admin > Plugins %s or contact your Network Admin.
					Required plugins for this template: %s %s %s', 'jupiterx' ),
					'<strong>',
					'</strong>',
					'<div class="jupiterx-missed-plugins-list">',
					$missed_plugins_html,
					'</div>'
				);

				throw new Exception( $message );
			}


			$pm_response = $plugin_manager->install_batch( $plugins['options']['jupiterx_support_plugins'] );
			if ( ! $pm_response ) {
				$pm_response = $plugin_manager->get_response_message();
				throw new Exception( $pm_response );
			}

			$message = '{param} plugins are installed.';
			$this->message( array( $message, count( $plugins['options']['jupiterx_support_plugins'] ) ), true );
			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}
	}

	/**
	 * Import plugins content.
	 *
	 * @since 1.0.3
	 */
	public function import_plugins_content( $template_name ) {

		try {
			$this->setTemplateName( $template_name );
			// Get template settings.
			$settings = $this->getSettingsData( $this->getTemplateName() );

			// Supported plugins list.
			$supported_plugins = $settings['options']['jupiterx_support_plugins'];

			// Run plugins importer.
			foreach ( $supported_plugins as $plugin ) {
				if ( is_callable( [ $this, "import_{$plugin}_content" ] ) ) {
					call_user_func( [ $this, "import_{$plugin}_content" ] );
				}
			}

			$this->message( __( 'Data of plugins have imported.', 'jupiterx'), true );

			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}

	}

	/**
	 * Import Revolution Slider content.
	 *
	 * @since 1.0.3
	 */
	public function import_revslider_content() {
		if ( ! class_exists( 'RevSlider' ) ) {
			return;
		}

		$filesystem = new JupiterX_Filesystem( [
			'context' => $this->getBasePath(),
		] );

		$revslider_folder = $this->getBasePath() . sanitize_title( $this->getTemplateName() ) . '/revslider';

		// Check extracted template if `revslider` folder exists inside.
		if ( ! $filesystem->exists( $revslider_folder ) ) {
			return;
		}

		$revslider = new RevSlider();

		$sliders = glob( $revslider_folder . '/*.zip' );

		if ( empty( $sliders ) ) {
			return;
		}

		global $wpdb;

		$tables = [
			'revslider_css',
			'revslider_layer_animations',
			'revslider_navigations',
			'revslider_sliders',
			'revslider_slides',
			'revslider_static_slides',
		];

		// Truncate tables.
		foreach	( $tables as $table ) {
			$wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}{$table}" );
		}

		// Import sliders.
		foreach ( $sliders as $slide ) {
			/**
			 * Start import slider.
			 *
			 * @param boolean Update animation.
			 * @param boolean Deprecated static param.
			 * @param mixed   Slider file path.
			 * @param boolean Template slide.
			 * @param boolean Single slide.
			 * @param boolean Update navigation.
			 */
			$revslider->importSliderFromPost( true, true, $slide, false, false, true );
		}
	}

	/**
	 * Import theme content via Server-Sent Events request.
	 *
	 *
	 * @throws Exception If template data is empty.
	 * @throws Exception If preliminary data is empty.
	 */
	public function import_theme_content_sse() {
		try {
			/*
             * Filter data input from GET method. Eventsource doesn't allow us to use
             * POST method.
             */
			$template_name = '';
			if ( ! empty( $_GET['template_name'] ) ) {
				// WPCS: XSS ok, CSRF ok.
				$template_name = sanitize_text_field( $_GET['template_name'] );
			}

			$template_id = '';
			if ( ! empty( $_GET['template_id'] ) ) {
				// WPCS: XSS ok, CSRF ok.
				$template_id = sanitize_text_field( $_GET['template_id'] );
			}

			$fetch_attachments = 'false';
			if ( ! empty( $_GET['fetch_attachments'] ) ) {
				// WPCS: XSS ok, CSRF ok.
				$fetch_attachments = sanitize_text_field( $_GET['fetch_attachments'] );
			}

			// Include wordpress-importer class.
			JupiterX_Control_Panel_Helpers::include_wordpress_importer();
			$this->reinitialize_data_sse( $template_name, $template_id );

			// Set importer options as an array.
			$options = array(
				'fetch_attachments' => filter_var( $fetch_attachments, FILTER_VALIDATE_BOOLEAN ),
				'default_author'    => get_current_user_id(),
			);

			// Create new instance for Importer.
			$importer = new JupiterX_Importer( $options );
			$logger   = new WP_Importer_Logger_ServerSentEvents();
			$importer->set_logger( $logger );

			// Get preliminary information.
			$file     = $this->getAssetsAddress( 'template_content_path', $this->getTemplateName() );
			$pre_data = $importer->get_preliminary_information( $file );
			if ( is_wp_error( $pre_data ) ) {
				throw new Exception( $pre_data->get_error_message() );
			}

            // @codingStandardsIgnoreStart
            // Turn off PHP output compression, allow us to print the log.
			$previous = error_reporting(error_reporting() ^ E_WARNING);

			// Configuration disabled for theme check plugin.
            // ini_set('output_buffering', 'off');
			// ini_set('zlib.output_compression', false);

            error_reporting($previous);
            // @codingStandardsIgnoreEnd

			if ( $GLOBALS['is_nginx'] ) {
				// Setting this header instructs Nginx to disable fastcgi_buffering
				// and disable gzip for this request.
				header( 'X-Accel-Buffering: no' );
				header( 'Content-Encoding: none' );
			}

			// Start the event stream here to record all the logs.
			header( 'Content-Type: text/event-stream' );
			header( 'Cache-Control: no-cache' );

			// Time to run the import!
			set_time_limit( 0 );

			// Ensure we're not buffered.
			wp_ob_end_flush_all();
			flush();

			// Run import process.
			$process = $importer->import( $file );

			// Setup complete response.
			$complete = array(
				'status'  => true, // The process is complete no matter success or not.
				'error'   => false, // Message error if any.
				'data'    => null, // Compatibility with current Ajax.
				'message' => 'Template contents were imported.',
			);

			// Check if the request is error, then set the message.
			if ( is_wp_error( $process ) ) {
				$complete['error'] = $process->get_error_message();
			}

			$this->message_sse( $complete );
			exit;

		} catch ( Exception $e ) {
			$this->message_sse( $e->getMessage(), true );
			exit;
		}
	}

	/**
	 * Get settings.json data.
	 *
	 */
	public function getSettingsData( $template_name ) {

		$this->setTemplateName( $template_name );
		$settings_url  = $this->getAssetsAddress( 'settings_url', $this->getTemplateName() );
		$settings_path = $this->getAssetsAddress( 'settings_path', $this->getTemplateName() );
		$response  = JupiterX_Control_Panel_Helpers::getFileBody( $settings_url, $settings_path );

		return json_decode( $response, true );
	}

	/**
	 * Send a Server-Sent Events message.
	 *
	 *
	 * @param mixed   $message     Data to be JSON-encoded and sent in the message.
	 * @param boolean $need_header Send response along with the header.
	 */
	public function message_sse( $message, $need_header = false ) {
		// Add header to start event stream only if needed.
		if ( $need_header ) {
			// Start the event stream.
			header( 'Content-Type: text/event-stream' );
			header( 'Cache-Control: no-cache' );
		}

		// Convert any message data as an array.
		if ( ! is_array( $message ) ) {
			$message = array(
				'message' => $message,
			);
		}

		// Set message event and pass the data.
		echo "event: message\n";
		echo 'data: ' . wp_json_encode( $message ) . "\n\n";

		flush();
	}

	public function importThemeContent( $template_name, $fetch_attachments = false ) {
		try {

			// Include wordpress-importer class.
			JupiterX_Control_Panel_Helpers::include_wordpress_importer();
			$this->reinitializeData( $template_name );

			// Set importer options as an array.
			$options = array(
				'fetch_attachments' => filter_var( $fetch_attachments, FILTER_VALIDATE_BOOLEAN ),
				'default_author'    => get_current_user_id(),
			);

			// Create new instance for Importer.
			$importer = new WXR_Importer( $options );
			$logger   = new WP_Importer_Logger_ServerSentEvents();
			$importer->set_logger( $logger );

			// Get preliminary information.
			$file = $this->getAssetsAddress( 'template_content_path', $this->getTemplateName() );
			$data = $importer->get_preliminary_information( $file );
			if ( is_wp_error( $data ) ) {
				$this->message( 'Error in parsing theme_content.xml!', false );
				return false;
			}

			// Run import process.
			ob_start();
			$importer->import( $file );
			ob_end_clean();

			$this->message( 'Template contents were imported.', true );
			return true;

		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}
	}
	public function importMenuLocations( $template_name ) {
		try {
			$settings = $this->getSettingsData( $template_name );

			$nav_menus = wp_get_nav_menus();

			if ( ! isset( $settings['options']['jupiterx_menu_locations'] ) || empty( $settings['options']['jupiterx_menu_locations'] ) || empty( $nav_menus ) ) {
				$this->message( 'There were no menu locations to import.', true );
			}

			$menu_locations = $settings['options']['jupiterx_menu_locations'];

			$locations = [];

			foreach ( $nav_menus as $menu ) {
				if ( in_array( $menu->name, $menu_locations, true ) ) {
					$location_key = array_search( $menu->name, $menu_locations, true );
					$locations[ $location_key ] = $menu->term_id;
				}
			}

			set_theme_mod( 'nav_menu_locations', $locations );

			$this->message( 'Navigation locations is configured.', true, [ $locations ] );

			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );

			return false;
		} // End try().
	}

	public function setUpPages( $template_name ) {
		try {
			$package_data = $this->getSettingsData( $template_name );

			// Set homepage.
			if(isset($package_data['options']['page_on_front'])) {
				$homepage_title = $package_data['options']['page_on_front'];
				if ( ! empty( $homepage_title ) ) {
					$homepage = get_page_by_title( $homepage_title );
				}
				if ( ! empty( $homepage->ID ) ) {
					update_option( 'page_on_front', $homepage->ID );
					update_option( 'show_on_front', 'page' );
				}
			}

			// Set shop page.
			if(isset($package_data['options']['woocommerce_shop_page_id'])) {
				$shop_title = $package_data['options']['woocommerce_shop_page_id'];
				if ( ! empty( $shop_title ) ) {
					$shop_page = get_page_by_title( $shop_title );
				}
				if ( ! empty( $shop_page->ID ) ) {
					update_option( 'woocommerce_shop_page_id', $shop_page->ID );
				}
			}

			// Set cart page.
			if(isset($package_data['options']['woocommerce_cart_page_id'])) {
				$cart_title = $package_data['options']['woocommerce_cart_page_id'];
				if ( ! empty( $cart_title ) ) {
					$cart_page = get_page_by_title( $cart_title );
				}
				if ( ! empty( $cart_page->ID ) ) {
					update_option( 'woocommerce_cart_page_id', $cart_page->ID );
				}
			}

			// Set Checkout page.
			if(isset($package_data['options']['woocommerce_checkout_page_id'])) {
				$checkout_title = $package_data['options']['woocommerce_checkout_page_id'];
				if ( ! empty( $checkout_title ) ) {
					$checkout_page = get_page_by_title( $checkout_title );
				}
				if ( ! empty( $checkout_page->ID ) ) {
					update_option( 'woocommerce_checkout_page_id', $checkout_page->ID );
				}
			}

			// Set My Account page.
			if ( isset( $package_data['options']['woocommerce_myaccount_page_id'] ) ) {
				$myaccount_title = $package_data['options']['woocommerce_myaccount_page_id'];

				if ( ! empty( $myaccount_title ) ) {
					$myaccount_page = get_page_by_title( $myaccount_title );
				}

				if ( ! empty( $myaccount_page->ID ) ) {
					update_option( 'woocommerce_myaccount_page_id', $myaccount_page->ID );
				}
			}

			$this->message( 'pages are configured.', true );

			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );

			return false;
		} // End try().
	}
	/**
	 * Import Settings options.
	 *
	 * @param  string $template_name Name of template.
	 * @return mixed
	 * @throws Exception When Settings file is empty.
	 */
	public function import_settings( $template_name ) {
		try {
			$this->reinitializeData( $template_name );
			$data = $this->getSettingsData( $template_name );

			// Data checks.
			if ( 'array' != gettype( $data ) ) {
				throw new Exception(
					sprintf( __( 'Error importing settings! Please check that you uploaded (%s) a settings export file.', 'jupiterx' ), $file_name )
				);
			}
			if ( ! isset( $data['template'] ) || ! isset( $data['mods'] ) ) {
				throw new Exception(
					sprintf( __( 'Error importing settings! template Please check that you uploaded (%s) a settings export file.', 'jupiterx' ), $file_name )
				);
			}

			// Clear theme mods.
			remove_theme_mods();

			$data['mods'] = JupiterX_Control_Panel_Export_Import::_import_images( $data['mods'] );

			// If wp_css is set then import it.
			if ( function_exists( 'wp_update_custom_css_post' ) && isset( $data['wp_css'] ) && '' !== $data['wp_css'] ) {
				wp_update_custom_css_post( $data['wp_css'] );
			}

			// Exclude nav menu locations in this process.
			if ( isset( $data['mods']['nav_menu_locations'] ) ) {
				unset( $data['mods']['nav_menu_locations'] );
			}

			// Loop through the mods.
			foreach ( $data['mods'] as $key => $val ) {
				set_theme_mod( $key, $val );
			}

			// Set Jet Menu options.
			if ( isset( $data['options']['jet_menu_options'] ) ) {
				update_option( 'jet_menu_options', $data['options']['jet_menu_options'] );
			}

			// Set extra options.
			if ( ! empty( $data['options']['extra'] ) ) {
				foreach( $data['options']['extra'] as $key => $val ) {
					update_option( $key, $val );
				}
			}

			$this->message( 'Settings are imported.', true );
			return true;

		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );

			return false;
		}
	}
	public function importThemeWidgets( $template_name ) {
		$this->reinitializeData( $template_name );
		try {
			$data = JupiterX_Control_Panel_Helpers::getFileBody(
				$this->getAssetsAddress( 'widget_url', $this->getTemplateName() ),
				$this->getAssetsAddress( 'widget_path', $this->getTemplateName() )
			);
			$data = json_decode( $data, true );
			$this->import_widget_data( $data );

			$this->message( 'Widgets are imported.', true );

			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );

			return false;
		}
	}
	public function finalizeImporting( $template_name ) {
		$this->reinitializeData( $template_name );
		$template_name = sanitize_title( $template_name );
		// Check if it had something to import.
		try {
			/*
			          $json_url  = $this->getAssetsAddress( 'json_url', $this->getTemplateName() );
			$json_path = $this->getAssetsAddress( 'json_path', $this->getTemplateName() );
			$response  = JupiterX_Control_Panel_Helpers::getFileBody( $json_url, $json_path );
			$plugins   = json_decode( $response, true );
			if (
				empty( $plugins['importing_data'] ) == false &&
				is_array( $plugins['importing_data'] ) &&
				count( $plugins['importing_data'] ) > 0 ) {
				foreach ( $plugins['importing_data'] as $key => $value ) {
					switch ( $value['name'] ) {
						case 'layer-slider':
							$ls_content_path = $this->getBasePath() . $template_name . '/' . $value['content_path'];
							if ( file_exists( $ls_content_path ) ) {
								$this->importLayerSliderContent( $ls_content_path );
							}
							break;
					}
				}
			}*/

			if ( ! $this->cleanInstallFiles( $template_name ) ) {
				throw new Exception( 'Can not remove installation source files' );
				return false;
			}

			update_option( 'jupiterx_template_installed', $this->getTemplateName() );
			update_option( 'jupiterx_template_installed_id', $this->getTemplateID() );

			jupiterx_flush_compiler( 'jupiterx' );

			jupiterx_elementor_flush_cache();

			$this->message( 'Data imported successfully', true );
			return true;

		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );

			return false;
		}
	}

	/**
	 * Clean install files
	 *
	 * @param $template_name
	 * @author Artbees Team
	 * @return bool
	 */
	private function cleanInstallFiles( $template_name ) {
		$jupiterx_filesystem = new JupiterX_Filesystem(
			array(
				'context' => $this->getBasePath(),
			)
		);

		// Deleting Template Source Folder.
		$template_path = $this->getBasePath() . sanitize_title( $template_name );
		if ( $jupiterx_filesystem->exists( $template_path ) && $jupiterx_filesystem->is_dir( $template_path ) && ! $jupiterx_filesystem->delete( $template_path, true ) ) {
			return false;
		}

		// Deleting Template Source Zip file.
		$template_zip = $template_path . '.zip';
		if ( $jupiterx_filesystem->exists( $template_zip ) && $jupiterx_filesystem->is_file( $template_zip ) && ! $jupiterx_filesystem->delete( $template_zip ) ) {
			return false;
		}

		return true;
	}
	public function uninstallTemplate() {
		try {
			$tables = array(
				'comments',
				'commentmeta',
				'links',
				'options',
				'postmeta',
				'posts',
				'term_relationships',
				'termmeta',
				'terms',
				'term_taxonomy',
			);

			$db_manager = new JupiterX_Control_Panel_Database_Manager();

			$db_manager->backup_media_records();

			$reset = $this->resetWordpressDatabase( $tables, array(), true );

			$db_manager->restore_media_records();

			if ( ! $reset ) {
				throw new Exception( 'Failed to uninstall template. Please try again.' );
			}

			$this->message( 'Template uninstall success.', true );
			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );

			return false;
		}
	}
	public function availableWidgets() {
		global $wp_registered_widget_controls;
		$widget_controls   = $wp_registered_widget_controls;
		$available_widgets = array();
		foreach ( $widget_controls as $widget ) {
			if ( ! empty( $widget['id_base'] ) && ! isset( $available_widgets[ $widget['id_base'] ] ) ) {
				$available_widgets[ $widget['id_base'] ]['id_base'] = $widget['id_base'];
				$available_widgets[ $widget['id_base'] ]['name']    = $widget['name'];
			}
		}

		return apply_filters( 'available_widgets', $available_widgets );
	}

	/**
	 * Import widgets' data.
	 *
	 * @throws Exception If can not read widget data.
	 *
	 * @param  array $data Widgets' data.
	 * @return boolean
	 */
	public function import_widget_data( $data ) {
		global $wp_registered_sidebars;

		$available_widgets = $this->availableWidgets();
		$widget_instances  = array();
		foreach ( $available_widgets as $widget_data ) {
			$widget_instances[ $widget_data['id_base'] ] = get_option( 'widget_' . $widget_data['id_base'] );
		}
		if ( empty( $data ) || ! is_array( $data ) ) {
			throw new Exception( 'Widget data could not be read. Please try a different file.' );
		}
		$results = array();
		foreach ( $data as $sidebar_id => $widgets ) {
			if ( 'wp_inactive_widgets' == $sidebar_id ) {
				continue;
			}
			if ( isset( $wp_registered_sidebars[ $sidebar_id ] ) ) {
				$sidebar_available    = true;
				$use_sidebar_id       = $sidebar_id;
				$sidebar_message_type = 'success';
				$sidebar_message      = '';
			} else {
				$sidebar_available    = false;
				$use_sidebar_id       = 'wp_inactive_widgets';
				$sidebar_message_type = 'error';
				$sidebar_message      = 'Sidebar does not exist in theme (using Inactive)';
			}
			$results[ $sidebar_id ]['name']         = ! empty( $wp_registered_sidebars[ $sidebar_id ]['name'] ) ? $wp_registered_sidebars[ $sidebar_id ]['name'] : $sidebar_id;
			$results[ $sidebar_id ]['message_type'] = $sidebar_message_type;
			$results[ $sidebar_id ]['message']      = $sidebar_message;
			$results[ $sidebar_id ]['widgets']      = array();
			foreach ( $widgets as $widget_instance_id => $widget ) {
				$fail               = false;
				$id_base            = preg_replace( '/-[0-9]+$/', '', $widget_instance_id );
				$instance_id_number = str_replace( $id_base . '-', '', $widget_instance_id );
				if ( ! $fail && ! isset( $available_widgets[ $id_base ] ) ) {
					$fail                = true;
					$widget_message_type = 'error';
					$widget_message      = 'Site does not support widget';
				}
				$widget = apply_filters( 'jupiterx_widget_settings', $widget );
				if ( ! $fail && isset( $widget_instances[ $id_base ] ) ) {
					$sidebars_widgets        = get_option( 'sidebars_widgets' );
					$sidebar_widgets         = isset( $sidebars_widgets[ $use_sidebar_id ] ) ? $sidebars_widgets[ $use_sidebar_id ] : array();
					$single_widget_instances = ! empty( $widget_instances[ $id_base ] ) ? $widget_instances[ $id_base ] : array();
					foreach ( $single_widget_instances as $check_id => $check_widget ) {
						if ( in_array( "$id_base-$check_id", $sidebar_widgets ) && (array) $widget == $check_widget ) {
							$fail                = true;
							$widget_message_type = 'warning';
							$widget_message      = 'Widget already exists';
							break;
						}
					}
				}
				if ( ! $fail ) {
					$single_widget_instances = get_option( 'widget_' . $id_base );
					$single_widget_instances = ! empty( $single_widget_instances ) ? $single_widget_instances : array(
						'_multiwidget' => 1,
					);
					$single_widget_instances[] = (array) $widget;
					end( $single_widget_instances );
					$new_instance_id_number = key( $single_widget_instances );
					if ( '0' === strval( $new_instance_id_number ) ) {
						$new_instance_id_number                           = 1;
						$single_widget_instances[ $new_instance_id_number ] = $single_widget_instances[0];
						unset( $single_widget_instances[0] );
					}
					if ( isset( $single_widget_instances['_multiwidget'] ) ) {
						$multiwidget = $single_widget_instances['_multiwidget'];
						unset( $single_widget_instances['_multiwidget'] );
						$single_widget_instances['_multiwidget'] = $multiwidget;
					}
					update_option( 'widget_' . $id_base, $single_widget_instances );
					$sidebars_widgets                    = get_option( 'sidebars_widgets' );
					$new_instance_id                     = $id_base . '-' . $new_instance_id_number;
					$sidebars_widgets[ $use_sidebar_id ][] = $new_instance_id;
					update_option( 'sidebars_widgets', $sidebars_widgets );
					if ( $sidebar_available ) {
						$widget_message_type = 'success';
						$widget_message      = 'Imported';
					} else {
						$widget_message_type = 'warning';
						$widget_message      = 'Imported to Inactive';
					}
				}
				$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['name']         = isset( $available_widgets[ $id_base ]['name'] ) ? $available_widgets[ $id_base ]['name'] : $id_base;
				$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['title']        = ! empty( $widget->title ) ? $widget->title : '';
				$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['message_type'] = $widget_message_type;
				$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['message']      = $widget_message;
			} // End foreach().
		} // End foreach().

		return true;
	}
	/**
	 * It will empty all or custom database tables of WordPress and install WordPress again if needed.
	 *
	 * @param array $table          which table need to be empty ? example : array('user' , 'usermeta')
	 *                              table names should be without any prefix
	 * @param bool  $install_needed if WordPress need to be installed after reseting database
	 *                              it should be false or true
	 *
	 * @return bool return if everything looks good and throwing errors on problems
	 */
	public function resetWordpressDatabase( $tables = array(), $exclude_tables = array(), $install_needed = false ) {
		global $wpdb, $reactivate_wp_reset_additional, $current_user;

		if ( $install_needed ) {

			require_once ABSPATH . '/wp-admin/includes/upgrade.php';

			$new_options = array();

			$old_options = array(
				'artbees_api_key',
				'active_plugins',
				'jupiterx_setup_wizard_current_page',
				'jupiterx_setup_wizard_hide_notice',
			);

			$blogname = get_option( 'blogname' );
			$blog_public = get_option( 'blog_public' );
			$site_url = site_url();
			$current_theme = wp_get_theme();

			foreach ( $old_options as $old_option_key ) {
				$new_options[ $old_option_key ] = get_option( $old_option_key );
			}

			if ( 'admin' != $current_user->user_login ) {
				$user = get_user_by( 'login', 'admin' );
			}

			if ( empty( $user->user_level ) || $user->user_level < 10 ) {
				$user = $current_user;
				$session_tokens = get_user_meta( $user->ID, 'session_tokens', true );
			}

			// Check if we need all the tables or specific table.
			if ( is_array( $tables ) && count( $tables ) > 0 ) {
				array_walk(
					$tables, function ( &$value, $key ) use ( $wpdb ) {
						$value = $wpdb->prefix . $value;
					}
				);
			} else {
				$prefix = str_replace( '_', '\_', $wpdb->prefix );
				$tables = $wpdb->get_col( "SHOW TABLES LIKE '{$prefix}%'" );
			}

			// exclude table if its valued.
			if ( is_array( $exclude_tables ) && count( $exclude_tables ) > 0 ) {
				array_walk(
					$exclude_tables, function ( &$ex_value, $key ) use ( $wpdb ) {
						$ex_value = $wpdb->prefix . $ex_value;
					}
				);
				$tables = array_diff( $tables, $exclude_tables );
			}
			// Removing data from WordPress tables.
			foreach ( $tables as $table ) {
				$wpdb->query( "DROP TABLE $table" );
			}

			$result = wp_install( $blogname, $user->user_login, $user->user_email, $blog_public );
			switch_theme( $current_theme->get_stylesheet() );

			/* GoDaddy Patch => GD have a problem of cleaning siteurl option value after reseting database */
			if ( site_url() == '' ) {
				$wpdb->update(
					$wpdb->options, array(
						'option_value' => $site_url,
					),array(
						'option_name' => 'siteurl',
					)
				);
			}
			extract( $result, EXTR_SKIP );

			$query = $wpdb->prepare( "UPDATE $wpdb->users SET user_pass = %s, user_activation_key = '' WHERE ID = %d", $user->user_pass, $user_id );
			$wpdb->query( $query );

			$get_user_meta = function_exists( 'get_user_meta' ) ? 'get_user_meta' : 'get_usermeta';
			$update_user_meta = function_exists( 'update_user_meta' ) ? 'update_user_meta' : 'update_usermeta';

			if ( $get_user_meta($user_id, 'default_password_nag') ) {
				$update_user_meta($user_id, 'default_password_nag', false);
			}

			if ( $get_user_meta($user_id, $wpdb->prefix . 'default_password_nag') ) {
				$update_user_meta($user_id, $wpdb->prefix . 'default_password_nag', false);
			}

			wp_clear_auth_cookie();
			wp_set_current_user( $user_id, $user->user_login );
			if ( $session_tokens ) {
				delete_user_meta( $user->ID, 'session_tokens' );
				update_user_meta( $user->ID, 'session_tokens', $session_tokens );
			}

			wp_set_auth_cookie( $user_id, true );
			do_action( 'wp_login', $user->user_login, $user );

			if ( $new_options ) {
				foreach ( $new_options as $key => $value ) {
					update_option( $key, $value );
				}
			}
			return true;
		} else {

			$jupiterx_temp_installed = get_option( 'jupiterx_template_installed' );

			if ( $jupiterx_temp_installed ) {

				// Delete plugins.
				$plugins = $this->getSettingsData( $jupiterx_temp_installed );
				if ( $plugins ) {
					$JupiterX_Control_Panel_Plugin_Manager = new JupiterX_Control_Panel_Plugin_Manager( false, false );
					if(isset($plugins['options']['jupiterx_support_plugins'])) {
						foreach ( $plugins['options']['jupiterx_support_plugins'] as $required_plugin ) {
							if ( ! $JupiterX_Control_Panel_Plugin_Manager->deactivate( $JupiterX_Control_Panel_Plugin_Manager->get_plugin_basename_by_slug( $required_plugin ) ) ) {
								throw new Exception( sprintf( 'Failed to deactivate plugin: %s', $required_plugin ) );
								return false;
							}
						}
					}
				}

				// Delete option data for page_on_front.
				if ( get_option( 'page_on_front' ) ) {
					delete_option( 'page_on_front' );
				}

				// Delete option data for show_on_front.
				if ( get_option( 'show_on_front' ) ) {
					delete_option( 'show_on_front' );
				}

				// Delete option data for woocommerce_shop_page_id.
				if ( get_option( 'woocommerce_shop_page_id' ) ) {
					delete_option( 'woocommerce_shop_page_id' );
				}

				// Delete widgets.
				$wpdb->query( "DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE '%widget%';" );

			}// End if().

			// truncate tables.
			foreach ( $tables as $table ) {
				$wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}{$table}" );
			}

			return true;
		}// End if().
	}

	private function setResponseForApiTemplateList( $url, $configs ) {
		$headers = array(
			'theme-name'       => $this->getThemeName(),
			'pagination-start' => isset( $configs['pagination_start'] ) ? $configs['pagination_start'] : 0,
			'pagination-count' => isset( $configs['pagination_count'] ) ? $configs['pagination_count'] : 1,
		);

		if ( isset( $configs['template_id'] ) && is_null( $configs['template_id'] ) == false ) {
			$headers['template-id'] = $configs['template_id'];
		}

		if ( isset( $configs['template_name'] ) && is_null( $configs['template_name'] ) == false ) {
			$headers['template-name'] = $configs['template_name'];
		}

		if ( isset( $configs['template_category'] ) && is_null( $configs['template_category'] ) == false ) {
			$headers['template-category'] = $configs['template_category'];
		}

		return $this->wp_remote_get( $url, $headers );
	}
	/**
	 * This method is resposible to get template list from api and create download link if template need to extract from WordPress repo.
	 *
	 * @param str $template_name if template name is valued it will return array of information about the this template.
	 *                           but if template is valued as false it will return all templates information
	 *
	 * @return array will return array of templates
	 */
	public function getTemplateListFromApi( $configs ) {
		if ( ! is_array( $configs ) ) {
			$configs = array();
		}
		$url      = $this->getApiURL() . 'theme/templates';
		$response = $this->setResponseForApiTemplateList( $url, $configs );
		if ( false == isset( $response->bool ) || false == $response->bool ) {
			throw new Exception( $response->message );
		}
		return $response->data;
	}
	public function getTemplateDownloadLink( $template_name = '', $type = 'download' ) {
		$url      = $this->getApiURL() . 'theme/download-template';
		$response = $this->wp_remote_get( $url,	array(
			'template-name' => $template_name,
			'type'          => $type,
		) );

		if ( false == isset( $response->bool ) || false == $response->bool ) {
			throw new Exception( $response->message );
		}

		/**
		 * Filters the template download url.
		 *
		 * @param string $response->data Download url.
		 */
		return apply_filters( 'jupiterx_template_download_url', $response->data, $type );
	}

	/**
	 * Gets psd file download link.
	 *
	 */
	public function get_template_psd_link() {
		$template_name = $_POST['template_name'];
		try {
			$response = $this->getTemplateDownloadLink( $template_name, 'download-psd' );
			$this->message(
				'Successfull', true, array(
					'psd_link' => $response,
				)
			);
			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		} // End try().
	}

	/**
	 * This method is resposible to get templates categories list from api
	 *
	 * @param str $template_name if template name is valued it will return array of information about the this template.
	 * but if template is valued as false it will return all templates information.
	 *
	 * @return array will return array of plugins.
	 */
	public function getTemplateCategoryListFromApi() {
		try {
			$url      = $this->getApiURL() . 'theme/template-categories';
			$response = $this->wp_remote_get( $url );
			if ( false == isset( $response->bool ) || false == $response->bool ) {
				throw new Exception( $response->message );
			}
			$this->message( 'Successfull', true, $response->data );
			return true;
		} catch ( Exception $e ) {
			$this->message( $e->getMessage(), false );
			return false;
		}
	}
	/**
	 * We need to make assets addresses dynamic and fully proccess.
	 * in one method for future development
	 * it will get the type of address and will return full address in string
	 * example :
	 * for (options_url) type , it will return something like this
	 * (http://localhost/jupiter/wp-content/uploads/jupiterx_templates/dia/options.txt).
	 *
	 * For (options_path) type , it will return something like this.
	 * (/usr/apache/www/wp-content/uploads/jupiterx_templates/dia/options.txt)
	 *
	 * @param str $which_one     Which address do you need.
	 * @param str $template_name such as.
	 */
	public function getAssetsAddress( $which_one, $template_name ) {
		$template_name = sanitize_title( $template_name );
		switch ( $which_one ) {
			case 'template_content_url':
				return $this->getBaseUrl() . $template_name . '/' . $this->getTemplateContentFileName();
				break;
			case 'template_content_path':
				return $this->getBasePath() . $template_name . '/' . $this->getTemplateContentFileName();
				break;
			case 'widget_url':
				return $this->getBaseUrl() . $template_name . '/' . $this->getWidgetFileName();
				break;
			case 'widget_path':
				return $this->getBasePath() . $template_name . '/' . $this->getWidgetFileName();
				break;
			case 'settings_url':
				return $this->getBaseUrl() . $template_name . '/' . $this->get_settings_file_name();
				break;
			case 'settings_path':
				return $this->getBasePath() . $template_name . '/' . $this->get_settings_file_name();
				break;
			default:
				throw new Exception( 'File name you are looking for is not introduced.' );

				return false;
				break;
		}
	}
	public function importLayerSliderContent( $content_path ) {
		global $wpdb;
		$plugin  = new JupiterX_Control_Panel_Plugin_Manager();
		$ls_path = $plugin->find_plugin_path( $this->layer_slider_slug );

		if ( $ls_path == false ) {
			throw new Exception( 'LayerSlider is not installed , install it first' );
			return false;
		}
		if ( $plugin->check_active_plugin( $this->layer_slider_slug ) == false ) {
			throw new Exception( 'LayerSlider is installed but not activated , activate it first' );
			return false;
		}
		// Empty layerslider table first.
		$table = $wpdb->prefix . 'layerslider';
		$wpdb->query( "TRUNCATE TABLE $table" );

		// Try to import configs.
		$ls_plugin_root_path = pathinfo( $plugin->get_plugins_dir() . $ls_path );
		include $ls_plugin_root_path['dirname'] . '/classes/class.ls.importutil.php';
		new LS_ImportUtil( $content_path );
		return true;
	}

	/**
	 * Reusable wrapper method for WP remote getter.
	 *
	 * Method only returns response body.
	 */
	public function wp_remote_get( $url = '', $headers = [] ) {
		$required_headers = [
			'api-key' => get_option( 'artbees_api_key' ),
			'domain'  => $_SERVER['SERVER_NAME'],
		];

		// Combined headers.
		$headers = array_merge( $headers, $required_headers );

		$response = json_decode( wp_remote_retrieve_body( wp_remote_get( $url, [
			'sslverify' => false,
			'headers'   => $headers,
		] ) ) );

		return $response;
	}

	/**
	 * This method is resposible to manage all the classes messages.
	 */
	public function message( $message, $status, $data = null ) {
		$response = [
			'message' => jupiterx_logic_message_helper( 'template-management', $message ),
			'status'  => $status,
			'data'    => $data,
		];

		header( 'Content-Type: application/json' );
		wp_die( json_encode( $response ) );
	}
}

/* Disable woocommerce redirection */
add_action( 'admin_init', 'disable_woocommerce', 5 );
/**
 * Disable Woocommerce redirect for template install
 *
 */
function disable_woocommerce() {
	delete_transient( '_wc_activation_redirect' );
	add_filter(
		'woocommerce_prevent_automatic_wizard_redirect', function () {
			return true;
		}
	);
}

add_filter(
	'pre_transient__wc_activation_redirect', function () {
		return 0;
	}
);

add_filter(
	'pre_transient__vc_page_welcome_redirect', function () {
		return 0;
	}
);

global $abb_phpunit;
if ( empty( $abb_phpunit ) || $abb_phpunit == false ) {
	new JupiterX_Control_Panel_Install_Template();
}
