<?php
namespace BricksUltimate;

if ( ! defined( 'ABSPATH' ) ) exit;

class Ajax {
	public $product_id = false;
	private $elementId = false;
	private $pageId = false;
	/**
     * Main class constructor
     *
     */
    public function __construct() {
    	if( class_exists('WooCommerce') ) 
    	{
			add_action( 'wp_ajax_buwoo_update_cart_item_quantity', [ $this, 'buwoo_update_cart_item_quantity' ] );
			add_action( 'wp_ajax_nopriv_buwoo_update_cart_item_quantity', [ $this, 'buwoo_update_cart_item_quantity' ] );
			add_action( 'wp_ajax_bu_applied_coupon', [ $this, 'get_applied_coupons' ] );
			add_action( 'wp_ajax_nopriv_bu_applied_coupon', [ $this, 'get_applied_coupons' ] );
			add_action( 'wp_ajax_bu_added_to_cart_notice', [ $this, 'bu_added_to_cart_notice' ] );
			add_action( 'wp_ajax_nopriv_bu_added_to_cart_notice', [ $this, 'bu_added_to_cart_notice' ] );
			add_action( 'wp_ajax_bu_load_variation_form', [ $this, 'bu_load_variation_form' ] );
			add_action( 'wp_ajax_nopriv_bu_load_variation_form', [ $this, 'bu_load_variation_form' ] );
			add_action( 'wp_ajax_buwoo_calculate_shipping_cost', [ $this, 'buwoo_calculate_shipping_cost' ] );
			add_action( 'wp_ajax_nopriv_buwoo_calculate_shipping_cost', [ $this, 'buwoo_calculate_shipping_cost' ] );

			add_action('wp_ajax_bu_update_content', [$this,'update_content_fragments'] );
			add_action('wp_ajax_nopriv_bu_update_content', [$this,'update_content_fragments'] );

			add_action('wp_ajax_buob_add_to_cart', [$this,'buob_add_to_cart'] );
			add_action('wp_ajax_nopriv_buob_add_to_cart', [$this,'buob_add_to_cart'] );

			add_action('wp_ajax_bufsn_free_shipping_amount', [$this,'bufsn_free_shipping_amount'] );
			add_action('wp_ajax_nopriv_bufsn_free_shipping_amount', [$this,'bufsn_free_shipping_amount'] );
		}

		add_action( 'wp_ajax_bu_ajax_search', [ $this, 'bu_get_search_result' ] );
		add_action( 'wp_ajax_nopriv_bu_ajax_search', [ $this, 'bu_get_search_result' ] );
    }

    public function get_shipping_methods_for_country($country_code) {
		global $wpdb;

		// Get zones that apply to this country
		$zones = $wpdb->get_results(
		    $wpdb->prepare(
		        "SELECT zone_id FROM {$wpdb->prefix}woocommerce_shipping_zone_locations 
		        WHERE location_code = %s AND location_type = 'country'",
		        $country_code
		    )
		);

		$zone_ids = array_map(function($zone) { return $zone->zone_id; }, $zones);

		// Also include the "Rest of the World" zone (ID 0)
		$zone_ids[] = 0;

		// Get shipping methods for these zones
		$methods = $wpdb->get_results(
		    "SELECT * FROM {$wpdb->prefix}woocommerce_shipping_zone_methods 
		    WHERE zone_id IN (" . implode(',', $zone_ids) . ") AND is_enabled = 1"
		);

		return $methods;
	}

