<?php
/**
 * BoldGrid Source Code
 *
 * @package Boldgrid_Inspirations_Built
 * @copyright BoldGrid.com
 * @version $Id$
 * @author BoldGrid.com <wpb@boldgrid.com>
 */

/**
 * The BoldGrid Inspiration Built class.
 */
class Boldgrid_Inspirations_Built {

	/**
	 * An instance of Boldgrid_Inspirations_Inspiration.
	 *
	 * @var Inspiration
	 */
	protected $inspiration;

	/**
	 * The data gathered about the users scenario.
	 *
	 * @var array
	 */
	protected $mode_data;

	/**
	 * The users installation settings.
	 *
	 * @var array
	 */
	protected $install_options;

	/**
	 * Bool that checks if staging plugin is active.
	 *
	 * @var Bool
	 */
	protected $staging_plugin_active = false;

	/**
	 * Array of theme names.
	 *
	 * @var array
	 */
	protected $current_theme_names;

	/**
	 * Take in the main plugin as a param.
	 *
	 * @param Boldgrid_Inspirations_Inspiration $inspiration
	 */
	public function __construct( $inspiration ) {
		$this->inspiration = $inspiration;
	}

	public $design_first = true;

	/**
	 * Add actions/hooks
	 */
	public function add_hooks() {

		// Find the users individual scenario and set up the menu.
		add_action( 'admin_menu',
			array(
				$this,
				'admin_menu',
			)
		);

		// Add the needed styles.
		add_action( 'admin_enqueue_scripts',
			array(
				$this,
				'enqueue_scripts',
			)
		);

		// Should the user be starting with inspirations? If so, give them a notice at the top of
		// the page.
		add_action( 'admin_notices',
			array(
				$this,
				'you_should_start_with_inspirations',
			)
		);

		add_action( 'admin_init', array( $this, 'remove_notices' ) );
	}

	/**
	 * Adds inline CSS to admin_head using the active color palette.
	 *
	 * @since xxx
	 */
	public function admin_colors() {
		global $_wp_admin_css_colors;
		$this->admin_colors = $_wp_admin_css_colors;
		$user = get_user_option( 'admin_color' );
		echo '<style>
			.pageset-option.active,.coin-option.active,.sub-category.active,.pageset-option.blue,.coin-option.blue,.blue { background-color:' . $this->admin_colors[ $user ]->colors[3] . ' !important; }
			.devices button:focus { border-bottom-color: ' . $this->admin_colors[ $user ]->colors[3] . '; }
			</style>';
	}

	/**
	 * Generate the scenario data and add the users menu items.
	 */
	public function admin_menu() {
		$this->staging_plugin_active = $this->check_staging_plugin();

		$this->add_top_menu_item( 'boldgrid-inspirations' );

		self::add_sub_menu_items( 'boldgrid-inspirations' );
	}

	/**
	 * Checks to see if the staging plugin is active.
	 *
	 * @return boolean
	 */
	public function check_staging_plugin() {
		$staging_plugin_active = is_plugin_active( 'boldgrid-staging/boldgrid-staging.php' );

		return ( $staging_plugin_active && class_exists( 'Boldgrid_Staging_Page_And_Post_Staging' ) );
	}

	/**
	 * Returns the name of a theme if and only if the theme is a boldgrid theme.
	 *
	 * @param WP_Theme $wp_theme
	 *
	 * @return string
	 */
	public static function get_boldgrid_theme_name( $wp_theme ) {
		$current_boldgrid_theme = '';

		$current_theme = $wp_theme;

		if ( is_a( $current_theme, 'WP_Theme' ) &&
			 strpos( strtolower( $current_theme->get( 'TextDomain' ) ), 'boldgrid' ) !== false ) {
			$current_boldgrid_theme = $current_theme->get( 'Name' );
		}

		return $current_boldgrid_theme;
	}

	/**
	 * Get all pages by status.
	 *
	 * @param string $post_status
	 *
	 * @return array
	 */
	public static function get_installed_pages( $post_status ) {
		$all_pages = get_pages(
			array(
				'post_status' => array(
					$post_status,
					'draft',
				),
			) );

			if ( false == is_array( $all_pages ) ) {
				$all_pages = array();
			}

			$boldgrid_pages = array();

			foreach ( $all_pages as $page ) {
				$post_meta = get_post_meta( $page->ID );
				if ( isset( $post_meta['boldgrid_page_id'] ) ) {
					$boldgrid_pages[] = $post_meta['boldgrid_page_id'][0];
				}
			}

			return $boldgrid_pages;
	}

