<?php
/**
 * Admin page class
 *
 * @since         1.0.0
 * @package       factory-core
 */

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! class_exists( 'Wbcr_FactoryPages600_AdminPage' ) ) {

	class Wbcr_FactoryPages600_AdminPage extends Wbcr_FactoryPages600_Page {

		/**
		 * Visible page title.
		 * For example: 'License Manager'
		 *
		 * @var string
		 */
		public $page_title;

		/**
		 * Visible title in menu.
		 * For example: 'License Manager'
		 *
		 * @var string
		 */
		public $menu_title = null;

		/**
		 * If set, an extra sub menu will be created with another title.
		 *
		 * @var string
		 */
		public $menu_sub_title = null;

		/**
		 * Иконка меню в главном меню админ панели
		 *
		 * Используется только в том случае, если ссылка на страницу отображается
		 * в главном меню админ панели (левый сайдбар) и не является элементом подменю.
		 *
		 * Пример: '~/assets/img/menu-icon.png', ~/ будет заменен ссылкой на корневую
		 * директорию плагина.
		 * Можно использовать dashicons: '\f321'
		 *
		 * @var string
		 */
		public $menu_icon = null;

		/**
		 * Позиция в главном меню админ панели
		 *
		 * Если эта страница была добавлена в главное меню админ панели (левый сайдбар).
		 * Вы можете установить позицию меню. Подробнее смотрите в WordPress кодексе.
		 *
		 * @link http://codex.wordpress.org/Function_Reference/add_menu_page
		 *
		 * Позиция может быть установлена от 0 до 100 и чем больше цифра, тем ниже будет
		 * расположен пункт меню.
		 *
		 * Внимание! Если два пункта используют одинаковую цифру-позицию, один из пунктов
		 * меню может быть перезаписан и будет показан только один пункт из двух.
		 * Чтобы избежать конфликта, можно использовать десятичные значения, вместо целых
		 * чисел: 63.3 вместо 63. Используйте кавычки: "63.3".
		 *
		 * 2 Консоль
		 * 4 Разделитель
		 * 5 Посты
		 * 10 Медиа
		 * 15 Ссылки
		 * 20 Страницы
		 * 25 Комментарии
		 * 59 Разделитель
		 * 60 Внешний вид
		 * 65 Плагины
		 * 70 Пользователи
		 * 75 Инструменты
		 * 80 Настройки
		 * 99 Разделитель
		 *
		 * @var string
		 */
		public $menu_position = null;

		/**
		 * Тип записи к меню которой, нужно прикрепить ссылку на страницу
		 *
		 * К примеру, если вы установите тип записи "post". В меню "Записи" появится
		 * ссылка на эту страницу, как элемент подменю.
		 *
		 * Пример: 'post'
		 *
		 * @var string
		 */
		public $menu_post_type = null;

		/**
		 * Название (slug) элемента главного родительского меню в админ панели, в которое будет
		 * добавлен пункт меню этой страницы, как элемент подменю.
		 *
		 * Примеры:
		 * index.php - Консоль (Dashboard). Или спец. функция: add_dashboard_page();
		 * edit.php - Посты (Posts). Или спец. функция: add_posts_page();
		 * upload.php - Медиафайлы (Media). Или спец. функция: add_media_page();
		 * link-manager.php - Ссылки (Links). Или спец. функция: add_links_page();
		 * edit.php?post_type=page - Страницы (Pages). Или спец. функция: add_pages_page();
		 * edit-comments.php - Комментарии (Comments). Или спец. функция: add_comments_page();
		 * edit.php?post_type=your_post_type - Произвольные типы записей.
		 * themes.php - Внешний вид (Appearance). Или спец. функция: add_theme_page();
		 * plugins.php - Плагины (Plugins). Или спец. функция: add_plugins_page();
		 * users.php - Пользователи (Users). Или спец. функция: add_users_page();
		 * tools.php - Инструменты (Tools). Или спец. функция: add_management_page();
		 * options-general.php - Настройки (Settings). Или спец. функция: add_options_page()
		 * settings.php - Настройки (Settings) сети сайтов в MU режиме.
		 *
		 * @var string
		 */
		public $menu_target = null;

		/**
		 * if true, then admin.php is used as a base url.
		 *
		 * @var bool
		 */
		public $custom_target = false;

		/**
		 * Разрешения пользователя, чтобы иметь доступ к странице.
		 *
		 * Этот параметр отвечает и за доступ к странице этого пункта меню. Подробнее
		 * смотрите в кодексе WordPress:
		 *
		 * @link http://codex.wordpress.org/Roles_and_Capabilities
		 *
		 * Указывать массив разрешений, например:
		 * ['manage_options', 'manage_network']
		 *
		 * @var array
		 */
		public $capabilitiy = null;

		/**
		 * Скрыть страницу из главного меню админ панели?
		 *
		 * Если true, то закладка на эту страницу не будет добавлена в главное меню
		 * админ панели.
		 *
		 * @var bool
		 */
		public $internal = false;

		/**
		 * If true, the page is for network
		 *
		 * @var bool
		 */
		public $network = false;

		/**
		 * Предотвратить создание страницы?
		 *
		 * Если true, то страница не будет создана. Может пригодиться в тех случаях,
		 * когда страница должна быть создана только при выполнении условий.
		 *
		 * @since 3.0.6
		 * @var bool
		 */
		public $hidden = false;

		/**
		 * Сделать доступной страницу в панели управлениям сайтами (панель суперадминистратора)
		 *
		 * Если установлено true, в панели управления сайтами появится закладка на эту страницу.
		 * Также эта страница получить разрешения на просмотр для группы суперадминистраторов.
		 *
		 * @var bool
		 */
		public $available_for_multisite = false;

		/**
		 * Задать текст ссылки на странице плагинов (рядом с активировать/деактивировать)
		 *
		 * Будет работать только, свойство $add_link_to_plugin_actions=true.
		 * По умолчанию, если текст ссылки не задан, используется заголовок элемента меню
		 * или заголовок страницы.
		 *
		 * @var string
		 */
		public $title_plugin_action_link;

		/**
		 * Добавлять ссылку на странице плагинов (рядом с активировать/деактивировать)?
		 *
		 * Если true, будет автоматически добавлена ссылка на эту страницу, внутри страницы
		 * wp-admin/plugins.php (рядом с активировать/деактивировать). Чаще всего требуется
		 * добавить ссылку на страницу настроек. Если эта страница у вас является главной,
		 * то вы можете сделать это свойство активным.
		 *
		 * @link https://codex.wordpress.org/Plugin_API/Filter_Reference/plugin_action_links_(plugin_file_name)
		 * @var bool
		 */
		public $add_link_to_plugin_actions = false;

		public function __construct( Wbcr_Factory600_Plugin $plugin ) {
			parent::__construct( $plugin );
			$this->configure();

			$this->id = empty( $this->id ) ? str_replace( 'adminpage', '', strtolower( get_class( $this ) ) ) : $this->id;

			if ( $this->add_link_to_plugin_actions ) {
				if ( $plugin->isNetworkActive() ) {
					// plugin settings link
					add_filter(
						'network_admin_plugin_action_links_' . $this->plugin->get_paths()->basename,
						[
							$this,
							'addLinkToPluginActions',
						]
					);
				} else {
					// plugin settings link
					add_filter(
						'plugin_action_links_' . $this->plugin->get_paths()->basename,
						[
							$this,
							'addLinkToPluginActions',
						]
					);
				}
			}
		}

		/**
		 * May be used to configure the page before uts usage.
		 */
		public function configure() {
		}

		/**
		 * Includes the Factory Bootstrap assets for a current page.
		 *
		 * @param string $hook
		 *
		 * @return void
		 */
		public function actionAdminBootstrapScripts( $hook ) {
			$this->scripts->connect( 'bootstrap' );
			$this->styles->connect( 'bootstrap' );
		}

		/**
		 * Includes the assets for a current page (all assets except Factory Bootstrap assets).
		 *
		 * @param string $hook
		 *
		 * @return void
		 */
		public function actionAdminScripts( $hook ) {
			$this->scripts->connect();
			$this->styles->connect();
		}

		/**
		 * @return string
		 */
		public function getMenuScope() {
			return $this->plugin->getPluginName();
		}


		/**
		 * @return string
		 */
		public function getMenuTitle() {
			$menu_title = ! $this->menu_title ? $this->page_title : $this->menu_title;

			/**
			 * @since 4.0.9 - добавлен
			 */
			return apply_filters( 'wbcr/factory/pages/impressive/menu_title', $menu_title, $this->plugin->getPluginName(), $this->id );
		}

		/**
		 * @return string
		 */
		public function getPageTitle() {

			$page_title = ! $this->page_title ? $this->getMenuTitle() : $this->page_title;

			/**
			 * @since 4.0.9 - добавлен
			 */
			return apply_filters( 'wbcr/factory/pages/impressive/page_title', $page_title, $this->plugin->getPluginName(), $this->id );
		}

		/**
		 * @param string|null $id
		 *
		 * @return string
		 */
		public function getResultId( $id = null ) {
			$id = ! empty( $id ) ? $id : $this->id;

			if ( $this->plugin ) {
				return $id . '-' . $this->getMenuScope();
			}

			return $id;
		}

		/**
		 * Registers admin page for the admin menu.
		 */
		public function connect() {
			$result_id = $this->getResultId();

			$this->hidden = apply_filters( 'wbcr_factory_600_page_is_hidden_' . $result_id, $this->hidden );

			if ( $this->hidden ) {
				return;
			}

			$this->internal = apply_filters( 'wbcr_factory_600_page_is_internal_' . $result_id, $this->internal );

			if ( $this->internal ) {
				$this->menu_target    = null;
				$this->menu_post_type = null;
			}

			// makes redirect to the page
			$controller = $this->request->get( 'fy_page', null, true );

			if ( $controller && $controller == $this->id ) {
				$plugin = $this->request->get( 'fy_plugin', null, true );

				if ( $this->plugin->getPluginName() == $plugin ) {

					$action  = $this->request->get( 'fy_action', 'index', true );
					$is_ajax = $this->request->get( 'fy_ajax', false );

					if ( $is_ajax ) {
						$this->executeByName( $action );
						exit;
					} else {

						$params = (array) $this->request->getAll( true );

						unset( $params['fy_page'] );
						unset( $params['fy_plugin'] );
						unset( $params['fy_action'] );

						$this->redirectToAction( $action, $params );
					}
				}
			}

			// calls scripts and styles, adds pages to menu
			if ( $this->request->get( 'page', 'none' ) == $result_id ) {
				$this->assets( $this->scripts, $this->styles );

				if ( ! $this->scripts->isEmpty( 'bootstrap' ) || ! $this->styles->isEmpty( 'bootstrap' ) ) {
					add_action(
						'wbcr_factory_600_bootstrap_enqueue_scripts_' . $this->plugin->getPluginName(),
						[
							$this,
							'actionAdminBootstrapScripts',
						]
					);
				}

				// includes styles and scripts
				if ( ! $this->scripts->isEmpty() || ! $this->styles->isEmpty() ) {
					add_action( 'admin_enqueue_scripts', [ $this, 'actionAdminScripts' ] );
				}
			}

			// if this page for a custom menu page
			if ( $this->menu_post_type ) {
				$this->menu_target = 'edit.php?post_type=' . $this->menu_post_type;

				if ( empty( $this->capabilitiy ) ) {
					$this->capabilitiy = 'edit_' . $this->menu_post_type;
				}
			}

			// sets default capabilities
			if ( empty( $this->capabilitiy ) ) {
				$this->capabilitiy = 'manage_options';
			}

			// submenu
			if ( $this->menu_target ) {
				add_submenu_page(
					$this->menu_target,
					$this->getPageTitle(),
					$this->getMenuTitle(),
					$this->capabilitiy,
					$result_id,
					[
						$this,
						'show',
					]
				);
				// global menu
			} else {
				add_menu_page(
					$this->getPageTitle(),
					$this->getMenuTitle(),
					$this->capabilitiy,
					$result_id,
					[
						$this,
						'show',
					],
					null,
					$this->menu_position
				);

				if ( ! empty( $this->menu_sub_title ) ) {

					add_submenu_page(
						$result_id,
						$this->menu_sub_title,
						$this->menu_sub_title,
						$this->capabilitiy,
						$result_id,
						[
							$this,
							'show',
						]
					);
				}

				add_action( 'admin_head', [ $this, 'actionAdminHead' ] );
			}

			// executes an action
			if ( $this->current() ) {
				ob_start();
				$action = $this->request->get( 'action', 'index', true );
				$this->executeByName( $action );
				$this->result = ob_get_contents();
				ob_end_clean();
			}
		}

		protected function current() {
			$result_id = $this->getResultId();

			if ( $result_id == $this->request->get( 'page', 'none' ) ) {
				return true;
			}

			return false;
		}

		/**
		 * @param string $action
		 * @param array  $query_args
		 */
		public function redirectToAction( $action, $query_args = [] ) {

			wp_safe_redirect( $this->getActionUrl( $action, $query_args ) );
			exit;
		}

		/**
		 * @param string $action
		 * @param array  $query_args
		 */
		public function actionUrl( $action = null, $query_args = [] ) {
			echo $this->getActionUrl( $action, $query_args );
		}

		/**
		 * @param null  $action
		 * @param array $query_args
		 *
		 * @return string
		 */
		public function getActionUrl( $action = null, $query_args = [] ) {
			$url = $this->getBaseUrl( null, $query_args );

			if ( ! empty( $action ) ) {
				$url = add_query_arg( 'action', $action, $url );
			}

			return $url;
		}

		/**
		 * @return string
		 */
		public function getBaseUrl( $id = null, $query_args = [] ) {
			$result_id = $this->getResultId( $id );

			if ( $this->menu_target && ! $this->custom_target ) {
				$url = $this->network ? network_admin_url( $this->menu_target ) : admin_url( $this->menu_target );

				return add_query_arg( array_merge( [ 'page' => $result_id ], $query_args ), $url );
			}

			$url = $this->network ? network_admin_url( 'admin.php' ) : admin_url( 'admin.php' );

			return add_query_arg(
				array_merge(
					[
						'page' => $result_id,
						$query_args,
					]
				),
				$url
			);
		}

		public function actionAdminHead() {
			$result_id = $this->getResultId();

			if ( ! empty( $this->menu_icon ) ) {

				if ( preg_match( '/\\\f\d{3}/', $this->menu_icon ) ) {
					$icon_code = $this->menu_icon;
				} else {
					$icon_url = str_replace( '~/', $this->plugin->get_paths()->url . '/', $this->menu_icon );
				}
			}

			global $wp_version;

			if ( version_compare( $wp_version, '3.7.3', '>' ) ) {
				?>
				<style type="text/css" media="screen">
					<?php if ( ! empty( $icon_url ) ) { ?>

					a.toplevel_page_<?php echo esc_attr( $result_id ); ?> .wp-menu-image {
						background: url('<?php echo esc_url( $icon_url ); ?>') no-repeat center center !important;
					}

					<?php } ?>

					a.toplevel_page_<?php echo esc_attr( $result_id ); ?> .wp-menu-image:before {
						content: "<?php echo ! empty( $icon_code ) ? esc_attr( $icon_code ) : ''; ?>" !important;
					}

					a.toplevel_page_<?php echo esc_attr( $result_id ); ?> .wp-menu-image,
					a.toplevel_page_<?php echo esc_attr( $result_id ); ?>.wp-has-current-submenu .wp-menu-image,
					a.toplevel_page_<?php echo esc_attr( $result_id ); ?>.current .wp-menu-image {
						background-position: 8x 6px !important;
						background-size: 20px 20px !important
					}
				</style>
			<?php } else { ?>
				<style type="text/css" media="screen">
					a.toplevel_page_<?php echo esc_attr( $result_id ); ?> .wp-menu-image {
						background: url('<?php echo esc_url( $icon_url ); ?>') no-repeat 6px -33px !important;
					}

					a.toplevel_page_<?php echo esc_attr( $result_id ); ?>:hover .wp-menu-image,
					a.toplevel_page_<?php echo esc_attr( $result_id ); ?>.current .wp-menu-image {
						background-position: 6px -1px !important;
					}
				</style>
				<?php
			}

			if ( $this->internal ) {
				?>
				<style type="text/css" media="screen">
					li.toplevel_page_<?php echo esc_attr( $result_id ); ?> {
						display: none;
					}
				</style>
				<?php
			}
		}


		/**
		 * Add settings link in plugins list
		 *
		 * @param $links
		 *
		 * @return mixed
		 */
		function addLinkToPluginActions( $links ) {
			$link_title = ! empty( $this->title_plugin_action_link ) ? $this->title_plugin_action_link : $this->getMenuTitle();

			$settings_link = '<a href="' . $this->getBaseUrl() . '">' . $link_title . '</a>';
			array_unshift( $links, $settings_link );

			return $links;
		}
	}
}