<?php
/**
 * The file that defines the core plugin class
 *
 * A class definition that includes attributes and functions used across both the
 * public-facing side of the site and the admin area.
 *
 * @link       http://wpgenie.org
 * @since      1.0.0
 *
 * @package    Woocommerce_Simple_Storewide_Sale
 * @subpackage Woocommerce_Simple_Storewide_Sale/includes
 */

/**
 * The core plugin class.
 *
 * This is used to define internationalization, admin-specific hooks, and
 * public-facing site hooks.
 *
 * Also maintains the unique identifier of this plugin as well as the current
 * version of the plugin.
 *
 * @since      1.0.0
 * @package    Simple_Storewide_Sale_For_Woocommerce
 * @subpackage Simple_Storewide_Sale_For_Woocommerce/includes
 * @author     WpGenie <info@wpgenie.org>
 */
class Simple_Storewide_Sale_For_Woocommerce {

	/**
	 * The loader that's responsible for maintaining and registering all hooks that power
	 * the plugin.
	 *
	 * @since    1.0.0
	 * @access   protected
	 * @var      Simple_Storewide_Sale_For_Woocommerce_Loader    $loader    Maintains and registers all hooks for the plugin.
	 */
	protected $loader;

	/**
	 * The unique identifier of this plugin.
	 *
	 * @since    1.0.0
	 * @access   protected
	 * @var      string    $plugin_name    The string used to uniquely identify this plugin.
	 */
	protected $plugin_name;

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

	/**
	 * Notices (array)
	 *
	 * @var array
	 */
	public $notices = array();

	/**
	 * Define the core functionality of the plugin.
	 *
	 * Set the plugin name and the plugin version that can be used throughout the plugin.
	 * Load the dependencies, define the locale, and set the hooks for the admin area and
	 * the public-facing side of the site.
	 *
	 * @since    1.0.0
	 */
	public function __construct() {

		$this->plugin_name = 'simple-storewide-sale-for-woocommerce';
		$this->version     = '1.0.0';
		$this->load_dependencies();
		$this->define_admin_hooks();
		$this->define_public_hooks();
		add_action( 'admin_notices', array( $this, 'admin_notices' ), 15 );
	}

	/**
	 * Load the required dependencies for this plugin.
	 *
	 * Include the following files that make up the plugin:
	 *
	 * - Wc_simple_storewide_sale_Loader. Orchestrates the hooks of the plugin.
	 * - Wc_simple_storewide_sale_i18n. Defines internationalization functionality.
	 * - Wc_simple_storewide_sale_Admin. Defines all hooks for the admin area.
	 * - Wc_simple_storewide_sale_Public. Defines all hooks for the public side of the site.
	 *
	 * Create an instance of the loader which will be used to register the hooks
	 * with WordPress.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function load_dependencies() {

		/**
		 * The class responsible for orchestrating the actions and filters of the
		 * core plugin.
		 */
		require_once plugin_dir_path( __DIR__ ) . 'includes/class-simple-storewide-sale-for-woocommerce-loader.php';

		/**
		 * The class responsible for defining all actions that occur in the admin area.
		 */
		require_once plugin_dir_path( __DIR__ ) . 'admin/class-simple-storewide-sale-for-woocommerce-admin.php';

		/**
		 * The class responsible for defining all actions that occur in the public-facing
		 * side of the site.
		 */
		require_once plugin_dir_path( __DIR__ ) . 'public/class-simple-storewide-sale-for-woocommerce-public.php';