    public function bufsn_free_shipping_amount() {
    	$country = $_POST['country']??'US';
    	
		$country_methods = $this->get_shipping_methods_for_country( $country );
		$instance_id = false;
		$data = ['success' => false ];

		foreach( $country_methods as $methods ) {
			if( $methods->method_id == 'free_shipping' ) {
				$instance_id = $methods->instance_id;
				break;
			}
		}

		if( $instance_id ) {
			$shippingObj = new \WC_Shipping_Free_Shipping( $instance_id );
			$min_amount = $shippingObj->get_option( 'min_amount', 0.00);
			$min_amount = ( strpos($min_amount, \wc_get_price_decimal_separator() ) !== false ) ? $min_amount : $min_amount . \wc_get_price_decimal_separator() . '00';

			$data['min_amount'] = $min_amount;
			$data['min_amt_price'] = wc_price( $min_amount );

			$decimals 	= \wc_get_price_decimals() == 0 ? 2 : \wc_get_price_decimals();
			$cartTotal = number_format( \BricksUltimate\WooCommerce::get_customer_order_amount(), $decimals, wc_get_price_decimal_separator(), wc_get_price_thousand_separator() );
			$cartTotal = str_replace( [ wc_get_price_decimal_separator(), wc_get_price_thousand_separator() ], '', $cartTotal );
			$min_amount = str_replace( [ wc_get_price_decimal_separator(), wc_get_price_thousand_separator() ], '', $min_amount );
			$diff = ( absint( $min_amount ) - absint( $cartTotal ) );

			if( $diff > 0 ) {
				$data['amount'] = wc_price( $diff / 100 );
			} else {
				$data['amount'] = wc_price( $min_amount / 100 );
			}

			$data['success'] = true;
		}

		wp_send_json( $data );
    }

    public function update_content_fragments() {
		//check_ajax_referer( 'atc-nonce', 'security' );
		$fragments = [];
		$prefix = $_POST['prefix'] ?? 'bu-';
		$content = get_option('bultimate_client')??'';
		foreach( (array) \BricksUltimate\Plugin::$bu_settings['wccntrsf'] as $el ) {
			$tpl_post_id = explode("|", $el );
			ob_start();
			\BricksUltimate\WooCommerce::buwoo_content_updater( $el );
			$content .= ob_get_clean();
			if( $content )
				$fragments['.' . $prefix . $tpl_post_id[0]] = $content;
		}
		
		$data = array(
			'fragments' => $fragments
		);

		wp_send_json( $data );
	}

	public function buwoo_update_cart_item_quantity() {
		//check_ajax_referer( 'atc-nonce', 'security' );

		$cart_key = sanitize_text_field( $_GET['cart_key'] );
		$new_qty = wc_stock_amount(absint( $_GET['qty'] ));

		if ( $cart_key ) {
			if ( $new_qty == 0 ) {
				\WC()->cart->remove_cart_item( $cart_key );
			} else {
				\WC()->cart->set_quantity( $cart_key, $new_qty );
			}
		}

		\wc_clear_notices();

		$fragments = [];

		ob_start();
		\woocommerce_mini_cart();
		$mini_cart = ob_get_clean();

		$fragments['div.widget_shopping_cart_content'] = '<div class="widget_shopping_cart_content">' . $mini_cart . '</div>';

		$data = array(
			'fragments' => apply_filters(
				'woocommerce_add_to_cart_fragments',
				\BricksUltimate\WooCommerce::buwoo_cart_fragment($fragments)
			),
			'cart_hash' => \WC()->cart->get_cart_hash(),
		);

		wp_send_json( $data );
	}

	public function buwoo_calculate_shipping_cost() {

		\WC_Shortcode_Cart::calculate_shipping();

		$element_id = $_POST['element_id'];
		$post_id = isset( $_POST['post_id'] ) ? $_POST['post_id'] : 0;

		$preview_id = \Bricks\Database::$page_data['preview_or_post_id'];
		\Bricks\Database::$page_data['preview_or_post_id'] = $post_id;

		\WC()->cart->calculate_shipping();
		$data = \Bricks\Helpers::get_element_data( $post_id, $element_id );
		$output = \Bricks\Frontend::render_element( $data['element'] );

		\Bricks\Database::$page_data['preview_or_post_id'] = $preview_id;

		\wc_clear_notices();
		wp_send_json(
			array(
				'fragments' => array(
					'.brxe-bu-shipping-cal' => $output
				)
			)
		);
	}

