<?php

/**
 * Class TX_Importer_AJAX
 *
 */
class TX_Importer_AJAX {
	/**
	 * @var string
	 */
	private static $key_option_current_demo = 'tx_importer_current_demo';

	/**
	 * Handle ajax uninstall.
	 *
	 * @return bool
	 */
	public function handle_ajax_uninstall() {
		TX_Importer_Service::reset_data_demo();

		return $this->_send_response_success( null );
	}

	/**
	 * Handle post data.
	 *
	 * @return bool
	 */
	public function handle_ajax() {
		try {
			$packages = ! empty( $_POST['packages'] ) ? $_POST['packages'] : false;

			if ( $packages ) {
				$demo = ! empty( $_POST['demo'] ) ? $_POST['demo'] : false;
				if ( ! $demo ) {
					throw TX_Error::create( __( 'Something went wrong!', 'edumodo' ), 4 );
				}

				$demos = TX_Importer::get_demo_data();
				if ( ! isset( $demos[ $demo ] ) ) {
					throw TX_Error::create( __( 'Demo not found!', 'edumodo' ), 4 );
				}

				$this->check_retry_import();

				return $this->_initializeImporter( $demos[ $demo ], $packages );
			}

			$current_step = $this->_get_key_current_step();

			return $this->_step_by_step( $current_step );
		} catch ( TX_Error $exception ) {
			return $this->_send_response_error( $exception->getMessage(), $exception->getErrorCode(), $exception->getHowTo() );
		} catch ( Exception $exception ) {
			return $this->_send_response_error( $exception->getMessage(), $exception->getCode() );
		}
	}

	/**
	 * Check retry import.
	 */
	private function check_retry_import() {
		$retry = isset( $_POST['retry'] ) ? $_POST['retry'] : false;

		if ( ! $retry || $retry === 'false' ) {
			return;
		}

		$current_posts_pp       = get_option( 'tx_importer_posts_pp', 100 );
		$current_attachments_pp = get_option( 'tx_importer_attachments_pp', 10 );

		update_option( 'tx_importer_posts_pp', max( intval( $current_posts_pp / 2 ), 10 ) );
		update_option( 'tx_importer_attachments_pp', max( intval( $current_attachments_pp / 2 ), 1 ) );
	}

	/**
	 * Initialize import.
	 *
	 * @param array $demo
	 * @param array $packages
	 *
	 * @return bool
	 */
	private function _initializeImporter( $demo, $packages = array() ) {
		do_action( 'tx_wizard_importer_start_import_demo', $demo );

		$packages = (array) $packages;
		$packages = apply_filters( 'tx_wizard_importer_prepare_packages', $packages );
		$this->_save_current_demo_data( $demo, $packages );
		update_option( 'tx_importer_prepare_wp_import', false );

		$this->_send_response_success( array(
			'next' => $this->_get_key_current_step()
		) );

		return true;
	}

	/**
	 * Prepare demo content.
	 */
	private function _prepare_demo_content() {
		$dir = $this->_get_dir_current_demo();
		$xml = $dir . '/content.xml';

		TX_Importer_Service::analyze_content( $xml );
	}

	/**
	 * Store temporarily demo data.
	 *
	 * @param array $demo
	 * @param array $packages
	 *
	 * @return bool
	 */
	private function _save_current_demo_data( $demo, $packages ) {
		$theme_slug = get_option( 'stylesheet' );

		return update_option( self::$key_option_current_demo, array(
			'theme'                  => $theme_slug,
			'demo'                   => $demo['key'],
			'revsliders'             => isset( $demo['revsliders'] ) ? $demo['revsliders'] : array(),
			'packages'               => $packages,
			'dir'                    => $demo['dir'],
			'plugins_required'       => isset( $demo['plugins_required'] ) ? $demo['plugins_required'] : false,
			'plugins_required_count' => count( $demo['plugins_required'] ),
			'current_step'           => 0,
		) );
	}

	/**
	 * Update current demo data
	 *
	 * @param $args
	 *
	 * @return bool
	 */
	public static function update_current_demo_data( $args ) {
		return update_option( self::$key_option_current_demo, $args );
	}