		$this->loader = new Simple_Storewide_Sale_For_Woocommerce_Loader();
	}

	/**
	 * Register all of the hooks related to the admin area functionality
	 * of the plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function define_admin_hooks() {

		$plugin_admin = new Simple_Storewide_Sale_For_Woocommerce_Admin( $this->get_plugin_name(), $this->get_version() );

		$this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles' );
		$this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts' );
		$this->loader->add_action( 'woocommerce_admin_field_datetimepicker', $plugin_admin, 'datetimepicker' );
		$this->loader->add_action( 'woocommerce_admin_field_ajaxproduct', $plugin_admin, 'ajaxproduct' );
		$this->loader->add_action( 'woocommerce_admin_field_hiddenhash', $plugin_admin, 'hiddenhash' );

		$this->loader->add_filter( 'plugin_row_meta', $plugin_admin, 'add_support_link', 10, 2 );
		$this->loader->add_filter( 'woocommerce_get_settings_pages', $plugin_admin, 'settings_class', 20 );
		$this->loader->add_filter( 'woocommerce_update_options_simple_storewide_sale', $this, 'set_onsale_page_transient', 90 );
		$this->loader->add_filter( 'woocommerce_delete_product_transients', $this, 'delete_onsale_page_transient', 90 );
	}

	/**
	 * Register all of the hooks related to the public-facing functionality
	 * of the plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function define_public_hooks() {

		$this->loader->add_action( 'init', $this, 'get_onsale_page_transient', 100 );
		$plugin_public = new Simple_Storewide_Sale_For_Woocommerce_Public( $this->get_plugin_name(), $this->get_version() );
		$this->loader->add_action( 'wp_footer', $plugin_public, 'sale_notice' );
		if ( $plugin_public->run_sales() && ! is_admin() ) {
			$this->loader->add_filter( 'woocommerce_product_get_price', $plugin_public, 'filterprice', 15, 2 );
			$this->loader->add_filter( 'woocommerce_product_get_sale_price', $plugin_public, 'filterprice', 15, 2 );
			$this->loader->add_filter( 'woocommerce_product_variation_get_price', $plugin_public, 'filterprice', 15, 2 );
			$this->loader->add_filter( 'woocommerce_product_variation_get_sale_price', $plugin_public, 'filterprice', 15, 2 );
			$this->loader->add_filter( 'woocommerce_variation_prices_price', $plugin_public, 'filterprice', 15, 3 );
			$this->loader->add_filter( 'woocommerce_variation_prices_sale_price', $plugin_public, 'filterprice', 10, 3 );
			$this->loader->add_filter( 'wc_onsale_page_product_ids_on_sale', $plugin_public, 'add_wc_onsale_page_product_ids_on_sale', 10, 1 );
			$this->loader->add_filter( 'woocommerce_get_variation_prices_hash', $plugin_public, 'add_discount_woocommerce_get_variation_prices_hash', 15, 2 );
		}
	}

	/**
	 * Run the loader to execute all of the hooks with WordPress.
	 *
	 * @since    1.0.0
	 */
	public function run() {
		$this->loader->run();
	}

	/**
	 * The name of the plugin used to uniquely identify it within the context of
	 * WordPress and to define internationalization functionality.
	 *
	 * @since     1.0.0
	 * @return    string    The name of the plugin.
	 */
	public function get_plugin_name() {
		return $this->plugin_name;
	}

	/**
	 * The reference to the class that orchestrates the hooks with the plugin.
	 *
	 * @since     1.0.0
	 * @return    Wc_simple_storewide_sale_Loader    Orchestrates the hooks of the plugin.
	 */
	public function get_loader() {
		return $this->loader;
	}

	/**
	 * Retrieve the version number of the plugin.
	 *
	 * @since     1.0.0
	 * @return    string    The version number of the plugin.
	 */
	public function get_version() {
		return $this->version;
	}

	/**
	 * Allow this class and other classes to add slug keyed notices (to avoid duplication)
	 *
	 * @param  mixed $slug slug.
	 * @param  mixed $type type.
	 * @param  mixed $message message.
	 * @return void
	 */
	public function add_admin_notice( $slug, $type, $message ) {
		$this->notices[ $slug ] = array(
			'class'   => $type,
			'message' => $message,
		);
	}

	/**
	 * Display any notices we've collected thus far (e.g. for connection, disconnection)
	 */
	public function admin_notices() {
		foreach ( (array) $this->notices as $notice_key => $notice ) {
			echo "<div class='" . esc_attr( $notice['class'] ) . "'><p>";
			echo wp_kses( $notice['message'], array( 'a' => array( 'href' => array() ) ) );
			echo '</p></div>';
		}
	}

	/**
	 * Set onsale page transient
	 *
	 * @return array
	 */
	public function set_onsale_page_transient() {

		$tax_query = array();
		$metaquery = array();
		if ( sssfw_fs()->is_premium() ) {
			$excludetype        = get_option( 'wcsss_exclude_type', '' );
			$excludecat         = get_option( 'wcsss_exclude_cat', '' );
			$includecat         = get_option( 'wcsss_include_cat', '' );
			$excludetags        = get_option( 'wcsss_exclude_tag', '' );
			$includetags        = get_option( 'wcsss_include_tag', '' );
			$excludeproduct_tmp = get_option( 'wcsss_exclude_product', '' );
			$includeproduct_tmp = get_option( 'wcsss_include_product', '' );
			$includesku_tmp     = get_option( 'wcsss_include_sku', '' );
			$excludesku_tmp     = get_option( 'wcsss_exclude_sku', '' );

			if ( ! empty( $excludetype ) ) {
				$tax_query[] = array(
					'taxonomy' => 'product_type',
					'field'    => 'slug',
					'terms'    => $excludetype,
					'operator' => 'NOT IN',
				);
			}

			if ( ! empty( $excludecat ) ) {
				$tax_query[] = array(
					'taxonomy' => 'product_cat',
					'field'    => 'id',
					'terms'    => $excludecat,
					'operator' => 'NOT IN',
				);
			}

			if ( ! empty( $includecat ) ) {
				$tax_query[] = array(
					'taxonomy' => 'product_cat',
					'field'    => 'id',
					'terms'    => $includecat,
					'operator' => 'IN',
				);
			}

			if ( ! empty( $excludetags ) ) {
				$tax_query[] = array(
					'taxonomy' => 'product_tag',
					'field'    => 'id',
					'terms'    => $excludetags,
					'operator' => 'NOT IN',
				);
			}
			if ( ! empty( $includetags ) ) {
				$tax_query[] = array(
					'taxonomy' => 'product_tag',
					'field'    => 'id',
					'terms'    => $includetags,
					'operator' => 'IN',
				);
			}
			if ( ! empty( $includesku_tmp ) ) {
				$metaquery[] =
					array(
						'key'     => '_sku',
						'value'   => explode( ',', $includesku_tmp ),
						'compare' => 'IN',
					);
			}
			if ( ! empty( $excludesku_tmp ) ) {
				$metaquery[] = array(
					'key'     => '_sku',
					'value'   => explode( ',', $excludesku_tmp ),
					'compare' => 'NOT IN',
				);
			}

			if ( ! empty( $excludeproduct_tmp ) ) {
				$query_args['post__not_in'] = $excludeproduct_tmp;
			}
			if ( ! empty( $includeproduct_tmp ) ) {
				$query_args['post__in'] = $includeproduct_tmp;
			}
			if ( ! empty( $tax_query ) ) {
				$query_args['tax_query'] = $tax_query;
			}
			if ( ! empty( $metaquery ) ) {
				$query_args['meta_query'] = $metaquery;
			}
		}
		$query_args['post_type']      = 'product';
		$query_args['posts_per_page'] = '-1';

		$query = new WP_Query( $query_args );

		$product_ids_on_sale = wp_parse_id_list( array_merge( wp_list_pluck( $query->posts, 'ID' ), array_diff( wp_list_pluck( $query->posts, 'post_parent' ), array( 0 ) ) ) );

		set_transient( 'wc_onsale_page_products_onsale', $product_ids_on_sale, DAY_IN_SECONDS * 30 );

		return $product_ids_on_sale;
	}

	/**
	 * Delete onsale page_ ransient
	 *
	 * @return void
	 */
	public function delete_onsale_page_transient() {
		delete_transient( 'wc_onsale_page_products_onsale' );
		$this->set_onsale_page_transient();
	}

	/**
	 * Get onsale page transient
	 *
	 * @return array
	 */
	public function get_onsale_page_transient() {
		$product_ids_on_sale = get_transient( 'wc_onsale_page_products_onsale' );
		if ( false !== $product_ids_on_sale ) {
			return $product_ids_on_sale;
		} else {
			$product_ids_on_sale = $this->set_onsale_page_transient();
			return $product_ids_on_sale;
		}
	}
}