	/**
	 * Find the users installation data.
	 *
	 * @return array
	 */
	public static function find_all_install_options() {
		// Get Installed Settings.
		( $active_install_options = get_option( 'boldgrid_install_options' ) ) ||
			 ( $active_install_options = array() );

			 $active_install_options['installed_pages'] = self::get_installed_pages( 'publish' );
			 $active_install_options['theme_stylesheet'] = get_stylesheet();
			 $active_install_options['theme_name'] = self::get_boldgrid_theme_name( wp_get_theme() );

			 $install_options['active_options'] = $active_install_options;

			 ( $staging_install_options = get_option( 'boldgrid_staging_boldgrid_install_options' ) ) ||
			 ( $staging_install_options = array() );

			 $staging_install_options['installed_pages'] = self::get_installed_pages( 'staging' );
			 $staging_install_options['theme_name'] = self::get_boldgrid_theme_name(
			 $staging_theme = self::get_staging_theme() );

			 if ( $staging_theme ) {
				 $staging_install_options['theme_stylesheet'] = $staging_theme->get_stylesheet();
				}

				$install_options['boldgrid_staging_options'] = $staging_install_options;
				$install_options['theme_release_channel'] = Boldgrid_Inspirations_Theme_Install::fetch_theme_channel();

				return $install_options;
	}

	/**
	 * Check to see if the user has a staged site.
	 *
	 * @return boolean
	 */
	public function has_staged_site() {
		$has_staged_site = false;

		if ( $this->staging_plugin_active ) {
			$staged_pages = Boldgrid_Staging_Page_And_Post_Staging::get_all_staged_pages();
			$staged_pages = is_array( $staged_pages ) ? $staged_pages : array();
			$has_staged_site = ( bool ) count( $staged_pages );
		}

		return $has_staged_site;
	}

	/**
	 * Our active site was installed by BoldGrid.
	 *
	 * @since x.x.x
	 */
	public function has_active_bg_site( $install_options ) {
		$installed_pages = get_option( 'boldgrid_installed_page_ids', array() );

		if ( empty( $installed_pages ) ) {
			return false;
		}

		// Generate a CSV of pages installed by BoldGrid.
		$installed_pages = implode( ',', $installed_pages );

		$pages = get_pages( array(
			'include' => $installed_pages,
			'post_status' => 'publish',
		));

		// If we have at least one 'BoldGrid installed page' published, return true.
		return ( ! empty( $pages ) );
	}

	/**
	 * Check to see if the user has an active site.
	 *
	 * @return boolean
	 */
	public static function has_active_site() {
		// Get all pages.
		$pages = get_pages();

		// If there are no pages, then return false.
		if ( empty( $pages ) ) {
			return false;
		}

		// Get default, attribution, and coming soon pages.
		$default_page = get_page_by_title( 'Sample Page' );
		$attribution_page = get_page_by_title( 'Attribution' );
		$coming_soon_page = get_page_by_title( 'WEBSITE COMING SOON' );

		// Initialize $ids_to_remove.
		$ids_to_filter = array();

		// Get the boldgrid_attribution option data.
		$attribution = get_option( 'boldgrid_attribution' );

		// If there is attribution data, then add the page id to $ids_to_filter.
		if ( ! empty( $attribution ) && isset( $attribution['page']['id'] ) ) {
			$ids_to_filter[] = $attribution['page']['id'];
		}

		// Add the page ids of the default, attribution, and coming soon pages from title match,
		// to the array.
		foreach ( array(
			$default_page,
			$attribution_page,
			$coming_soon_page,
		) as $page ) {
			if ( null !== $page ) {
				$ids_to_filter[] = $page->ID;
			}
		}

		// Build an array of page objects that do not match page ids in $ids_to_filter.
		$active_pages = array();

		foreach ( $pages as $page ) {
			if ( ! in_array( $page->ID, $ids_to_filter ) ) {
				$active_pages[] = $page;
			}
		}

		// Return whether or not we have any pages in the array.
		return ! empty( $active_pages );
	}