	/**
	 * Get option current demo.
	 *
	 * @return array
	 */
	public static function get_current_demo_data() {
		return get_option( self::$key_option_current_demo );
	}

	/**
	 * Get dir current demo.
	 *
	 * @return string
	 */
	private function _get_dir_current_demo() {
		$current_demo = self::get_current_demo_data();

		$base_dir = apply_filters( 'tx_wizard_importer_base_path_demo_data', false, $current_demo );
		if ( ! $base_dir ) {
			return $current_demo['dir'];
		}

		return apply_filters( 'tx_wizard_importer_directory_current_demo', $base_dir . $current_demo['demo'], $current_demo['demo'] );
	}

	/**
	 * Get selected packages.
	 *
	 * @return array
	 */
	private function _get_selected_packages() {
		$current_demo = self::get_current_demo_data();

		return ! empty( $current_demo['packages'] ) ? $current_demo['packages'] : array();
	}

	/**
	 * Get index current step.
	 *
	 * @return int
	 */
	private function _get_index_current_step() {
		$current_demo = self::get_current_demo_data();

		return ! empty( $current_demo['current_step'] ) ? intval( $current_demo['current_step'] ) : 0;
	}

	/**
	 * Increase index current step
	 */
	private function _increase_index_current_step() {
		$current_demo                 = self::get_current_demo_data();
		$current_demo['current_step'] = $this->_get_index_current_step() + 1;
		self::update_current_demo_data( $current_demo );
	}

	/**
	 * Get key current step.
	 *
	 * @return bool|mixed
	 */
	private function _get_key_current_step() {
		$index    = $this->_get_index_current_step();
		$packages = $this->_get_selected_packages();

		if ( $index < count( $packages ) ) {
			return $packages[ $index ];
		}

		return false;
	}

	/**
	 * Next step and get key step.
	 *
	 * @return bool|mixed
	 */
	private function _get_key_next_step() {
		$this->_increase_index_current_step();
		$index    = $this->_get_index_current_step();
		$packages = $this->_get_selected_packages();

		if ( $index < count( $packages ) ) {
			return $packages[ $index ];
		}

		$this->_finish();

		return false;
	}

	/**
	 * Finish process import.
	 */
	private function _finish() {
		/**
		 * Delete post hello world.
		 */
		wp_trash_post( 1 );

		//$this->_update_settings();

		/**
		 * Remap menu locations.
		 */
		$tx_wp_import = TX_WP_Import_Service::instance( false );
		$tx_wp_import->set_menu_locations();

		/**
		 * Update option demo installed.
		 */
		$demo_data = self::get_current_demo_data();
		$demo_key  = isset( $demo_data['demo'] ) ? $demo_data['demo'] : false;
		if ( ! $demo_data ) {
			return;
		}

		TX_Importer::update_key_demo_installed( $demo_key );
	}

	/**
	 * Update site settings.
	 */
	private function _update_settings() {
		$dir           = $this->_get_dir_current_demo();
		$settings_file = $dir . '/settings.dat';

		TX_Importer_Service::settings( $settings_file );
	}


	/**
	 * Call step import.
	 *
	 * @param $step
	 *
	 * @return mixed
	 * @throws Exception
	 */
	private function _step_by_step( $step ) {
		do_action( 'tx_wizard_importer_start_step', $step );

		$callback_function = 'step_' . $step;

		$callable = apply_filters( "tx_wizard_importer_step_$step", array( $this, $callback_function ) );

		if ( is_callable( $callable ) ) {
			return call_user_func( $callable );
		}

		throw TX_Error::create( __( 'Something went wrong!', 'edumodo' ), 3 );
	}