    public function bu_load_variation_form() {
    	//check_ajax_referer( 'atc-nonce', 'security' );

		$product_id 		= $_POST['id'] ?? false;
		$this->elementId 	= $_POST['element'] ?? false;
		$this->pageId 		= $_POST['page'] ?? false;

		if( ! $product_id ) {
			return;
		}

		global $post;

		$args = array( 'post__in' => array($product_id), 'post_type' => 'product' );
		$variableProduct = get_posts( $args );

		foreach( $variableProduct as $post ) :
			setup_postdata($post);

			if( $this->elementId ) {
				add_filter( 'woocommerce_product_single_add_to_cart_text', [ $this, 'bu_qa_add_to_cart_text' ] );
				add_filter( 'esc_html', [ $this, 'bu_avoid_esc_html' ], 10, 2 );
			}

			woocommerce_template_single_add_to_cart();

			if( $this->elementId ) {
				remove_filter( 'woocommerce_product_single_add_to_cart_text', [ $this, 'bu_qa_add_to_cart_text' ] );
				remove_filter( 'esc_html', [ $this, 'bu_avoid_esc_html' ], 10, 2 );
			}

		endforeach; 
		wp_reset_postdata(); 
		die();
    }

    public function bu_qa_add_to_cart_text( $atc ) {
		$settings = \Bricks\Helpers::get_element_settings($this->pageId, $this->elementId);

		$icon = ! empty( $settings['qaicon'] ) ? \Bricks\Element::render_icon( $settings['qaicon'], [ 'single-atc-icon' ] ) : '';
		if( ! empty( $settings['qaHideBtnText'] ) && ! empty( $icon ) ) {
			$atc = $icon;
		} else {
			$singleATCText = \BricksUltimate\Helpers::get_value( $settings, 'qaATCBtnText', __( 'Add to cart', 'woocommerce' ) );
			$atc = $singleATCText . $icon;
		}

		return $atc;
	}

	public function bu_avoid_esc_html( $esc_html_text, $text ) {
		return $text;
	}

	public function get_applied_coupons() {
		//check_ajax_referer( 'bu-applied-coupons', 'security' );
		\BricksUltimate\WooCommerce::appliedCoupons();
		wp_die();
	}

	public function bu_added_to_cart_notice() {
		//check_ajax_referer( 'atc-nonce', 'security' );

		$data = ['success' => false];

		$postId = $_POST['product_id'];
		$template_id = $_POST['template_id'];

		if( $postId && $template_id ) {

			global $postData;

			$postData['id'] = $postId;
			$postData['filterType'] = 'notice';

			// Store current main render_data self::$elements
			$store_elements = \Bricks\Frontend::$elements;

			$data = ['success' => true];
			add_filter( 'bricks/posts/query_vars', [ __CLASS__, 'filter_query_args' ], 10, 3 );

			$elements = get_post_meta( $template_id, BRICKS_DB_PAGE_CONTENT, true );
			$template_inline_css = \Bricks\Templates::generate_inline_css( $template_id, $elements );

			$css = "<style id=\"bricks-inline-css-template-{$template_id}\">{$template_inline_css}</style>";

			$data['notice'] = do_shortcode('[bricks_template id="'. $template_id .'"]') . $css ;
			remove_filter( 'bricks/posts/query_vars', [ __CLASS__, 'filter_query_args' ], 10, 3 );

			// Reset the main render_data self::$elements
			\Bricks\Frontend::$elements = $store_elements;
			
			wc_clear_notices();
		}

		wp_send_json( $data );

		wp_die();
	}

