<?php

/**
 * The file that defines the core plugin attribute class
 *
 * @link       https://wpconfiguratorbuilder.com
 * @since      1.0.0
 *
 * @package    wcb-configurator-builder
 * @subpackage wcb-configurator-builder/includes
 */

if ( ! defined('ABSPATH') ) {
	die();
}

/**
 * The core plugin attribute class.
 *
 * This is used to define core attribute post type and maintain its data.
 *
 * @since      1.0.0
 * @package    wcb-configurator-builder
 * @subpackage wcb-configurator-builder/includes/woocommerce
 * @author     WPCB <support@wpconfiguratorbuilder.com>
 */

class WPCB_WC_Product
{
	/**
	 * Initialize the class and set its properties.
	 *
	 * @since    1.0.0
	 * @param    string $plugin_name       The name of this plugin.
	 * @param    string $version   		   The version of this plugin.
	 */
	public function __construct()
	{
		add_action( 'wp', array($this, 'modify_configurable_product_hooks'), 99 );

		add_filter( 'woocommerce_get_price_html', array($this, 'modify_configurator_price_display'), 99, 2 );
		add_filter( 'woocommerce_product_add_to_cart_url', array( $this, 'replace_configurator_add_to_cart_link' ), 99, 2 );
		add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'replace_configurator_add_to_cart_text' ), 99, 2 );

		add_action('woocommerce_available_variation', array($this, 'product_variation_group_of_quantity'), 10, 3);

		add_action( 'init', array($this, 'set_add_to_cart_button_text'), 10);
	}

	/**
	 * Register the stylesheets for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function product_variation_group_of_quantity($variation_data, $product, $variation)
	{
		// Adding to the main product form the group of quantity custom field (for each variation)
		$variation_data['stock_qty'] = 999999;
		if ( $variation->get_manage_stock() ) {
			$variation_data['stock_qty'] = $variation->get_stock_quantity();
		} else if ( ! $variation->is_in_stock() ) {
			$variation_data['stock_qty'] = 0;
		}
		$variation_data['backorders'] = $variation->is_on_backorder();
		return $variation_data;
	}

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since    1.0.0
	 */
	public function modify_configurator_price_display($price, $product)
	{
		if (is_admin()) {
			return $price;
		}
		if ('' === $product->get_price()) {
			return $price;
		}
		if ( is_a( $product, 'WC_Product_Variation' ) ) {
			return $price;
		}

		$wpcb_configuration_id = wpcb_product_has_configurator(get_the_ID());
		if (!$wpcb_configuration_id) {
			return $price;
		}
		if (!get_post_meta( $wpcb_configuration_id, '_change_price_display', true)){
			return $price;
		}

		$format = get_post_meta( $wpcb_configuration_id, '_price_display', true );
		$max_price = get_post_meta( $wpcb_configuration_id, '_max_price', true );
		if ( '' === $max_price ) {
			if ( is_a( $product, 'WC_Product_Variable' ) ) {
				$max_price = $product->get_variation_price('max');
			} else {
				$max_price = wpcb_get_configuration_price_max( $wpcb_configuration_id );
			}
		}
		
		$min_price = wpcb_get_configuration_price_min( $wpcb_configuration_id );
		if ( 0 == $min_price ) {
			$min_price = $product->get_price();
		}

		$format = str_replace( '${price}', wpcb_get_formatted_price( $product->get_price() ), $format );
		$format = str_replace( '${min_price}', wpcb_get_formatted_price( $min_price ), $format );
		$format = str_replace( '${sale_price}', wpcb_get_formatted_price( $product->get_sale_price() ), $format );
		$format = str_replace( '${max_price}', wpcb_get_formatted_price( $max_price ), $format );

		return esc_attr( $format );
	}

	/**
	 * Modify WooCommerce product loop add to cart button link
	 *
	 * @since    1.0.0
	 */
	public function replace_configurator_add_to_cart_link( $url, $product ) {
		$wpcb_configuration_id = wpcb_product_has_configurator($product->get_id());
		if (!$wpcb_configuration_id) {
			return $url;
		}
		return $product->get_permalink();
	}

	/**
	 * Modify WooCommerce product loop add to cart button text
	 *
	 * @since    1.0.0
	 */
	public function replace_configurator_add_to_cart_text( $button_text, $product ) {
		$wpcb_configuration_id = wpcb_product_has_configurator($product->get_id());
		if (!$wpcb_configuration_id) {
			return $button_text;
		}

		$suffix = wpcb_get_i18n_suffix();
		$button_text = wpcb_get_option( 'wpcb_button_loop_cart_text', $suffix );
		if ( ! $button_text ) {
			$button_text = __( 'Configure', 'wcb-configurator-builder' );
		}

		return $button_text;
	}

	/**
	 * Modify WooCommerce product page hooks
	 *
	 * @since    1.0.0
	 */
	public function modify_configurable_product_hooks()
	{
		global $wpcb_configuration_id;

		add_action( 'woocommerce_before_add_to_cart_button', function() {
			echo '<input type="hidden" name="wpcb_redirect_uri" value="' . esc_url( get_permalink() ) . '">';

			if ( isset( $_GET['cart_key'] ) ) {
				echo '<input type="hidden" name="cart_item_key" value="' . esc_attr( sanitize_text_field( wp_unslash( $_GET['cart_key'] ) ) ) . '">';
			}
		});

		add_filter('woocommerce_product_single_add_to_cart_text', array($this, 'set_add_to_cart_button_text'), 10);
		add_filter('woocommerce_quantity_input_args', array($this, 'set_product_quantity_value'), 90, 2);
		
		add_action('woocommerce_quantity_input_min', array($this, 'set_min_product_quantity'), 90 );
		add_action('woocommerce_quantity_input_max', array($this, 'set_max_product_quantity'), 90 );

		$wpcb_configuration_id = wpcb_product_has_configurator(get_the_ID());
		if (!$wpcb_configuration_id) {
			return;
		}

		$wpcb_is_popup = 'popup' === get_post_meta( $wpcb_configuration_id, '_template_display', true);
		if ($wpcb_is_popup) {
			if ( 'replace' === get_post_meta( $wpcb_configuration_id, '_default_form_display', true ) ) {
				add_action('woocommerce_before_add_to_cart_button', function() {
					global $wpcb_configuration_id, $wpcb_cart_action;
					if (!$wpcb_cart_action) {
						echo '<div class="wpcb-delete-form">';
					}
				}, 10);

				add_action('woocommerce_after_add_to_cart_button', function() {
					global $wpcb_configuration_id, $wpcb_cart_action;
					if (!$wpcb_cart_action) {
						echo '</div>'; // ./wpcb-delete-form
					}
				}, 1);
			}

			add_action('woocommerce_after_add_to_cart_button', array($this, 'include_configuration_popup_button'), 50);
			add_action('woocommerce_after_single_product', array($this, 'include_configuration_popup_template'), 20);

			add_action('woocommerce_before_add_to_cart_button', function () {
				global $wpcb_configuration_id, $wpcb_cart_action;
				if ($wpcb_cart_action) {
					echo '<div class="wpcb-configurator-form-add-to-cart hidden"';
					if ( function_exists('wpcb_display_total_price_attributes') ) {
						wpcb_display_total_price_attributes( $wpcb_configuration_id );
					}
					echo '>';
				}
			}, 20);

			add_action('woocommerce_after_add_to_cart_button', function () {
				global $product, $wpcb_configuration_id, $wpcb_cart_action;
				if (!$wpcb_cart_action) {
					return;
				}

				$is_review_page = ( isset( $_GET['wpcb_result'] ) && $_GET['wpcb_result'] );
				$has_review_page = 'yes' === get_post_meta( $wpcb_configuration_id, '_totals_review_page', true );
				$wpcb_configuration_alt_action = get_post_meta( $wpcb_configuration_id, '_button_alt_action', true );
				include WPCB_BASE . 'public/blocks/form-button-alt.php';
				echo '</div>'; // .form-add-to-cart
			}, 10);

		} else if ('tabs' === get_post_meta( $wpcb_configuration_id, '_page_display', true ) || 'shortcode' === get_post_meta( $wpcb_configuration_id, '_page_display', true )) {

			if ( 'replace' === get_post_meta( $wpcb_configuration_id, '_default_form_display', true ) ) {
				add_action('woocommerce_before_add_to_cart_button', function() {
					global $wpcb_configuration_id, $wpcb_cart_action;
					if (!$wpcb_cart_action) {
						echo '<div class="wpcb-delete-form">';
					}
				}, 10);
				
				add_action('woocommerce_after_add_to_cart_button', function() {
					global $wpcb_configuration_id, $wpcb_cart_action;
					if (!$wpcb_cart_action) {
						echo '</div>'; // ./wpcb-delete-form
					}
				}, 10);
			}

			if ( 'tabs' === get_post_meta( $wpcb_configuration_id, '_page_display', true ) ) {
				add_filter('woocommerce_product_tabs', array($this, 'wpcb_configuration_product_tab'));
				add_action('woocommerce_after_add_to_cart_button', array($this, 'wpcb_configuration_product_tab_button'), 20);
			}

			add_action('woocommerce_before_add_to_cart_button', function () {
				global $wpcb_configuration_id, $wpcb_cart_action;
				if ($wpcb_cart_action) {
					echo '<div class="wpcb-configurator-form-add-to-cart hidden"';
					if ( function_exists('wpcb_display_total_price_attributes') ) {
						wpcb_display_total_price_attributes( $wpcb_configuration_id );
					}
					echo '>';
				}
			}, 20);

			add_action('woocommerce_after_add_to_cart_button', function () {
				global $product, $wpcb_configuration_id, $wpcb_cart_action;
				if (!$wpcb_cart_action) {
					return;
				}
				$is_review_page = ( isset( $_GET['wpcb_result'] ) && $_GET['wpcb_result'] );
				$has_review_page = 'yes' === get_post_meta( $wpcb_configuration_id, '_totals_review_page', true );
				$wpcb_configuration_alt_action = get_post_meta( $wpcb_configuration_id, '_button_alt_action', true );
				include WPCB_BASE . 'public/blocks/form-button-alt.php';
				echo '</div>'; // .form-add-to-cart
			}, 10);

		} else {

			// Replace page contents
			if ( ! in_array( get_post_meta( $wpcb_configuration_id, '_template', true ), array( 'basic', 'basic-summary' ) ) ) {
				add_filter('woocommerce_single_product_image_thumbnail_html', array($this, 'return_empty_image'), 99);
				add_action('woocommerce_product_thumbnails', array($this, 'show_product_images'), 10);
			}

			add_action('woocommerce_before_add_to_cart_button', array($this, 'include_configuration_options'), 10);
			add_action('woocommerce_before_add_to_cart_button', array($this, 'include_configuration_button_wrapper'), 20);

			add_action('woocommerce_after_add_to_cart_button', array($this, 'include_configuration_button_wrapper_close'), 10);
			add_action('woocommerce_after_add_to_cart_form', array($this, 'include_configuration_form_actions'), 10);

			if (!wp_is_block_theme() && !function_exists('woodmart_get_opt')) {
				add_action('woocommerce_before_single_product_summary', array($this, 'include_configuration_wrapper'), 5);
				add_action('woocommerce_after_single_product_summary', array($this, 'include_configuration_wrapper_close'), 5);
			}
		}
	}

	/**
	 * Add WooCommerce configure button contents
	 *
	 * @since    1.0.0
	 */
	public function wpcb_configuration_product_tab_button()
	{
		global $wpcb_configuration_id, $wpcb_cart_action;
		if ($wpcb_cart_action) {
			return;
		}

		$suffix = wpcb_get_i18n_suffix();
		$button_text = wpcb_get_option( 'wpcb_button_personalize_text', $suffix );
		if ( ! $button_text ) {
			$button_text = __( 'Configure', 'wcb-configurator-builder' );
		}

		$href = '#tab-wpcb-configurator';
		if ( 'shortcode' === get_post_meta( $wpcb_configuration_id, '_page_display', true ) ) {
			$href = '#wpcb-configuration-' . $wpcb_configuration_id;
		}

		echo '<a href="' . esc_attr( $href ) . '" class="button wpcb-button wpcb-button-alt">' . esc_attr( $button_text ) . '</a>';
	}

	/**
	 * Register WooCommerce custom tab
	 *
	 * @since    1.0.0
	 */
	public function wpcb_configuration_product_tab($tabs)
	{
		$suffix = wpcb_get_i18n_suffix();
		$tab_title = wpcb_get_option( 'wpcb_button_personalize_tab_text', $suffix );
		$tab_priority = apply_filters( 'wpcb_configurator_tab_priority', 5 );

		if ( ! $tab_title ) {
			$tab_title = __('Configurator', 'wcb-configurator-builder');
		}

		$tabs['wpcb-configurator'] = array(
			'title'     => $tab_title,
			'priority'  => $tab_priority,
			'callback'  => array( $this, 'wpcb_configuration_product_tab_content' )
		);

		return $tabs;
	}

	/**
	 * Output WooCommerce custom tab contents
	 *
	 * @since    1.0.0
	 */
	public function wpcb_configuration_product_tab_content()
	{
		global $product;
		echo do_shortcode('[wpcb_configuration id="' . $product->get_id() . '"]');
	}

	/**
	 * Clear WooCommerce image output.
	 *
	 * @since    1.0.0
	 */
	public function return_empty_image()
	{
		return '';
	}

	/**
	 * Set min allowed product quantity.
	 *
	 * @since    1.0.0
	 */
	public function set_min_product_quantity($min)
	{
		global $product, $wpcb_configuration_id;
		if ( ! $wpcb_configuration_id ) {
			return $min;
		}
		if ('no' === get_post_meta( $wpcb_configuration_id, '_show_quantity', true )) {
			return 1;
		}
		if ( '' !== get_post_meta( $wpcb_configuration_id, '_quantity_input_name', true ) ) {
			return 1;
		}
		return $min;
	}

	/**
	 * Set max allowed product quantity.
	 *
	 * @since    1.0.0
	 */
	public function set_max_product_quantity($max)
	{
		global $product, $wpcb_configuration_id;
		if ( ! $wpcb_configuration_id ) {
			return $max;
		}
		if ('no' === get_post_meta( $wpcb_configuration_id, '_show_quantity', true )) {
			return 1;
		}
		if ( '' !== get_post_meta( $wpcb_configuration_id, '_quantity_input_name', true ) ) {
			return 1;
		}
		return $max;
	}

	/**
	 * Update product quantity based on passed cart quantity
	 *
	 * @since    1.0.0
	 */
	public function set_product_quantity_value( $args, $product )
	{
		if ( isset( $_GET['cart_qty'] ) ) {
			$args['input_value'] = sanitize_key( wp_unslash( $_GET['cart_qty'] ) );
		}
		return $args;
	}

	/**
	 * Update WooCommerce add to cart button text
	 *
	 * @since    1.0.0
	 */
	public function set_add_to_cart_button_text($text)
	{
		global $wpcb_configuration_id;
		$suffix = wpcb_get_i18n_suffix();

		if (isset($_GET['cart_key']) && isset($_GET['wpcb_configuration'])) {
			$update_text = wpcb_get_option('wpcb_button_cart_update_text', $suffix) ?: __('Update cart item', 'wcb-configurator-builder');
			return $update_text;
		}

		if ($wpcb_configuration_id) {
			$button_text = wpcb_get_option('wpcb_button_cart_text', $suffix) ?: __('Add to cart', 'wcb-configurator-builder');
			return $button_text;
		}

		return $text;
	}

	/**
	 * Show configuration wrapper
	 *
	 * @since    1.0.0
	 */
	public function include_configuration_wrapper()
	{
		global $wpcb_configuration_id;

		do_action('wpcb_public_output_scripts');

		$config_name = isset( $_GET['wpcb_result'] ) ? sanitize_text_field( $_GET['wpcb_result'] ) : '';
		if ( '' !== $config_name && function_exists( 'wpcb_configurator_form_review_page' ) ) :
			wpcb_configurator_form_review_page();
		endif;

		echo '<div class="wpcb-configurator-wrapper" data-wpcb-id="' . esc_attr( $wpcb_configuration_id ) . '">';
	}

	/**
	 * Show configuration wrapper close
	 *
	 * @since    1.0.0
	 */
	public function include_configuration_wrapper_close()
	{
		echo '</div>';
	}

	/**
	 * Show configuration wrapper
	 *
	 * @since    1.0.0
	 */
	public function include_configuration_button_wrapper()
	{
		global $product, $wpcb_configuration_id, $wpcb_step_count;

		$is_review_page = ( isset( $_GET['wpcb_result'] ) && $_GET['wpcb_result'] );
		if ( $is_review_page ) {
			return;
		}

		$wpcb_totals_class = '';
		if (wpcb_get_option('wpcb_border_style')) {
			$wpcb_totals_class .= ' wpcb-border-' . wpcb_get_option('wpcb_border_style');
		}
		if ($wpcb_step_count > 1) {
			$wpcb_totals_class .= ' wpcb-has-step-nav';
		}
		if ( 'sticky' === get_post_meta( $wpcb_configuration_id, '_totals_position', true ) ) {
			$wpcb_totals_class .= ' wpcb-sticky';
		}

		do_action( 'wpcb_before_configuration_form_totals' );

		if ( wpcb_get_option( 'wpcb_enable_option_summary_inline' ) ) {
			include WPCB_BASE . 'public/blocks/form-summary.php';
		}

		include WPCB_BASE . 'public/blocks/form-price-table.php';

		echo '<div class="wpcb-configurator-form-totals' . esc_attr($wpcb_totals_class) . '" data-wpcb-id="' . esc_attr( $wpcb_configuration_id ) . '">';

		include WPCB_BASE . 'public/blocks/form-price.php';

		$button_action = get_post_meta( $wpcb_configuration_id, '_button_action', true );
		$button_alt_action = get_post_meta( $wpcb_configuration_id, '_button_alt_action', true );
		$has_review_page = 'yes' === get_post_meta( $wpcb_configuration_id, '_totals_review_page', true );

		if ('' !== $button_action) {
			echo '<div class="wpcb-configurator-form-totals-actions ' . esc_attr( $button_action ) . ' ' . esc_attr( $button_alt_action ) . '">';

			if ($wpcb_step_count > 1 && function_exists('wpcb_configurator_form_step_buttons')) {
				/**
				 * Include inline step button
				 */
				wpcb_configurator_form_step_buttons();
			}

			echo '<div class="wpcb-configurator-form-add-to-cart hidden"';
			if ( function_exists('wpcb_display_total_price_attributes') ) {
				wpcb_display_total_price_attributes( $wpcb_configuration_id );
			}
			echo '>';

			include WPCB_BASE . 'public/blocks/form-button.php';
		}

		if ( ( 'cart' !== $button_action && 'cart' !== $button_alt_action ) || $has_review_page ) {
			echo '<div class="wpcb-cart-hidden">';
		}
	}

	/**
	 * Show configuration wrapper close
	 *
	 * @since    1.0.0
	 */
	public function include_configuration_button_wrapper_close()
	{
		global $product, $wpcb_configuration_id;

		$is_review_page = ( isset( $_GET['wpcb_result'] ) && $_GET['wpcb_result'] );
		if ( $is_review_page ) {
			return;
		}

		$button_action = get_post_meta( $wpcb_configuration_id, '_button_action', true );
		$wpcb_configuration_alt_action = get_post_meta( $wpcb_configuration_id, '_button_alt_action', true );
		$has_review_page = 'yes' === get_post_meta( $wpcb_configuration_id, '_totals_review_page', true );
		
		if ( ( 'cart' !== $button_action && 'cart' !== $wpcb_configuration_alt_action ) || $has_review_page ) {
			echo '</div>'; // .wpcb-cart-hidden
		}

		include WPCB_BASE . 'public/blocks/form-button-alt.php';

		echo '</div>'; // .form-add-to-cart
		echo '</div>'; // .form-totals-actions
		echo '</div>'; // .form-totals

		$panel_label = wpcb_get_option( 'wpcb_summary_panel_label', $suffix ) ?: __( 'Your configuration', 'wcb-configurator-builder' );
		$panel_args = array(
			'description' => '<div class="wpcb-configurator-price-table"></div>',
			'id' => 'wpcb-configurator-price-details-' . $wpcb_configuration_id,
		);
		wpcb_display_panel_html_safe( $panel_label, $panel_args );

		do_action( 'wpcb_after_configuration_form_totals' );
	}

	/**
	 * Show configuration form actions
	 *
	 * @since    1.0.0
	 */
	public function include_configuration_form_actions()
	{
		global $product, $wpcb_configuration_id;

		include WPCB_BASE . 'public/blocks/form-actions.php';
	}

	/**
	 * Show configuration form options
	 *
	 * @since    1.0.0
	 */
	public function include_configuration_options()
	{
		global $product, $wpcb_configuration_id;

		/**
		 * Start template form display
		 * 
		 * @hooked -
		 */
		do_action( 'wpcb_before_template_form_options' );

		echo '<div class="wpcb-configurator-options" data-wpcb-id="' . esc_attr( $wpcb_configuration_id ) . '">';

		include WPCB_BASE . 'public/blocks/product-summary.php';

		include WPCB_BASE . 'public/blocks/step-list.php';

		/**
		 * Template form display
		 * 
		 * @hooked wpcb_template_form_options_list - 10
		 */

		do_action( 'wpcb_template_form_options' );

		include WPCB_BASE . 'public/blocks/step-buttons.php';

		echo '</div>';

		/**
		 * End template form display
		 * 
		 * @hooked -
		 */
		do_action( 'wpcb_after_template_form_options' );
	}

	/**
	 * Show configuration gallery
	 *
	 * @since    1.0.0
	 */
	public function show_product_images()
	{
		global $product, $wpcb_configuration_id;
		if (!$wpcb_configuration_id) {
			return;
		}

		/**
		 * Template visuals display
		 * 
		 * @hooked wpcb_template_gallery_wrapper - 10
		 * @hooked wpcb_template_gallery_actions - 20
		 * @hooked wpcb_template_gallery_main - 30
		 * @hooked wpcb_template_gallery_nav - 40
		 * @hooked wpcb_template_gallery_wrapper_close - 50
		 */
		do_action( 'wpcb_template_visuals' );
	}

	/**
	 * Show configuration wrapper close
	 *
	 * @since    1.0.0
	 */
	public function include_configuration_popup_button()
	{
		global $wpcb_cart_action;
		if ($wpcb_cart_action) {
			return;
		}

		wpcb_configurator_popup_button(true);
	}

	/**
	 * Show configuration wrapper close
	 *
	 * @since    1.0.0
	 */
	public function include_configuration_popup_template()
	{
		if ( ! is_product() ) {
			return;
		}

		global $wpcb_configuration_id;
		if ( ! $wpcb_configuration_id ) {
			return;
		}

		$template_layout = get_post_meta( $wpcb_configuration_id, '_template', true );
		if ( 'custom' === $template_layout ) {
			return;
		}

		$template_display = get_post_meta( $wpcb_configuration_id, '_template_display', true );
		if ( 'popup' !== $template_display ) {
			return;
		}

		do_action('wpcb_public_output_scripts');

		$template_path = sprintf(
			'public/templates/%s',
			$template_layout
		);

		ob_start();

		require WPCB_BASE . $template_path . '.php';

		$safe_html = ob_get_contents();
		ob_end_clean();

		echo $safe_html;
	}
}
