<?php
/**
 * YITH_YWBC_Frontend class
 *
 * @package YITH\Barcodes\Classes
 */

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

if ( ! class_exists( 'YITH_YWBC_Frontend' ) ) {

	/**
	 * YITH_YWBC_Frontend
	 *
	 * @class   YITH_YWBC_Frontend
	 * @package Yithemes
	 * @since   1.0.0
	 * @author  YITH <plugins@yithemes.com>
	 */
	class YITH_YWBC_Frontend {

		/**
		 * Single instance of the class
		 *
		 * @since 1.0.0
		 * @var instance
		 */
		protected static $instance;

		/**
		 * Get_instance
		 *
		 * @return instance
		 */
		public static function get_instance() {
			if ( is_null( self::$instance ) ) {
				self::$instance = new self();
			}

			return self::$instance;
		}

		/**
		 * Constructor
		 *
		 * Initialize plugin and registers actions and filters to be used
		 *
		 * @since  1.0
		 */
		protected function __construct() {

			$this->init_hooks();
		}

		/**
		 * Initialize all hooks used by the plugin affecting the front-end behaviour
		 */
		public function init_hooks() {
			add_action(
				'wp_enqueue_scripts',
				array(
					$this,
					'enqueue_scripts',
				)
			);

			add_action(
				'wp_enqueue_scripts',
				array(
					$this,
					'enqueue_style',
				)
			);

			add_action(
				'woocommerce_order_details_after_order_table',
				array(
					$this,
					'show_barcode_on_view_order_page',
				)
			);

			/**
			 * Show the barcode on front-end product page
			 */
			add_action(
				'woocommerce_before_add_to_cart_form',
				array(
					$this,
					'show_barcode_on_single_product_page',
				),
				25
			);

			add_filter(
				'woocommerce_available_variation',
				array(
					$this,
					'show_variation_barcode',
				),
				10,
				3
			);

			add_action(
				'woocommerce_store_api_checkout_order_processed',
				array(
					$this, 
					'on_new_order',
				)
			);

			add_action(
				'woocommerce_update_order',
				array(
					$this,
					'on_new_api_order',
				)
			);
		}

		/**
		 * On_new_order
		 * Create barcode for new orders if needed
		 *
		 * @param  int $order_id order_id.
		 * @return void
		 */
		public function on_new_order( $order ) {
			$order_id = $order->get_id();
			// Check if barcode are enabled for orders.
			if ( ! YITH_YWBC()->enable_on_orders ) {
				return;
			}

			// Check if barcode should be create automatically.
			if ( ! YITH_YWBC()->create_on_orders ) {
				return;
			}

			/** APPLY_FILTERS: ywbc_before_create_order_barcode
			*
			* Filter the condition create or not the order barcode on new order.
			*
			* @param $order_id ID of the order.
			*/
			if ( apply_filters( 'ywbc_before_create_order_barcode', true, $order_id ) ) {
				$this->create_order_barcode( $order_id );
			}

		}

		/**
		 * On_new_order
		 * Create barcode for new orders if needed
		 *
		 * @param  int $order_id order_id.
		 * @return void
		 */
		public function on_new_api_order( $order_id ) {

			$order = wc_get_order( $order_id );

			if ( ! is_object( $order ) ){
				return;
			}

			$barcode_already_generated = $order->get_meta( '_ywbc_barcode_value' );

			if ( $barcode_already_generated ){
				return;
			}

			if ( 'rest-api' === $order->get_created_via() ){
				$this->on_new_order( $order );
			}
		}

		/**
		 * Create the barcode values for the order
		 *
		 * @param int    $order_id order_id.
		 * @param string $protocol protocol.
		 * @param string $value value.
		 */
		public function create_order_barcode( $order_id, $protocol = '', $value = '' ) {
			$protocol = $protocol ? $protocol : YITH_YWBC()->orders_protocol;

			$order = wc_get_order( $order_id );

			$value_option = get_option( 'ywbc_order_barcode_type', 'id' );

			if ( 'number' === $value_option ) {
				$value_type = $order->get_order_number();
			} elseif ( 'custom_field' === $value_option ) {

				$custom_field = get_option( 'ywbc_order_barcode_type_custom_field' );

				if ( 'order_url' === $custom_field && 'QRcode' === $protocol ) {
					$my_account_url = get_permalink( get_option( 'woocommerce_myaccount_page_id' ) );
					$value_type     = $my_account_url . 'view-order/' . $order_id;
				} else {
					$value_type = $order->get_meta( $custom_field );

				}
			} else {
				$value_type = $order_id;
			}

			$the_value = $value ? $value : $value_type;

			/** APPLY_FILTERS: yith_barcode_new_order_value
			*
			* Filter the value of the barcode image when creating the order barcode.
			*
			* @param $the_value Formatted value.
			* @param $order_id  ID of the order.
			* @param $protocol  Current protocol.
			* @param $value     Current value.
			*/
			$the_value = apply_filters( 'yith_barcode_new_order_value', $the_value, $order_id, $protocol, $value );

			$this->generate_barcode_image( $order_id, $protocol, $the_value );
		}

		/**
		 * Generate a new barcode instance
		 *
		 * @param int    $object_id the id of the object(WC_Product or WC_Order) associated to this barcode.
		 * @param string $protocol  the protocol to use.
		 * @param string $value     the value to use as the barcode value.
		 *
		 * @return YITH_Barcode
		 */
		public function generate_barcode_image( $object_id, $protocol, $value ) {
			$barcode = new YITH_Barcode( $object_id );
			
			$image_path = YITH_YWBC()->get_server_file_path( $object_id, $protocol, $value );
			$res = $barcode->generate( $protocol, $value, $image_path );
			$barcode->save();

			/** DO_ACTION: yith_ywbc_after_generate_barcode
			*
			* Adds an action after generating the barcode image.
			*
			* @param $object_id ID of the barcode.
			* @param $protocol  Protocol.
			* @param $value     Value.
			*/

			do_action( 'yith_ywbc_after_generate_barcode', $object_id, $protocol, $value );

			return $barcode;

		}

		/**
		 * Show_variation_barcode
		 *
		 * @param  mixed      $args args.
		 * @param  mixed      $product_variable product_variable.
		 * @param  WC_Product $variation Variation product object or ID.
		 * @return args
		 */
		public function show_variation_barcode( $args, $product_variable, $variation ) {

			$barcode = YITH_Barcode::get( $variation->get_id() );
			if ( $barcode->exists() ) {

				$args['barcode_img']   = esc_attr( YITH_YWBC()->get_public_file_path( $barcode ) );
				$args['barcode_value'] = $barcode->get_display_value();
			}

			return $args;
		}

		/**
		 * Enqueue scripts for the front-end
		 */
		public function enqueue_scripts() {

			/** APPLY_FILTERS: yith_ywbc_enqueue_frontend_script_source_path
			*
			* Filter the enqueue of the frontend script.
			*/
			// register and enqueue ajax calls related script file.
			wp_register_script(
				'ywbc-frontend',
				apply_filters( 'yith_ywbc_enqueue_frontend_script_source_path', YITH_YWBC_SCRIPTS_URL . yit_load_js_file( 'ywbc-frontend.js' ) ),
				array(
					'jquery',
				),
				YITH_YWBC_VERSION,
				true
			);

			wp_localize_script(
				'ywbc-frontend',
				'ywbc_data',
				array(

					/** APPLY_FILTERS: yith_barcodes_loader
					*
					* Filter the default loading gif in the frontend.
					*/
					'loader'   => apply_filters( 'yith_barcodes_loader', YITH_YWBC_ASSETS_URL . '/images/loading.gif' ),
					'ajax_url' => admin_url( 'admin-ajax.php' ),
				)
			);

			wp_enqueue_script( 'ywbc-frontend' );
		}

		/**
		 * Enqueue style for the front-end
		 */
		public function enqueue_style() {
			global $post;

			if ( ( YITH_YWBC()->show_on_product_page && is_product() ) || ( YITH_YWBC()->show_on_order_page && is_view_order_page() ) ) {
				wp_enqueue_style(
					'ywbc-style',
					YITH_YWBC_ASSETS_URL . '/css/ywbc-style.css',
					array(),
					YITH_YWBC_VERSION
				);
			}

			// Load the styles only if the post contains the shortcodes.
			if ( $post && ( has_shortcode( $post->post_content, 'yith_order_barcode' ) || has_shortcode( $post->post_content, 'yith_product_barcode' ) ) || apply_filters( 'yith_ywbc_enqueue_shortcode_styles', false ) ) {
				wp_enqueue_style(
					'ywbc-shortcodes-style',
					YITH_YWBC_ASSETS_URL . '/css/ywbc-shortcodes-style.css',
					array(),
					YITH_YWBC_VERSION
				);
			}
		}

		/**
		 * Show the order barcode on order page
		 *
		 * @param WC_Order $order the order being shown.
		 *
		 * @since  1.0.0
		 */
		public function show_barcode_on_view_order_page( $order ) {

			/** APPLY_FILTERS: yith_ywmc_prevent_show_barcode_on_view_order_page
			*
			* Filter the conmdition to show the barcode in the view order page or not.
			*
			* @param $bool  false by default.
			* @param $order Order object.
			*/
			if ( ! YITH_YWBC()->show_on_order_page || apply_filters( 'yith_ywmc_prevent_show_barcode_on_view_order_page', false, $order ) ) {
				return;
			}

			YITH_YWBC()->show_barcode( $order->get_id(), true );
		}

		/**
		 * Show the barcode on the product page
		 */
		public function show_barcode_on_single_product_page() {
			if ( ! YITH_YWBC()->show_on_product_page ) {
				return;
			}

			global $product;
			$product_id     = $product->get_id();
			$show_container = $product->is_type( 'variable' );

			/** APPLY_FILTERS: yith_ywbc_use_original_product_barcode
			*
			* Filter the condition to use or not the original product barcode in the single product page.
			*/
			if ( defined( 'ICL_SITEPRESS_VERSION' ) && apply_filters( 'yith_ywbc_use_original_product_barcode', false ) ) {
				global $sitepress;

				$product_id = yit_wpml_object_id( $product_id, 'product', true, $sitepress->get_default_language() );
			}

			?><div class="ywbc-barcode-container-product-page" style="width: 50%; margin: 15px 0;">
			<?php
			YITH_YWBC()->show_barcode( $product_id, true, '', '', $show_container );
			?>
			</div>
			<?php
		}
	}
}
YITH_YWBC_Frontend::get_instance();