	public function buob_add_to_cart() {
		$data = ['success' => false];

		$quantity 	= $_POST['quantity'];
		$product_id = $_POST['productId'];
		$bumpId 	= $_POST['bumpId'];

		global $product;
		$product = wc_get_product( $product_id );
		$variation_id   = $product->is_type( 'variable' ) ? $product->get_id() : null;
		$product_id     = $product->is_type( 'variable' ) && 0 !== $product->get_parent_id() ? $product->get_parent_id() : $product->get_id();
		$variation_data = null;
		$metadata       = array(
			'_buob_bump_id' => $bumpId,
		);

		if ( $product->is_type( 'variation' ) ) {
			$variation_data = array();

			foreach ( $product->get_variation_attributes() as $taxonomy => $term_names ) {
				$taxonomy                                = str_replace( 'attribute_', '', $taxonomy );
				$attribute_label_name                    = str_replace( 'attribute_', '', wc_attribute_label( $taxonomy ) );
				$variation_data[ $attribute_label_name ] = $term_names;
			}
		}

		if( \WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation_data, $metadata ) ) {
			do_action( 'woocommerce_ajax_added_to_cart', $product_id );

			\wc_clear_notices();

			$data = array(
				'success' => true,
			);
		} else {
			$data = array(
				'success' => false,
				'error'  => true,
			);
		}

