<?php

/**
 * Class TX_Plugins_Manager.
 */
class TX_Plugins_Manager extends TX_Admin_Sub_Page {
	/**
	 * @var null
	 */
	private static $plugins = null;

	/**
	 * @var string
	 */
	public $key_page = 'plugins';

	/**
	 * @var string
	 */
	public static $page_key = 'plugins';

	/**
	 * @var null
	 */
	private static $all_plugins_require = null;

	/**
	 * Is writable.
	 *
	 * @var bool
	 */
	private static $is_writable = null;

	/**
	 * Add notice.
	 *
	 * @param string $content
	 * @param string $type
	 */
	public static function add_notification( $content = '', $type = 'success' ) {
		TX_Dashboard::add_notification( array(
			'content' => $content,
			'type'    => $type,
			'page'    => self::$page_key,
		) );
	}

	/**
	 * Get url plugin actions.
	 *
	 * @param $args
	 *
	 * @return string
	 */
	public static function get_url_plugin_actions( $args ) {
		$args = wp_parse_args( $args, array(
			'slug'          => '',
			'plugin-action' => '',
			'network'       => '',
		) );

		$args['action'] = 'tx_plugins';

		$url = admin_url( 'admin.php' );
		$url = add_query_arg( $args, $url );

		return $url;
	}

	/**
	 * Get link delete plugin.
	 *
	 * @param $plugin_file
	 *
	 * @return string
	 */
	public static function get_url_delete_plugin( $plugin_file ) {
		$url = wp_nonce_url( 'plugins.php?action=delete-selected&checked[]=' . $plugin_file . '&plugin_status=all', 'bulk-plugins' );

		return network_admin_url( $url );
	}

	/**
	 * TX_Plugins_Manager constructor.
	 */
	protected function __construct() {
		parent::__construct();

		$this->init_hooks();
	}