	/**
	 *
	 */
	public static function has_blank_active_site() {
		/*
		 * Get a list of all active pages.
		 *
		 * If we have an active Attribution page, exclude that from the list.
		 */
		$attribution_page = get_page_by_title( 'Attribution' );

		if ( is_object( $attribution_page ) ) {
			$exclude = $attribution_page->ID;
		} else {
			$exclude = '';
		}

		$pages = get_pages( array(
			'exclude' => $exclude,
			'post_status' => 'publish',
		));

		// If there are no active pages, return true.
		if ( empty( $pages ) ) {
			return true;
		}

		// Get default pages we're expecting.
		$default_pages = array(
			'sample' => get_page_by_title( 'Sample Page' ),
			'coming_soon' => get_page_by_title( 'WEBSITE COMING SOON' ),
		);

		// How many of our default pages were found.
		$default_pages_found = 0;
		foreach ( $default_pages as $page ) {
			if ( is_object( $page ) ) {
				$default_pages_found++;
			}
		}

		/*
		 * If the count of our pages found is the same as our count of default pages found, then we
		 * have a blank site.
		 */
		if ( $default_pages_found == count( $pages ) ) {
			return true;
		}
		/*
		 * If the number of pages we have is <= the number of default pages found, then we have
		 * a blank site.
		 *
		 * EQUALS
		 * If we have 2 pages and we have 2 default_pages_found, then every page we have is a default
		 * page.
		 *
		 * LESS THAN
		 * If we have 1 page and we have 2 default pages, then one of our default pages is the current
		 * page.
		 */
		if ( count( $pages ) <= $default_pages_found ) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Get the staging theme name from the staging plugin.
	 *
	 * @return WP_Theme | null
	 */
	public static function get_staging_theme() {
		return class_exists( 'Boldgrid_Staging_Theme' ) ? Boldgrid_Staging_Theme::get_staging_theme() : null;
	}

	/**
	 * Get the menu slug needed to make sure that the first item has the same slug as the primary.
	 *
	 * @param string $top_level
	 *
	 * @return string
	 */
	public static function get_menu_slug( &$top_level ) {
		if ( $top_level ) {
			$slug = $top_level;
			$top_level = '';
		} else {
			$slug = '';
		}

		return $slug;
	}

	/**
	 * Add the styles and the scripts.
	 */
	public function enqueue_scripts() {
		$current_screen = get_current_screen();

		if ( 'toplevel_page_boldgrid-inspirations' != $current_screen->base ) {
			return;
		}

		if ( isset( $_REQUEST['task'] ) ) {
			return;
		}

		// Add active color palette css.
		add_action('admin_head',
			array(
				$this,
				'admin_colors',
			)
		);

		add_thickbox();

		// Css.
		wp_register_style(
			'boldgrid-inspirations-css',
			plugins_url(
				'/assets/css/boldgrid-inspirations.css',
				BOLDGRID_BASE_DIR . '/boldgrid-inspirations.php'
			),
			array(),
			BOLDGRID_INSPIRATIONS_VERSION
		);

		wp_enqueue_style( 'boldgrid-inspirations-css' );

		wp_enqueue_style( 'boldgrid-inspirations-font-awesome' );

		wp_enqueue_style( 'dashicons' );

		// Js.
		wp_enqueue_script( 'boldgrid-inspirations',
			plugins_url(
				'assets/js/boldgrid-inspirations.js',
				BOLDGRID_BASE_DIR . '/boldgrid-inspirations.php'
			),
			array(
				'wp-util',
			),
			BOLDGRID_INSPIRATIONS_VERSION,
			true
		);

		wp_localize_script( 'boldgrid-inspirations',
			'Inspiration',
			array(
				'active' => 'Active',
				'staging' => 'Staging',
				'coins' => __( 'Coins', 'boldgrid-inspirations' ),
				'fetchingThemes' => __( 'Fetching themes...', 'boldgrid-inspirations' ),
				'fetchingCategories' => __( 'Fetching categories...', 'boldgrid-inspirations' ),
				'errorFetchingThemes' => __( 'There was an error fetching themes.', 'boldgrid-inspirations' ),
				'errorFetchingCategories' => __( 'There was an error fetching categories.', 'boldgrid-inspirations' ),
				'errorFetchingPagesets' => __( 'There was an error fetching pagesets.', 'boldgrid-inspirations' ),
				'errorBuildingPreview' => __( 'There was an error building your custom website preview.', 'boldgrid-inspirations' ),
				'previewTimeout' => __( 'Connection timed out when attempting to load custom website preview.', 'boldgrid-inspirations' ),
				'select' => __( 'Select', 'boldgrid-inspirations' ),
				'tryFewMinutes' => __( 'Please try again in a few minutes.', 'boldgrid-inspirations' ),
				'tryFewSeconds' => __( 'Please try again in a few seconds.', 'boldgrid-inspirations' ),
				'tryAgain' => __( 'Try again', 'boldgrid-inspirations' ),
			)
		);

		/*
		 * Add Fancybox.
		 *
		 * This includes both js and css.
		 */
		wp_register_style(
			'boldgrid-inspirations-fancybox',
			plugins_url(
				'/assets/css/fancybox.css',
				BOLDGRID_BASE_DIR . '/boldgrid-inspirations.php'
			),
			array(),
			BOLDGRID_INSPIRATIONS_VERSION
		);

		wp_enqueue_style( 'boldgrid-inspirations-fancybox' );

		wp_enqueue_script( 'boldgrid-inspirations-fancybox',
			plugins_url(
				'assets/js/fancybox.js',
				BOLDGRID_BASE_DIR . '/boldgrid-inspirations.php'
			),
			array(
				'jquery',
			),
			BOLDGRID_INSPIRATIONS_VERSION,
			true
		);

		$this->enqueue_jquery_toggles();

		// Js.
		wp_enqueue_script( 'boldgrid-lazyload',
			plugins_url(
				'assets/js/lazyload.js',
				BOLDGRID_BASE_DIR . '/boldgrid-inspirations.php'
			),
			array( 'jquery' ),
			BOLDGRID_INSPIRATIONS_VERSION,
			true
		);
	}

	/**
	 * Enqueue jQuery Toggles.
	 *
	 * This is used to add the toggles under Features within step 2 of Inspirations.
	 *
	 * @since 1.3.7
	 */
	public function enqueue_jquery_toggles() {
		wp_register_style(
			'boldgrid-inspirations-toggles',
			plugins_url(
				'/assets/css/jquery-toggles/toggles-full.css',
				BOLDGRID_BASE_DIR . '/boldgrid-inspirations.php'
			),
			array(),
			BOLDGRID_INSPIRATIONS_VERSION
		);

		wp_enqueue_style( 'boldgrid-inspirations-toggles' );

		wp_enqueue_script( 'boldgrid-inspirations-toggles',
			plugins_url(
				'assets/js/jquery-toggles/toggles.js',
				BOLDGRID_BASE_DIR . '/boldgrid-inspirations.php'
			),
			array( 'jquery', ),
			BOLDGRID_INSPIRATIONS_VERSION,
			true
		);
	}

	/**
	 * Add the top level menui item "Inspirations".
	 *
	 * @param unknown $top_level
	 */
	public function add_top_menu_item( $top_level ) {
		add_menu_page( 'Inspirations', 'Inspirations', 'manage_options', $top_level,
			array(
				$this,
				'inspiration_page',
			), 'dashicons-lightbulb', '21.36' );
	}

	/**
	 * Add Layouts Menu Item after pages.
	 */
	public static function add_sub_menu_items( $top_level ) {
		$slug = self::get_menu_slug( $top_level );

		add_submenu_page( $top_level,
			'Install New Site',
			'Install New Site',
			'manage_options',
			$slug ? $slug : 'admin.php?page=boldgrid-inspirations'
		);
	}

	/**
	 * Callback that will render the Boldgrid Inspiration phase.
	 *
	 * @see           Boldgrid_Inspirations_Api::boldgrid_api_call().
	 * @global string $user_email.
	 *
	 * @return null
	 */
	public function inspiration_page() {
		global $user_email;

		// If we are prompting the user for an API key, then show only that prompt.
		if ( $this->inspiration->api->get_have_enqueued_api_key_prompt() ) {
			return;
		}

		$boldgrid_configs = Boldgrid_Inspirations_Config::get_format_configs();

		$api_call_results = Boldgrid_Inspirations_Api::boldgrid_api_call(
			$boldgrid_configs['ajax_calls']['get_version']
		);

		if ( is_null( $api_call_results ) ) {
			error_log( __METHOD__ . ': Error getting BoldGrid version.' );

			wp_die( $this->inspiration->api->notify_connection_issue() );
		}

		if ( isset( $_POST['task'] ) && 'deploy' == $_POST['task'] ) {
			// Check nonce.
			check_admin_referer( 'deploy', 'deploy' );

			$this->inspiration->deploy_script();
		} else {
			$theme_channel = Boldgrid_Inspirations_Theme_Install::fetch_theme_channel();

			$mode_data = $this->generate_scenarios();

			// Underscores Templates.
			include BOLDGRID_BASE_DIR . '/pages/templates/boldgrid-inspirations.php';

			// Page template.
			include BOLDGRID_BASE_DIR . '/pages/boldgrid-inspirations.php';
		}

		return;
	}

	/**
	 * Remove all admin notices from BoldGrid Inspirations page.
	 *
	 * If we allow admin notices to the Inspirations page, the page begins to feel a bit wonky. Don't
	 * allow any notices on this page.
	 *
	 * @since 1.2.6
	 *
	 * @global string $pagenow
	 */
	public function remove_notices() {
		global $pagenow;

		$page = ( isset( $_GET['page'] ) ? $_GET['page'] : null );

		// Are we on the Inspirations page?
		$is_inspirations_page = ( 'admin.php' === $pagenow && 'boldgrid-inspirations' === $page );

		// Are we prompting the user to enter their API key?
		$prompting_for_key = $this->inspiration->api->get_have_enqueued_api_key_prompt();

		/*
		 * If we're on the Inspirations page and we're not prompting the user for a key, remove all
		 * notices.
		 *
		 * If we were prompting them for a key, then we don't want to remove the notice to prompt
		 * them for a key.
		 */
		if ( $is_inspirations_page && ! $prompting_for_key ) {
			remove_all_actions( 'admin_notices' );
		}
	}

	/**
	 * Determine the user's scenario.
	 *
	 * # The user has a blank website.							has_blank_active_site()
	 * # The user has an active site built with BoldGrid.		has_active_bg_site()
	 * # The user has an active site not build with BoldGrid.	Deduced by has_blank_active_site()
	 * 															and has_active_bg_site().
	 * # The user has a staging site.
	 *
	 * @return array
	 */
	public function generate_scenarios() {
		$this->install_options = self::find_all_install_options();

		// Create return array.
		return array(
			'has_active_bg_site' => $this->has_active_bg_site( $this->install_options ),
			'has_staged_site' => $this->has_staged_site(),
			'has_blank_active_site' => self::has_blank_active_site(),
			'open-section' => ( ! empty( $_GET['force-section'] ) ) ? sanitize_text_field( $_GET['force-section'] ) : '',
			'staging_active' => $this->check_staging_plugin(),
			'staging_installed' => file_exists( WP_PLUGIN_DIR . '/boldgrid-staging' ),
			'url' => get_admin_url() . 'admin.php?page=boldgrid-inspirations',
		);
	}

	/**
	 * Should the user be starting with inspirations? If so, give them a notice at the top of the
	 * page.
	 *
	 * @global pagenow
	 */
	public function you_should_start_with_inspirations() {
		$pages_to_show_this_notice = array(
			'post-new.php',
			'theme-install.php',
		);

		global $pagenow;

		// Abort if necessary.
		if ( ! in_array( $pagenow, $pages_to_show_this_notice ) ) {
			return;
		}

		// Generate our scenario data.
		$scenarios = $this->generate_scenarios();

		// Display our alert.
		if ( false === $scenarios['has_active_bg_site'] && false === $scenarios['has_staged_site'] ) {
			?>
<div class="error notice is-dismissible">
	<p>
		We've recognized that you haven't installed an Active or Staging site
		with Inspirations. Before adding additional pages and themes, we
		recommend that you start with <a
			href="admin.php?page=boldgrid-inspirations&boldgrid-tab=install"
			class="dashicons-before dashicons-lightbulb"
			style="text-decoration: none;">Inspirations</a>.
	</p>
</div>
<?php
		}
	}
}