		wp_send_json( $data );
	}

	/**
	 * Get AJAX search results
	 * 
	 * @return array json data
	 */
	public function bu_get_search_result() {
		//check_ajax_referer( 'atc-nonce', 'security' );
		
		global $postData;

		$postData = [];
		$postData = $_REQUEST;

		$post_templates = $_REQUEST['posts'] ?? false;
		$term_templates = $_REQUEST['terms'] ?? false;
		$suggestions = [];

		if( $post_templates || $term_templates ) {
			$postData['filterType'] = 'asearch';

			if( ! empty( $_REQUEST['meta_query'] ) ) {
				$postData['relation'] = $_REQUEST['meta_relation'] ?? 'OR';
				$postData['meta_query'] = $_REQUEST['meta_query'];
			}

			// Store current main render_data self::$elements
			$store_elements = \Bricks\Frontend::$elements;

			if( $post_templates ) {
				$arr = explode('|', $post_templates );
				foreach( $arr as $arr_data ) {
					$postData['postType'] = explode('_', $arr_data )[0];
					$template_id = explode('_', $arr_data )[1];

					if( $template_id == 'none' )
						continue;
					
					add_filter( 'bricks/posts/query_vars', [ __CLASS__, 'filter_query_args' ], 10, 3 );

					$elements = get_post_meta( $template_id, BRICKS_DB_PAGE_CONTENT, true );
					$template_inline_css = \Bricks\Templates::generate_inline_css( $template_id, $elements );

					$css .= "<style id=\"bricks-inline-css-template-{$template_id}\">{$template_inline_css}</style>";

					$loop_id = \Bricks\Query::is_any_looping();

					$suggestions[] = [ 
						'query' => $_REQUEST['query'],
						'value' => html_entity_decode( do_shortcode("[bricks_template id=\"$template_id\" loopid=\"$loop_id\"]") . $css ),
					];
				
					remove_filter( 'bricks/posts/query_vars', [ __CLASS__, 'filter_query_args' ], 10, 3 );
				}
			}

			if( $term_templates ) {
				$template_ids = explode('|', $term_templates );
				foreach( $template_ids as $template_id ) {
					
					if( $template_id == 'none' )
						continue;

					add_filter( 'bricks/terms/query_vars', [ __CLASS__, 'filter_terms_query_args' ], 10, 3 );

					$elements = get_post_meta( $template_id, BRICKS_DB_PAGE_CONTENT, true );
					$template_inline_css = \Bricks\Templates::generate_inline_css( $template_id, $elements );

					$css .= "<style id=\"bricks-inline-css-template-{$template_id}\">{$template_inline_css}</style>";

					$loop_id = \Bricks\Query::is_any_looping();

					$suggestions[] = [ 
						'query' => $_REQUEST['query'],
						'value' => html_entity_decode( do_shortcode("[bricks_template id=\"$template_id\" loopid=\"$loop_id\"]") . $css ),
					];
				
					remove_filter( 'bricks/terms/query_vars', [ __CLASS__, 'filter_terms_query_args' ], 10, 3 );
				}
			}

			// Reset the main render_data self::$elements
			\Bricks\Frontend::$elements = $store_elements;
		}

		echo wp_send_json( array(
			'suggestions' => $suggestions,
		));

		die();
	}

	/**
	 * Filter the default query args
	 * 
	 * @param $query_vars array query args
	 * @param $settings array element settings
	 * @param $element_id string element ID
	 * 
	 * @return array query args
	 */
	public static function filter_query_args( $query_vars, $settings, $element_id ) {
		global $postData, $wpdb;

		if( $postData ) {
			if( $postData['filterType'] == 'asearch' ) {
				if ( ! empty( $postData['postType'] ) && $postData['postType'] == 'product' 
					&& class_exists('WooCommerce') 
				) {
					$product_visibility_term_ids = \wc_get_product_visibility_term_ids();
					$query_vars['tax_query']['relation'] = 'AND';

					$query_vars['tax_query'][] = array(
						'taxonomy' => 'product_visibility',
						'field'    => 'term_taxonomy_id',
						'terms'    => $product_visibility_term_ids['exclude-from-search'],
						'operator' => 'NOT IN',
					);
					
					if ( ! empty( $postData['taxonomy'] ) && ! empty( $postData['term'] ) ) {
						$query_vars['tax_query'][] = array(
							'taxonomy' => $postData['taxonomy'],
							'field'    => 'slug',
							'terms'    => strip_tags( trim( $postData['term'] ) ),
						);
					}

					/*$query_vars['meta_query'][] = array( 'key' => '_stock_status', 'value' => 'outofstock', 'compare' => 'NOT IN' );*/

					$product_ids = array();
					$sku = wc_clean( $postData['query']);

					$sku_to_parent_id = $wpdb->get_col( $wpdb->prepare( "SELECT p.post_parent as post_id FROM {$wpdb->posts} as p join {$wpdb->wc_product_meta_lookup} wpml on p.ID = wpml.product_id and wpml.sku LIKE '%%%s%%' where p.post_parent <> 0 group by p.post_parent", $sku ) );

					$sku_to_id = $wpdb->get_results( "SELECT product_id FROM {$wpdb->wc_product_meta_lookup} WHERE sku LIKE '%{$sku}%';", ARRAY_N );

					$sku_to_id_results = array();
					if ( is_array( $sku_to_id ) ) {
						foreach ( $sku_to_id as $id ) {
							$sku_to_id_results[] = $id[0];
						}
					}

					$product_ids = array_filter( 
						array_map( 
							'absint', 
							array_merge( $product_ids, $sku_to_id_results, $sku_to_parent_id ) 
						) 
					);

					if ( sizeof( $product_ids ) > 0 ) {
						$query_vars['post__in'] = $product_ids;
						return $query_vars;
					}
				}

				$query_vars['s'] = $postData['query'];

				/*$result = new \WP_Query( $query_vars );
				if($result && $result->have_posts() ) {
					\wp_reset_query();
					return $query_vars;
				}

				\wp_reset_query();*/

				if( ! empty( $postData['meta_query'] ) ) {
					unset( $query_vars['s'] );
					$query_vars['meta_query']['relation'] = $postData['relation'] ?? 'OR';
					foreach( $postData['meta_query'] as $meta_query) {
						$query_vars['meta_query'][] = array( 
							'key' 		=> $meta_query['key'], 
							'value' 	=> $postData['query'], 
							'compare' 	=> $meta_query['compare'],
							'type' 		=> $meta_query['type']
						);
					}
				}
			}

			if( $postData['filterType'] == 'notice' ) {
				$query_vars['p'] = $postData['id'];
				$query_vars['post_type'][] = 'product_variation';
			}
		}

		return $query_vars;
	}

	public static function filter_terms_query_args( $query_vars, $settings, $element_id ) {
		global $postData;
		
		if( $postData ) { 
			$query_vars['name__like'] = $postData['query'];
		}

		return $query_vars;
	}
}