<?php
/**
 * The admin-specific functionality of the plugin.
 *
 * @link       https://themeisle.com
 * @since      1.0.0
 *
 * @package    Orbit_Fox
 * @subpackage Orbit_Fox/app
 */

/**
 * The admin-specific functionality of the plugin.
 *
 * Defines the plugin name, version, and two examples hooks for how to
 * enqueue the admin-specific stylesheet and JavaScript.
 *
 * @package    Orbit_Fox
 * @subpackage Orbit_Fox/app
 * @author     Themeisle <friends@themeisle.com>
 */
class Orbit_Fox_Admin {

	/**
	 * The ID of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string $plugin_name The ID of this plugin.
	 */
	private $plugin_name;

	/**
	 * The version of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string $version The current version of this plugin.
	 */
	private $version;

	/**
	 * Initialize the class and set its properties.
	 *
	 * @param string $plugin_name The name of this plugin.
	 * @param string $version The version of this plugin.
	 *
	 * @since    1.0.0
	 */
	public function __construct( $plugin_name, $version ) {

		$this->plugin_name = $plugin_name;
		$this->version     = $version;

		add_action( 'rest_api_init', array( $this, 'init_dashboard_routes' ) );

	}

	/**
	 * Registers the REST routes used for updating the modules state and settings
	 */
	public function init_dashboard_routes() {
		register_rest_route(
			'obfx',
			'/toggle-module-state',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'update_module_callback' ),
				'permission_callback' => function () {
					return current_user_can( 'manage_options' );
				},
			)
		);
		register_rest_route(
			'obfx',
			'/set-module-settings',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'update_module_callback' ),
				'permission_callback' => function () {
					return current_user_can( 'manage_options' );
				},
			)
		);
	}

	/**
	 * Callback function for the REST requests.
	 * Updates the module data corresponding to the request and returns a response.
	 *
	 * @param WP_REST_Request $request The request
	 *
	 * @return WP_REST_Response The response to the request
	 */
	public function update_module_callback( WP_REST_Request $request ) {
		$data     = json_decode( $request->get_body(), true );
		$settings = new Orbit_Fox_Global_Settings();
		$modules  = $settings::$instance->module_objects;

		if ( ! isset( $data['slug'] ) || ! isset( $data['value'] ) ) {
			return new WP_REST_Response(
				array(
					'type'    => 'error',
					'message' => __( 'Bad request!', 'themeisle-companion' ),
				)
			);
		}

		if ( ! isset( $modules[ $data['slug'] ] ) ) {
			return new WP_REST_Response(
				array(
					'type'    => 'error',
					'message' => __( 'Module not found!', 'themeisle-companion' ),
				)
			);
		}

		$response = false;

		if ( $request->get_route() === '/obfx/toggle-module-state' ) {
			$response = $modules[ $data['slug'] ]->set_status( 'active', $data['value'] );
			$this->trigger_activate_deactivate( $data['value'], $modules[ $data['slug'] ] );
		}

		if ( $request->get_route() === '/obfx/set-module-settings' ) {
			unset( $data->slug );
			$response = $modules[ $data['slug'] ]->set_options( $data['value'] );
		}

		if ( ! $response ) {
			return new WP_REST_Response(
				array(
					'type'    => 'warning',
					'message' => __( 'Data unchanged!', 'themeisle-companion' ),
				)
			);
		}

		return new WP_REST_Response(
			array(
				'type' => 'success',
				'data' => $data,
			)
		);
	}

	/**
	 * Register the stylesheets for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_styles() {

		/**
		 * This function is provided for demonstration purposes only.
		 *
		 * An instance of this class should be passed to the run() function
		 * defined in Orbit_Fox_Loader as all of the hooks are defined
		 * in that particular class.
		 *
		 * The Orbit_Fox_Loader will then create the relationship
		 * between the defined hooks and the functions defined in this
		 * class.
		 */
		$screen = get_current_screen();
		if ( empty( $screen ) ) {
			return;
		}
		if ( in_array( $screen->id, array( 'toplevel_page_obfx_companion' ), true ) ) {
			$dependencies = include OBX_PATH . '/dashboard/build/dashboard.asset.php';
			wp_register_style( 'obfx-dashboard-style', OBFX_URL . 'dashboard/build/style-dashboard.css', array( 'wp-components' ), $dependencies['version'] );
			wp_enqueue_style( 'obfx-dashboard-style' );
			wp_register_style( 'obfx-dashboard-colors', OBFX_URL . 'obfx_modules/social-sharing/css/admin.css', array( 'wp-components' ), $dependencies['version'] );
			wp_enqueue_style( 'obfx-dashboard-colors' );
			wp_register_style( 'obfx-dashboard-social', OBFX_URL . 'obfx_modules/social-sharing/css/vendor/socicon/socicon.css', array( 'wp-components' ), $dependencies['version'] );
			wp_enqueue_style( 'obfx-dashboard-social' );
		}

		do_action( 'obfx_admin_enqueue_styles' );
	}

	/**
	 * Register the JavaScript for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_scripts() {

		/**
		 * This function is provided for demonstration purposes only.
		 *
		 * An instance of this class should be passed to the run() function
		 * defined in Orbit_Fox_Loader as all of the hooks are defined
		 * in that particular class.
		 *
		 * The Orbit_Fox_Loader will then create the relationship
		 * between the defined hooks and the functions defined in this
		 * class.
		 */

		$screen = get_current_screen();
		if ( empty( $screen ) ) {
			return;
		}
		if ( in_array( $screen->id, array( 'toplevel_page_obfx_companion' ), true ) ) {
			wp_enqueue_script( 'plugin-install' );
			wp_enqueue_script( 'updates' );

			$dependencies    = include OBX_PATH . '/dashboard/build/dashboard.asset.php';
			$global_settings = new Orbit_Fox_Global_Settings();
			$modules         = array_filter(
				$global_settings::$instance->module_objects,
				function ( $module ) {
					return $module->enable_module();
				}
			);
			$modules_options = array_map(
				function ( $module ) {
					return $module->options();
				},
				$modules
			);

			wp_register_script( 'obfx-dashboard', OBFX_URL . '/dashboard/build/dashboard.js', $dependencies['dependencies'], $this->version, true );
			wp_enqueue_script( 'obfx-dashboard' );
			wp_localize_script(
				'obfx-dashboard',
				'obfxDash',
				array(
					'path'             => OBFX_URL . '/dashboard/',
					'root'             => esc_url_raw( get_rest_url() ) . 'obfx/',
					'toggleStateRoute' => 'toggle-module-state',
					'setSettingsRoute' => 'set-module-settings',
					'nonce'            => wp_create_nonce( 'wp_rest' ),
					'modules'          => $modules,
					'data'             => get_option( 'obfx_data' ),
					'options'          => $modules_options,
					'plugins'          => $this->get_recommended_plugins(),
				)
			);
		}
		do_action( 'obfx_admin_enqueue_scripts' );
	}

	/**
	 * Add admin menu items for orbit-fox.
	 *
	 * @since   1.0.0
	 * @access  public
	 */
	public function menu_pages() {
		add_menu_page(
			__( 'Orbit Fox', 'themeisle-companion' ),
			__( 'Orbit Fox', 'themeisle-companion' ),
			'manage_options',
			'obfx_companion',
			array(
				$this,
				'page_modules_render',
			),
			'data:image/svg+xml;base64, ',
			'75'
		);
		add_submenu_page( 'obfx_companion', __( 'Orbit Fox General Options', 'themeisle-companion' ), __( 'General Settings', 'themeisle-companion' ), 'manage_options', 'obfx_companion' );
	}

	/**
	 * Add the initial dashboard notice to guide the user to the OrbitFox admin page.
	 *
	 * @since   2.3.4
	 * @access  public
	 */
	public function visit_dashboard_notice() {
		global $current_user;
		$user_id = $current_user->ID;
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}
		$screen = get_current_screen();
		if ( empty( $screen ) ) {
			return;
		}

		if ( in_array( $screen->id, array( 'toplevel_page_obfx_companion' ), true ) ) {
			add_user_meta( $user_id, 'obfx_ignore_visit_dashboard_notice', 'true', true );
			return;
		}
		if ( ! get_user_meta( $user_id, 'obfx_ignore_visit_dashboard_notice' ) ) { ?>
			<div class="notice notice-info" style="position:relative;">
				<p>
					<?php
					/*
					 * translators: Go to url.
					 */
					echo sprintf( esc_attr__( 'You have activated Orbit Fox plugin! Go to the %s to get started with the extra features.', 'themeisle-companion' ), sprintf( '<a href="%s">%s</a>', esc_url( add_query_arg( 'obfx_ignore_visit_dashboard_notice', '0', admin_url( 'admin.php?page=obfx_companion' ) ) ), esc_attr__( 'Dashboard Page', 'themeisle-companion' ) ) );
					?>
				</p>
				<a href="<?php echo esc_url( add_query_arg( 'obfx_ignore_visit_dashboard_notice', '0', admin_url( 'admin.php?page=obfx_companion' ) ) ); ?>"
				   class="notice-dismiss" style="text-decoration: none;">
					<span class="screen-reader-text">Dismiss this notice.</span>
				</a>
			</div>
			<?php
		}
	}

	/**
	 * Dismiss the initial dashboard notice.
	 *
	 * @since   2.3.4
	 * @access  public
	 */
	public function visit_dashboard_notice_dismiss() {
		global $current_user;
		$user_id = $current_user->ID;
		// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
		if ( isset( $_GET['obfx_ignore_visit_dashboard_notice'] ) && '0' == $_GET['obfx_ignore_visit_dashboard_notice'] ) {
			add_user_meta( $user_id, 'obfx_ignore_visit_dashboard_notice', 'true', true );
			wp_safe_redirect( admin_url( 'admin.php?page=obfx_companion' ) );
			exit;
		}
	}

	/**
	 * Calls the orbit_fox_modules hook.
	 *
	 * @since   1.0.0
	 * @access  public
	 */
	public function load_modules() {
		do_action( 'orbit_fox_modules' );
	}

	/**
	 * A method used for saving module options data
	 * and returning a well formatted response as an array.
	 *
	 * @codeCoverageIgnore
	 *
	 * @param array $data The options data to try and save via the module model.
	 *
	 * @return array
	 * @since   1.0.0
	 * @access  public
	 */
	public function try_module_save( $data ) {
		$response            = array();
		$global_settings     = new Orbit_Fox_Global_Settings();
		$modules             = $global_settings::$instance->module_objects;
		$response['type']    = 'error';
		$response['message'] = __( 'No module found! No data was updated.', 'themeisle-companion' );
		if ( isset( $modules[ $data['module-slug'] ] ) ) {
			$module = $modules[ $data['module-slug'] ];
			unset( $data['noance'] );
			unset( $data['module-slug'] );
			$response['type']    = 'warning';
			$response['message'] = __( 'Something went wrong, data might not be saved!', 'themeisle-companion' );
			$result              = $module->set_options( $data );
			if ( $result ) {
				$response['type']    = 'success';
				$response['message'] = __( 'Options updated, successfully!', 'themeisle-companion' );
			}
		}

		return $response;
	}

	/**
	 * Define render function for recommended tab.
	 */
	public function get_recommended_plugins() {
		$plugins = array(
			'optimole-wp',
			'wp-cloudflare-page-cache',
			'feedzy-rss-feeds',
			'translatepress-multilingual',
			'otter-blocks',
			'wp-maintenance-mode',
			'multiple-pages-generator-by-porthas',
		);

		$th_plugins = array(
			'wp-landing-kit' => array(
				'banner'      => esc_url( OBFX_URL ) . '/dashboard/assets/wp-landing.jpg',
				'name'        => 'WP Landing Kit',
				'description' => __( 'Turn WordPress into a landing page powerhouse with Landing Kit. Map domains to pages or any other published resource.', 'themeisle-companion' ),
				'author'      => 'Themeisle',
				'action'      => 'external',
				'url'         => tsdk_utmify( 'https://wplandingkit.com/', 'recommendedplugins', 'orbitfox' ),
				'premium'     => true,
			),
		);

		if ( class_exists( 'woocommerce' ) ) {
			$th_plugins['sparks'] = array(
				'banner'      => esc_url( OBFX_URL ) . '/dashboard/assets/sparks.jpeg',
				'name'        => 'Sparks for WooCommerce',
				'description' => __( 'Conversion-focused features for your online store.', 'themeisle-companion' ),
				'author'      => 'Themeisle',
				'action'      => 'external',
				'url'         => tsdk_utmify( 'https://themeisle.com/plugins/sparks-for-woocommerce/', 'recommendedplugins', 'orbitfox' ),
				'premium'     => true,
			);
		}
		$install_instance = new Orbit_Fox_Plugin_Install();

		shuffle( $plugins );

		$data = array();
		foreach ( $plugins as $plugin ) {
			$current_plugin = $install_instance->call_plugin_api( $plugin );
			if ( ! isset( $current_plugin->name ) ) {
				continue;
			}

			$data[ $plugin ] = array(
				'banner'      => $current_plugin->banners['low'],
				'name'        => html_entity_decode( $current_plugin->name ),
				'description' => html_entity_decode( $current_plugin->short_description, ENT_QUOTES ),
				'version'     => $current_plugin->version,
				'author'      => html_entity_decode( wp_strip_all_tags( $current_plugin->author ) ),
				'action'      => $install_instance->check_plugin_state( $plugin ),
				'path'        => $install_instance->get_plugin_path( $plugin ),
				'activate'    => $install_instance->get_plugin_action_link( $plugin ),
				'deactivate'  => $install_instance->get_plugin_action_link( $plugin, 'deactivate' ),
			);
		}

		foreach ( $th_plugins as $plugin_slug => $plugin_data ) {
			$data[ $plugin_slug ] = $plugin_data;
		}

		return $data;
	}

	/**
	 * A method to trigger module activation or deavtivation hook
	 * based in active status.
	 *
	 * @codeCoverageIgnore
	 *
	 * @param boolean $active_status The active status.
	 * @param Orbit_Fox_Module_Abstract $module The module referenced.
	 *
	 * @since   2.3.3
	 * @access  public
	 */
	public function trigger_activate_deactivate( $active_status, Orbit_Fox_Module_Abstract $module ) {
		if ( $active_status === true ) {
			do_action( $module->get_slug() . '_activate' );
		} else {
			do_action( $module->get_slug() . '_deactivate' );
		}
	}

	/**
	 * Method to display modules page.
	 *
	 * @codeCoverageIgnore
	 *
	 * @since   1.0.0
	 * @access  public
	 */
	public function page_modules_render() {
		echo '<div id="obfx-dash"></div>'; // entry point for the React dashboard
	}

}
