<?php

namespace AAWP;

use AAWP\Admin\Settings;

/**
 * Main AAWP Plugin class
 *
 * @since       2.0.0
 */
final class Plugin {

	/**
	 * AAWP instance.
	 *
	 * @access protected
	 * @since  3.9.0
	 * @var    AAWP The one true AAWP
	 */
	protected static $instance;

	/**
	 * The settings instance variable.
	 *
	 * @access public
	 * @since  3.9.0
	 * @var    AAWP\Admin\Settings
	 */
	public $settings;

	/**
	 * The api instance variable.
	 *
	 * @access public
	 * @since  3.9.0
	 * @var    AAWP_API
	 */
	public $api;

	/**
	 * The products instance variable.
	 *
	 * @access public
	 * @since  3.9.0
	 * @var    AAWP_DB_Products
	 */
	public $products;

	/**
	 * The lists instance variable.
	 *
	 * @access public
	 * @since  3.9.0
	 * @var    AAWP_DB_Lists
	 */
	public $lists;

	/**
	 * Main AAWP Instance
	 *
	 * Insures that only one instance of AAWP exists in memory at any one
	 * time. Also prevents needing to define globals all over the place.
	 *
	 * @since 1.0
	 * @static
	 * @staticvar array $instance
	 * @uses AAWP::setup_globals() Setup the globals needed
	 * @uses AAWP::includes() Include the required files
	 * @uses AAWP::setup_actions() Setup the hooks and actions
	 * @return AAWP
	 */
	public static function instance() {

		if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Plugin ) ) {
			self::$instance = new Plugin();

			if ( version_compare( PHP_VERSION, '5.6', '<' ) ) {

				add_action( 'admin_notices', [ 'AAWP', 'below_php_version_notice' ] );

				return self::$instance;
			}

			self::$instance->setup_constants();
			self::$instance->includes();

			add_action( 'plugins_loaded', [ self::$instance, 'setup_objects' ] );
			add_action( 'plugins_loaded', [ self::$instance, 'load_textdomain' ] );
		}

		return self::$instance;
	}

	/**
	 * Throw error on object clone
	 *
	 * The whole idea of the singleton design pattern is that there is a single
	 * object therefore, we don't want the object to be cloned.
	 *
	 * @since 3.9.0
	 * @access protected
	 * @return void
	 */
	public function __clone() {
		// Cloning instances of the class is forbidden.
		_doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin&#8217; huh?', 'aawp' ), '1.0' );
	}

	/**
	 * Disable unserializing of the class
	 *
	 * @since 3.9.0
	 * @access protected
	 * @return void
	 */
	public function __wakeup() {
		// Unserializing instances of the class is forbidden.
		_doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin&#8217; huh?', 'aawp' ), '1.0' );
	}

	/**
	 * Show a warning to sites running PHP < 5.3
	 *
	 * @static
	 * @access private
	 * @since 3.9.0
	 * @return void
	 */
	public static function below_php_version_notice() {
		?>
		<div class="error">
			<p>
				<?php sprintf( /* translators: %1$s - PHP Version Number. */ esc_html__( 'Your version of PHP is below the minimum version of PHP required by our plugin. Please contact your hosting company and request that your version will be upgraded to %1$s or later.', 'aawp' ), '5.6' ); ?>
			</p>
		</div>
		<?php
	}

	/**
	 * Setup plugin constants
	 *
	 * @access private
	 * @since 3.9.0
	 * @return void
	 */
	private function setup_constants() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh

		// Docs URL.
		if ( ! defined( 'AAWP_DOCS_URL' ) ) {
			define( 'AAWP_DOCS_URL', 'https://getaawp.com/docs/' );
		}

		// Plugin Settings URL.
		if ( ! defined( 'AAWP_ADMIN_SETTINGS_URL' ) ) {
			define( 'AAWP_ADMIN_SETTINGS_URL', admin_url( 'admin.php?page=aawp-settings' ) );
		}

		// Store.
		if ( ! defined( 'AAWP_STORE' ) ) {

			$amazon_settings   = get_option( 'aawp_api' );
			$aawp_api_settings = get_option( 'aawp_aawp_api' );

			if ( ! empty( $amazon_settings['status'] ) ) {
				$aawp_store = $amazon_settings['country'];
			} elseif ( ! empty( $aawp_api_settings['connect'] ) ) {
				$aawp_store = $aawp_api_settings['country'];
			} else {
				$aawp_store = 'de';
			}

			define( 'AAWP_STORE', $aawp_store );
		}

		// Shortcode.
		if ( ! defined( 'AAWP_SHORTCODE' ) ) {
			$general_settings = get_option( 'aawp_general' );
			$aawp_shortcode   = ( ! empty( $general_settings['shortcode'] ) ) ? $general_settings['shortcode'] : 'amazon';

			define( 'AAWP_SHORTCODE', $aawp_shortcode );
		}

		// Placeholder Tracking ID.
		if ( ! defined( 'AAWP_PLACEHOLDER_TRACKING_ID' ) ) {
			define( 'AAWP_PLACEHOLDER_TRACKING_ID', 'AAWP_PLACEHOLDER_TRACKING_ID' );
		}
	}

	/**
	 * Include required files
	 *
	 * @access private
	 * @since 3.9.0
	 * @return void
	 */
	private function includes() {

		// Core files.
		require_once AAWP_PLUGIN_DIR . 'includes/helper.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions.php';
		require_once AAWP_PLUGIN_DIR . 'includes/class.aawp-db.php';
		require_once AAWP_PLUGIN_DIR . 'includes/class.aawp-db-products.php';
		require_once AAWP_PLUGIN_DIR . 'includes/class.aawp-db-lists.php';
		require_once AAWP_PLUGIN_DIR . 'includes/class.aawp-api.php';
		require_once AAWP_PLUGIN_DIR . 'includes/hooks.php';
		require_once AAWP_PLUGIN_DIR . 'includes/class.aawp-wrapper.php';
		require_once AAWP_PLUGIN_DIR . 'includes/class.aawp-core.php';
		require_once AAWP_PLUGIN_DIR . 'includes/class.aawp-functions.php';
		require_once AAWP_PLUGIN_DIR . 'includes/api-functions.php';
		require_once AAWP_PLUGIN_DIR . 'includes/class.aawp-review-crawler.php';
		require_once AAWP_PLUGIN_DIR . 'includes/cache-functions.php';
		require_once AAWP_PLUGIN_DIR . 'includes/class.cache-handler.php';
		require_once AAWP_PLUGIN_DIR . 'includes/class.template-functions.php';
		require_once AAWP_PLUGIN_DIR . 'includes/class.template-handler.php';
		require_once AAWP_PLUGIN_DIR . 'includes/list-functions.php';
		require_once AAWP_PLUGIN_DIR . 'includes/list-helper-functions.php';
		require_once AAWP_PLUGIN_DIR . 'includes/product-functions.php';
		require_once AAWP_PLUGIN_DIR . 'includes/product-helper-functions.php';
		require_once AAWP_PLUGIN_DIR . 'includes/shortcodes.php';
		require_once AAWP_PLUGIN_DIR . 'includes/class.aawp-product.php';
		require_once AAWP_PLUGIN_DIR . 'includes/scripts.php';

		// Functions.
		require_once AAWP_PLUGIN_DIR . 'includes/functions/deprecated/functions.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/deprecated/class.widget.php';

		require_once AAWP_PLUGIN_DIR . 'includes/functions/widgets/functions.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/widgets/class.widget-bestseller.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/widgets/class.widget-box.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/widgets/class.widget-new-releases.php';

		require_once AAWP_PLUGIN_DIR . 'includes/functions/components/affiliate-links-extended.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/components/amp.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/components/customizations.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/components/geotargeting.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/components/items.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/components/stores.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/components/templating.php';

		require_once AAWP_PLUGIN_DIR . 'includes/functions/class.bestseller.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/class.box.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/class.extended.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/class.fields.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/class.link.php';
		require_once AAWP_PLUGIN_DIR . 'includes/functions/class.new-releases.php';

		require_once AAWP_PLUGIN_DIR . 'src/Loader.php';

		// Admin files.
		if ( is_admin() || defined( 'WP_CLI' ) && WP_CLI ) {

			// Bootstrap.
			require_once AAWP_PLUGIN_DIR . 'includes/admin/plugins.php';

			// Core.
			require_once AAWP_PLUGIN_DIR . 'includes/admin/functions.php';
			require_once AAWP_PLUGIN_DIR . 'includes/admin/actions.php';
			require_once AAWP_PLUGIN_DIR . 'includes/admin/ajax.php';
			require_once AAWP_PLUGIN_DIR . 'includes/admin/hooks.php';
			require_once AAWP_PLUGIN_DIR . 'includes/admin/post-search.php';
			require_once AAWP_PLUGIN_DIR . 'includes/admin/dashboard-page.php';
			require_once AAWP_PLUGIN_DIR . 'includes/admin/sysinfo.php';
			require_once AAWP_PLUGIN_DIR . 'includes/admin/modals.php';

			// Pages.
			require_once AAWP_PLUGIN_DIR . 'includes/admin/list-edit.php';
			require_once AAWP_PLUGIN_DIR . 'includes/admin/list-overview.php';
			require_once AAWP_PLUGIN_DIR . 'includes/admin/product-edit.php';
			require_once AAWP_PLUGIN_DIR . 'includes/admin/product-overview.php';

			// Upgrades.
			require_once AAWP_PLUGIN_DIR . 'includes/admin/upgrades.php';
		}//end if
	}

	/**
	 * Setup all objects
	 *
	 * @access public
	 * @since 1.6.2
	 * @return void
	 */
	public function setup_objects() {

		self::$instance->api      = new \AAWP_API();
		self::$instance->products = new \AAWP_DB_Products();
		self::$instance->lists    = new \AAWP_DB_Lists();

		if ( is_admin() || defined( 'WP_CLI' ) && WP_CLI ) {
			self::$instance->settings = new Settings();
		}

		$loader = new Loader();
		$loader->init();
	}

	/**
	 * Loads the plugin language files
	 *
	 * @access public
	 * @since 1.0
	 * @return void
	 */
	public function load_textdomain() {

		// Set filter for plugin's languages directory.
		$lang_dir = dirname( plugin_basename( AAWP_PLUGIN_FILE ) ) . '/languages/';

		/**
		 * Filters the languages directory path to use for AAWP.
		 *
		 * @param string $lang_dir The languages directory path.
		 */
		$lang_dir = apply_filters( 'aawp_languages_directory', $lang_dir );

		// Traditional WordPress plugin locale filter.

		global $wp_version;

		$get_locale = get_locale();

		if ( $wp_version >= 4.7 ) {
			$get_locale = get_user_locale();
		}

		/**
		 * Defines the plugin language locale used in AAWP.
		 *
		 * @var $get_locale The locale to use. Uses get_user_locale()` in WordPress 4.7 or greater,
		 *                  otherwise uses `get_locale()`.
		 */
		$locale = apply_filters( 'plugin_locale', $get_locale, 'aawp' );
		$mofile = sprintf( '%1$s-%2$s.mo', 'aawp', $locale );

		// Setup paths to current locale file.
		$mofile_local  = $lang_dir . $mofile;
		$mofile_global = WP_LANG_DIR . '/aawp/' . $mofile;

		if ( file_exists( $mofile_global ) ) {
			// Look in global /wp-content/languages/aawp/ folder.
			load_textdomain( 'aawp', $mofile_global );
		} elseif ( file_exists( $mofile_local ) ) {
			// Look in local /wp-content/plugins/aawp/languages/ folder.
			load_textdomain( 'aawp', $mofile_local );
		} else {
			// Load the default language files.
			load_plugin_textdomain( 'aawp', false, $lang_dir );
		}
	}
}