	/**
	 * Step install and activate plugins.
	 *
	 * @throws Exception
	 */
	public function step_plugins() {
		$current_demo     = self::get_current_demo_data();
		$plugins_required = $current_demo['plugins_required'];

		if ( empty( $plugins_required ) ) {
			return $this->next_step();
		}

		$plugin_required = isset( $plugins_required[0] ) ? $plugins_required[0] : false;
		if ( ! $plugin_required ) {
			return $this->next_step();
		}

		$extend_data               = array();
		$count_all_plugins         = $current_demo['plugins_required_count'];
		$remain_plugins            = count( $plugins_required );
		$percentage                = intval( 100 - $remain_plugins / $count_all_plugins * 100 );
		$extend_data['percentage'] = min( 100, $percentage );

		$plugin_slug = isset( $plugin_required['slug'] ) ? $plugin_required['slug'] : false;
		$plugin      = TX_Plugins_Manager::get_plugin_by_slug( $plugin_slug );

		if ( $plugin ) {
			$status = $plugin->get_status();
			if ( $status === 'not_installed' ) {
				$install = $plugin->install();

				if ( $install ) {
					$extend_data['installed'] = $plugin->get_slug();

					return $this->_try_step( $extend_data );
				} else {
					$messages = $plugin->get_messages();
					$string   = implode( '. ', $messages );
					tx_add_log( sprintf( __( 'Installing %s plugin failed. %s', 'edumodo' ), $plugin->get_name(), $string ), 'plugin_installation' );

					//Ignore install failed.
					//throw TX_Error::create( sprintf( __( 'Installing %s plugin failed. %s', 'edumodo' ), $plugin->get_name(), $string ), 9, __( 'Please try again or install manually the plugin on tab <strong>Plugins</strong>.', 'edumodo' ) );
				}
			} else if ( $status == 'inactive' ) {
				$result = $plugin->activate( true );
				if ( ! $result ) {
					$messages = $plugin->get_messages();
					$string   = implode( '. ', $messages );
					throw TX_Error::create( sprintf( __( 'Activating %s plugin failed. %s', 'edumodo' ), $plugin->get_name(), $string ), 9, __( 'Please try again or install manually the plugin on tab <strong>Plugins</strong>.', 'edumodo' ) );
				}

				$extend_data = array( 'activated' => $plugin->get_slug() );
			}
		}

		array_splice( $plugins_required, 0, 1 );
		$current_demo['plugins_required'] = $plugins_required;
		self::update_current_demo_data( $current_demo );

		$remain_plugins            = count( $plugins_required );
		$percentage                = intval( 100 - $remain_plugins / $count_all_plugins * 100 );
		$extend_data['percentage'] = min( 100, $percentage );

		return $this->_try_step( $extend_data );
	}

	/**
	 * Step import main content.
	 */
	public function step_main_content() {
		$prepare_wp_import = get_option( 'tx_importer_prepare_wp_import', false );
		if ( ! $prepare_wp_import ) {
			$this->_prepare_demo_content();
			update_option( 'tx_importer_prepare_wp_import', true );

			return $this->_try_step();
		}
		$packages         = $this->_get_selected_packages();
		$fetch_attachment = array_search( 'media', $packages ) !== false;
		$tx_wp_import   = TX_WP_Import_Service::instance();
		$response         = $tx_wp_import->import_posts( $fetch_attachment );
		if ( $response['has_posts'] && ( $response['has_posts'] !== 'attachment' ) ) {
			return $this->_try_step( $response );
		}

		/**
		 * Fix issue while importing missing some menu items
		 */
		$tx_wp_import->backfill_parents();
		$tx_wp_import->backfill_attachment_urls();
		$tx_wp_import->remap_featured_images();

		return $this->next_step( $response );
	}

	/**
	 * Step homepage
	 */
	public function step_homepage() {

    // Assign menus to their locations.
    $main_menu = get_term_by( 'name', 'Primary', 'nav_menu' );

    set_theme_mod( 'nav_menu_locations', array(
            'primary' => $main_menu->term_id,
        )
    );

    // Assign front page and posts page (blog page).
    $front_page_id = get_page_by_title( 'Home' );
    $blog_page_id  = get_page_by_title( 'Blog' );

    update_option( 'show_on_front', 'page' );
    update_option( 'page_on_front', $front_page_id->ID );
    update_option( 'page_for_posts', $blog_page_id->ID );

		$homepage_setup = TX_WP_Import_Service::instance();
		return $this->next_step( $homepage_setup );
	}