	/**
	 * Init hooks.
	 */
	private function init_hooks() {
		add_action( 'wp_ajax_tx_plugins_manager', array( $this, 'handle_ajax_plugin_request_actions' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
		add_filter( 'tx_dashboard_sub_pages', array( $this, 'add_sub_page' ) );
		add_action( 'admin_action_tx_plugins', array( $this, 'handle_plugin_actions' ) );
		add_action( 'tx_wizard_dashboard_init', array( $this, 'notification' ) );
		add_action( 'tx_wizard_pre_install_plugin', array( $this, 'raise_limit_plugin_installation' ) );
		add_action( 'tx_wizard_pre_upgrade_plugin', array( $this, 'raise_limit_plugin_installation' ) );
	}

	/**
	 * Raise limit for plugin installation (install/upgrade)
	 */
	public function raise_limit_plugin_installation() {
		tx_wizard_set_time_limit();
		wp_raise_memory_limit( 'tx_wizard_admin' );
	}


	/**
	 * Handle plugin actions like install, activate, deactivate.
	 */
	public function handle_plugin_actions() {
		$action   = isset( $_GET['plugin-action'] ) ? $_GET['plugin-action'] : false;
		$slug     = isset( $_GET['slug'] ) ? $_GET['slug'] : false;
		$network  = ! empty( $_GET['network'] ) ? true : false;
		$is_wporg = ! empty( $_GET['wporg'] ) ? true : false;

		if ( ! $action || ! $slug ) {
			return;
		}

		$plugin = new TX_Plugin( $slug, $is_wporg );

		if ( $action == 'install' ) {
			$plugin->install();

			// Activate after install.
			$link_activate = self::get_url_plugin_actions( array(
				'slug'          => $slug,
				'plugin-action' => 'activate',
				'network'       => $network,
			) );

			tx_wizard_redirect( $link_activate );
		}

		if ( $action == 'activate' ) {
			$plugin->activate( false, $network );
		}

		if ( $action == 'deactivate' ) {
			$plugin->deactivate();
		}

		tx_wizard_redirect( admin_url( 'plugins.php' ) );
	}

	/**
	 * Add sub page.
	 *
	 * @param $sub_pages
	 *
	 * @return mixed
	 */
	public function add_sub_page( $sub_pages ) {
		$sub_pages['plugins'] = array(
			'title' => __( 'Plugins', 'edumodo' ),
		);

		return $sub_pages;
	}

	/**
	 * Handle ajax plugin request action.
	 */
	public function handle_ajax_plugin_request_actions() {
		$slug   = isset( $_POST['slug'] ) ? $_POST['slug'] : false;
		$action = isset( $_POST['plugin_action'] ) ? $_POST['plugin_action'] : false;

		$plugins = self::get_plugins();
		foreach ( $plugins as $plugin ) {
			if ( $plugin->get_slug() == $slug ) {
				$result = false;

				$next_action = 'activate';

				switch ( $action ) {
					case 'install':
						$result = $plugin->install();
						break;

					case 'activate':
						$result      = $plugin->activate( null );
						$next_action = 'deactivate';
						break;

					case 'deactivate':
						$result = $plugin->deactivate();
						break;

					case 'update':
						$result    = $plugin->update();
						$is_active = $plugin->is_active();
						if ( $is_active ) {
							$next_action = 'deactivate';
						} else {
							$next_action = 'activate';
						}
						break;
				}

				if ( $result ) {
					wp_send_json_success( array(
						'messages' => $plugin->get_messages(),
						'action'   => $next_action,
						'text'     => ucfirst( $next_action ),
						'slug'     => $plugin->get_slug(),
						'version'  => $plugin->get_current_version(),
						'info'     => $plugin->get_info(),
						'status'   => $plugin->get_status(),
					) );
				}

				wp_send_json_error( array(
					'messages' => $plugin->get_messages(),
				) );
			}
		}

		wp_send_json_error();
	}

	/**
	 * Enqueue scripts.
	 *
	 */
	public function enqueue_scripts() {
		wp_enqueue_script( 'tx-plugins', TX_WIZARD_ADMIN_URI . '/assets/js/plugins/plugins.js', array( 'jquery' ), TX_WIZARD_VERSION );
		$this->localize_script();

		if ( ! $this->is_myself() ) {
			return;
		}
		wp_enqueue_script( 'tx-isotope', TX_WIZARD_ADMIN_URI . '/assets/js/plugins/isotope.pkgd.min.js', array( 'jquery' ), TX_WIZARD_VERSION );
		wp_enqueue_script( 'tx-plugins-manager', TX_WIZARD_ADMIN_URI . '/assets/js/plugins/plugins-manager.js', array( 'tx-plugins', 'tx-isotope', 'updates', 'tx-wizard-admin' ), TX_WIZARD_VERSION );
	}

	/**
	 * Localize script.
	 */
	public function localize_script() {
		wp_localize_script( 'updates', '_wpUpdatesItemCounts', array(
			'totals' => wp_get_update_data(),
		) );

		wp_localize_script( 'tx-plugins', 'tx_plugins_manager', array(
			'admin_ajax_action' => admin_url( 'admin-ajax.php' ),
		) );
	}

	/**
	 * Get all plugins require.
	 *
	 * @return TX_Plugin[]
	 */
	public static function get_plugins() {
		if ( self::$plugins == null ) {
			$all_plugins = self::get_all_plugins();

			$plugins = array();
			foreach ( $all_plugins as $index => $plugin ) {
				$tx_plugin = new TX_Plugin();
				$tx_plugin->set_args( $plugin );

				$plugins[] = $tx_plugin;
			}

			self::$plugins = $plugins;
		}

		return self::$plugins;
	}

	/**
	 * Get all plugins.
	 *
	 * @return array
	 */
	private static function get_all_plugins() {
		if ( self::$all_plugins_require == null ) {
			$plugins = array();

			$plugins = apply_filters( 'tx_wizard_get_all_plugins_require', $plugins );

			foreach ( $plugins as $index => $plugin ) {
				$plugin = wp_parse_args( $plugin, array(
					'required' => false,
					'add-on'   => false,
					'silent'   => true,
				) );

				$plugins[ $index ] = $plugin;
			}

			uasort( $plugins, function ( $first, $second ) {
				if ( $first['required'] === $second['required'] ) {
					return 0;
				}

				if ( $first['required'] ) {
					return - 1;
				}

				return 1;
			} );

			self::$all_plugins_require = $plugins;
		}

		return self::$all_plugins_require;
	}

	/**
	 * Get external plugins (outside wp.org).
	 *
	 * @return TX_Plugin[]
	 */
	public static function get_external_plugins() {
		$required_plugins = self::get_plugins();

		$plugins = array();
		foreach ( $required_plugins as $tx_plugin ) {
			if ( $tx_plugin->is_wporg() ) {
				continue;
			}

			$plugins[] = $tx_plugin;
		}

		return $plugins;
	}

	/**
	 * Get required plugins inactive or not installed.
	 *
	 * @return TX_Plugin[]
	 */
	public static function get_required_plugins_inactive() {
		$required_plugins = self::get_plugins();

		$plugins = array();
		foreach ( $required_plugins as $tx_plugin ) {
			if ( $tx_plugin->is_active() || $tx_plugin->is_add_on() ) {
				continue;
			}

			$plugins[] = $tx_plugin;
		}

		return $plugins;
	}

	/**
	 * Get all add ons.
	 *
	 * @return TX_Plugin[]
	 */
	public static function get_all_add_ons() {
		$all_plugins = self::get_plugins();

		$plugins = array();
		foreach ( $all_plugins as $plugin ) {
			if ( ! $plugin->is_add_on() ) {
				continue;
			}

			$plugins[] = $plugin;
		}

		return $plugins;
	}

	/**
	 * Get list slug plugins require all demo.
	 *
	 * @return array
	 */
	public static function get_slug_plugins_require_all() {
		$all_plugins = self::get_plugins();

		$plugins_require_all = array();
		foreach ( $all_plugins as $index => $plugin ) {
			if ( $plugin->is_required() ) {
				array_push( $plugins_require_all, $plugin->get_slug() );
			}
		}

		return $plugins_require_all;
	}

	/**
	 * Get plugin by slug.
	 *
	 * @param $slug
	 *
	 * @return false|TX_Plugin
	 */
	public static function get_plugin_by_slug( $slug ) {
		$all_plugins = self::get_plugins();

		if ( count( $all_plugins ) === 0 ) {
			return false;
		}

		foreach ( $all_plugins as $plugin ) {
			if ( $plugin->get_slug() == $slug ) {
				return $plugin;
			}
		}

		return false;
	}

	/**
	 * Check permission plugins directory.
	 */
	private static function check_permission() {
		self::$is_writable = wp_is_writable( WP_PLUGIN_DIR );
	}

	/**
	 * Get permission writable plugins directory.
	 */
	public static function get_permission() {
		if ( is_null( self::$is_writable ) ) {
			self::check_permission();
		}

		return self::$is_writable;
	}

	/**
	 * Notice waring.
	 */
	public function notification() {
		if ( ! self::get_permission() ) {
			TX_Dashboard::add_notification( array(
				'content' => '<strong>Important!</strong> Please check permission directory <code>' . WP_PLUGIN_DIR . '</code>. Please follow <a href="https://goo.gl/guirO5" target="_blank">the guide</a>.',
				'type'    => 'error',
			) );
		}
	}
}