	/**
	 * Step import media file.
	 */
	public function step_media() {
		$tx_wp_import = TX_WP_Import_Service::instance();
		$response       = $tx_wp_import->import_posts( true );
		if ( $response['has_posts'] ) {
			return $this->_try_step( $response );
		}

		return $this->next_step( $response );
	}

	/**
	 * Step import widgets.
	 */
	public function step_widget() {
		$dir          = $this->_get_dir_current_demo();
		$widget_file  = $dir . '/widget_data.json';

		TX_Importer_Service::widget( $widget_file );

		return $this->next_step();
	}

	/**
	 * Step import Slider Revolution
	 * @return bool
	 */
	public function step_revslider() {
		$demo_data  = self::get_current_demo_data();
		$revsliders = isset( $demo_data['revsliders'] ) ? $demo_data['revsliders'] : array();

		TX_Importer_Service::revslider( $revsliders );

		return $this->next_step();
	}

	/**
	 * Step import customizer.
	 */
	public function step_customizer() {
		$dir          = $this->_get_dir_current_demo();
		$setting_file = $dir . '/customizer.dat';
		TX_Importer_Service::customizer( $setting_file );

		return $this->next_step();
	}

	/**
	 * Step import theme options.
	 */
	public function step_theme_options() {
		$dir          = $this->_get_dir_current_demo();
		$setting_file = $dir . '/options.json';
		TX_Importer_Service::redux( $setting_file );

		return $this->next_step();
	}

	/**
	 * Next step and return response success.
	 *
	 * @param mixed $ext
	 *
	 * @return bool
	 */
	public function next_step( $ext = null ) {
		$done = $this->_get_key_current_step();
		$next = $this->_get_key_next_step();
		do_action( 'tx_wizard_importer_next_step', $done, $next, $ext );

		return $this->_send_response_success( array(
			'done' => $done,
			'next' => $next,
			'ext'  => $ext,
		) );
	}

	/**
	 * Next step and return response success.
	 *
	 * @param mixed $ext
	 *
	 * @return bool
	 */
	private function _try_step( $ext = null ) {
		$current = $this->_get_key_current_step();
		do_action( 'tx_wizard_importer_try_step', $current, $ext );

		return $this->_send_response_success( array(
			'next' => $current,
			'ext'  => $ext,
		) );
	}

	/**
	 * Send response error.
	 *
	 * @param string $msg
	 * @param string $code
	 * @param string $how_to
	 * @param bool $safe
	 *
	 * @return bool
	 */
	private function _send_response_error( $msg, $code, $how_to = '', $safe = true ) {
		$data = array(
			'title'  => $msg,
			'how_to' => $how_to,
			'code'   => $code,
		);

		if ( ! $safe ) {
			wp_send_json_error( $data );
		}

		$response = array(
			'success' => false,
		);

		if ( isset( $data ) ) {
			if ( is_wp_error( $data ) ) {
				$result = array();
				foreach ( $data->errors as $code => $messages ) {
					foreach ( $messages as $message ) {
						$result[] = array(
							'code'    => $code,
							'message' => $message,
						);
					}
				}

				$response['data'] = $result;
			} else {
				$response['data'] = $data;
			}
		}

		$this->_send_response( $response );

		return true;
	}

	/**
	 * Send response success.
	 *
	 * @param $data
	 * @param $safe
	 *
	 * @return bool
	 */
	private function _send_response_success( $data, $safe = true ) {
		if ( ! $safe ) {
			wp_send_json_success( $data );
		}
		$response = array(
			'success' => true,
		);

		if ( isset( $data ) ) {
			$response['data'] = $data;
		}

		$this->_send_response( $response );

		return true;
	}

	/**
	 * Send response.
	 *
	 * @param $data
	 */
	private function _send_response( $data ) {
		echo '<!-- TX_IMPORT_START -->';
		header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
		echo wp_json_encode( $data );
		echo '<!-- TX_IMPORT_END -->';
		if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
			wp_die();
		} else {
			die;
		}
	}
}
