<?php

namespace Objectiv\Plugins\Checkout\Model\Bumps;

use Objectiv\Plugins\Checkout\Interfaces\BumpInterface;
use Objectiv\Plugins\Checkout\Factories\BumpFactory;
use WC_Product;
use WP_Block_Editor_Context;

abstract class BumpAbstract implements BumpInterface {
	protected $id;
	protected $title;
	public $display_for;
	protected $products = array();
	protected $excluded_products;
	protected $excluded_categories;
	protected $minimum_subtotal;
	protected $categories;
	protected $any_product = false;
	protected $location;
	protected $discount_type;
	protected $offer_product;
	protected $auto_add = false;
	protected $offer_discount;
	protected $offer_language;
	protected $offer_description;
	protected $upsell = false;
	protected $offer_quantity;
	protected $match_offer_product_quantity;
	protected $can_quantity_be_updated = false;
	protected $products_to_remove = array();

	public function __construct() {
	}

	/**
	 * Load the bump
	 *
	 * @param $post
	 *
	 * @return bool
	 */
	public function load( $post ): bool {
		$this->id                           = $post->ID;
		$this->title                        = $post->post_title;
		$this->display_for                  = get_post_meta( $post->ID, 'cfw_ob_display_for', true );
		$this->products                     = (array) $this->parse_select_data( get_post_meta( $post->ID, 'cfw_ob_products_v9', true ) );
		$this->excluded_products            = (array) $this->parse_select_data( get_post_meta( $post->ID, 'cfw_ob_exclude_products_v9', true ) );
		$this->excluded_categories          = (array) $this->parse_select_data( get_post_meta( $post->ID, 'cfw_ob_exclude_categories_v9', true ) );
		$this->minimum_subtotal             = get_post_meta( $post->ID, 'cfw_ob_minimum_subtotal', true );
		$this->categories                   = (array) $this->parse_select_data( get_post_meta( $post->ID, 'cfw_ob_categories_v9', true ) );
		$this->any_product                  = get_post_meta( $post->ID, 'cfw_ob_any_product', true ) === 'yes';
		$this->location                     = get_post_meta( $post->ID, 'cfw_ob_display_location', true );
		$this->discount_type                = get_post_meta( $post->ID, 'cfw_ob_discount_type', true );
		$this->offer_product                = $this->parse_select_data( get_post_meta( $post->ID, 'cfw_ob_offer_product_v9', true ) );
		$this->auto_add                     = get_post_meta( $post->ID, 'cfw_ob_auto_add', true ) === 'yes';
		$this->offer_discount               = get_post_meta( $post->ID, 'cfw_ob_offer_discount', true );
		$this->offer_language               = get_post_meta( $post->ID, 'cfw_ob_offer_language', true );
		$this->offer_description            = get_post_meta( $post->ID, 'cfw_ob_offer_description', true );
		$this->upsell                       = get_post_meta( $post->ID, 'cfw_ob_upsell', true ) === 'yes';
		$this->offer_quantity               = get_post_meta( $post->ID, 'cfw_ob_offer_quantity', true );
		$this->match_offer_product_quantity = get_post_meta( $post->ID, 'cfw_ob_match_offer_product_quantity', true ) === 'yes';
		$this->can_quantity_be_updated      = get_post_meta( $post->ID, 'cfw_ob_enable_quantity_updates', true ) === 'yes';
		$this->products_to_remove           = (array) $this->parse_select_data( get_post_meta( $post->ID, 'cfw_ob_products_to_remove_v9', true ) );

		// Get post type of offer_product
		$this->offer_product = cfw_apply_filters( 'wpml_object_id', $this->offer_product, get_post_type( $this->offer_product ), true );

		if ( empty( $this->offer_quantity ) ) {
			$this->offer_quantity = 1;
		}

		if ( empty( $this->minimum_subtotal ) ) {
			$this->minimum_subtotal = 0;
		} else {
			$this->minimum_subtotal = (float) $this->minimum_subtotal;
		}

		return true;
	}

	public function has_custom_add_to_cart_handler(): bool {
		return false;
	}

	public function get_custom_add_to_cart_handler(): string {
		return '';
	}

	private function parse_select_data( $data ) {
		// Check if $data is an array
		if ( ! is_array( $data ) ) {
			return null;
		}

		// Check if the array is non-empty and has the expected structure
		foreach ( $data as $item ) {
			if ( ! is_array( $item ) || ! isset( $item['key'] ) ) {
				return null;
			}
		}

		// If $data contains only one element, return the 'key' of that element
		if ( count( $data ) === 1 ) {
			return $data[0]['key'];
		}

		// If $data contains multiple elements, return an array of 'key' values
		return array_column( $data, 'key' );
	}

	/**
	 * Get bump title
	 *
	 * @return string
	 */
	public function get_title(): string {
		return $this->title;
	}

	/**
	 * Is displayable
	 *
	 * @return bool
	 */
	public function is_displayable(): bool {
		if ( WC()->cart->is_empty() ) {
			return false;
		}

		if ( WC()->cart->get_subtotal() < (float)$this->minimum_subtotal ) {
			return false;
		}

		return true;
	}

	/**
	 * Is cart bump valid
	 *
	 * @return bool
	 */
	public function is_cart_bump_valid(): bool {
		if ( $this->get_subtotal_of_non_bumps() < (float)$this->minimum_subtotal ) {
			return false;
		}

		return true;
	}

	public function get_subtotal_of_non_bumps() {
		$subtotal = 0;

		foreach ( WC()->cart->get_cart() as $cart_item ) {
			if ( ! isset( $cart_item['_cfw_order_bump_id'] ) ) {
				$subtotal += $this->get_cart_item_subtotal( $cart_item['data'], $cart_item['quantity'] );
			}
		}

		return $subtotal;
	}

	public function get_cart_item_subtotal( \WC_Product $product, int $quantity ) {
		$price = $product->get_price();

		if ( $product->is_taxable() ) {

			if ( WC()->cart->display_prices_including_tax() ) {
				$row_price        = wc_get_price_including_tax( $product, array( 'qty' => $quantity ) );
			} else {
				$row_price        = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) );
			}
		} else {
			$row_price        = (float) $price * (float) $quantity;
		}

		return $row_price;
	}

	public function is_published(): bool {
		return get_post_status( $this->id ) === 'publish';
	}

	/**
	 * Is valid upsell
	 *
	 * @return bool
	 */
	public function is_valid_upsell(): bool {
		return $this->upsell && 'specific_products' === $this->display_for && count( $this->products ) === 1;
	}

	public function can_offer_product_be_added_to_the_cart(): bool {
		$product = $this->get_offer_product();

		return $product && $product->is_purchasable() && ( $product->is_in_stock() || $product->backorders_allowed() );
	}

	public function add_bump_meta_to_order_item( $item, $values ) {
		if ( ! $this->is_cart_bump_valid() || ! $this->is_published() ) {
			return;
		}

		$item->update_meta_data( '_cfw_order_bump_id', $values['_cfw_order_bump_id'] );
	}

	public function get_cfw_cart_item_discount( string $price_html, $cart_item ): string {
		if ( ! $this->is_cart_bump_valid() || ! $this->is_published() ) {
			return $price_html;
		}

		return $this->get_offer_product_price( $cart_item['variation_id'] ?? 0 );
	}

	/**
	 * Add to cart
	 *
	 * @throws \Exception
	 */
	public function add_to_cart( \WC_Cart $cart ) {
		$product        = $this->get_offer_product();
		$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(
			'_cfw_order_bump_id' => $this->id,
		);

		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;
			}
		}

		$quantity = $this->get_offer_quantity();

		do_action( 'cfw_before_order_bump_add_to_cart', $this );

		$product_type = $product->get_type();

		if ( has_action( 'cfw_order_bump_add_to_cart_product_type_' . $product_type  ) ) {
			/**
			 * Fires before order bump is added to the cart
			 *
			 * @since 9.0.0
			 * @param string $product_type The product type
			 * @param int $product_id The product ID
			 * @param int $quantity The quantity
			 * @param int $variation_id The variation ID
			 * @param array $variation_data The variation data
			 * @param array $metadata The metadata
			 * @param WC_Product $product The product
			 */
			do_action( 'cfw_order_bump_add_to_cart_product_type_' . $product_type, $product_id, $quantity, $variation_id, $variation_data, $metadata, $product );

			return true;
		}

		try {
			return $cart->add_to_cart( $product_id, $quantity, $variation_id, $variation_data, $metadata );
		} catch ( \Exception $e ) {
			wc_get_logger()->error( 'CheckoutWC: Failed to add order bump to cart. Error: ' . $e->getMessage(), array( 'source' => 'checkout-wc' ) );

			return false;
		}

	}

	/**
	 * @param int $needle_product_id
	 *
	 * @return int
	 */
	public function quantity_of_product_in_cart( int $needle_product_id ): int {
		$needle_product = wc_get_product( $needle_product_id );

		if ( ! $needle_product ) {
			return 0;
		}

		foreach ( WC()->cart->get_cart() as $cart_item ) {
			if ( $this->cart_item_is_product( $cart_item, $needle_product_id ) ) {
				return $cart_item['quantity'];
			}
		}

		return 0;
	}

	/**
	 * @param string $needle_category_id
	 *
	 * @return int
	 */
	public function quantity_of_normal_cart_items_in_category( int $needle_category_id ): int {
		$needle_category = get_term_by( 'term_id', $needle_category_id, 'product_cat' );

		if ( ! $needle_category ) {
			return 0;
		}

		$found = 0;

		foreach ( WC()->cart->get_cart() as $cart_item ) {
			if ( isset( $cart_item['_cfw_order_bump_id'] ) ) {
				continue;
			}

			$cart_item_terms = wp_get_post_terms( $cart_item['product_id'], 'product_cat' );

			/** @var \WP_Term $cart_item_term */
			foreach ( $cart_item_terms as $cart_item_term ) {
				if ( $cart_item_term->term_id === $needle_category_id ) {
					$found ++;
				}
			}
		}

		return $found;
	}

	/**
	 * @return bool
	 */
	public function bump_is_in_cart(): bool {
		foreach ( WC()->cart->get_cart() as $cart_item ) {
			if ( isset( $cart_item['_cfw_order_bump_id'] ) && $cart_item['_cfw_order_bump_id'] === $this->id ) {
				return true;
			}
		}

		return false;
	}

	/**
	 * @param int $needle_product_id
	 *
	 * @return int
	 */
	public function quantity_of_normal_product_in_cart( int $needle_product_id ): int {
		$needle_product = wc_get_product( $needle_product_id );

		if ( ! $needle_product ) {
			return 0;
		}

		foreach ( WC()->cart->get_cart() as $cart_item ) {
			if ( isset( $cart_item['_cfw_order_bump_id'] ) ) {
				continue;
			}

			if ( $this->cart_item_is_product( $cart_item, $needle_product_id ) ) {
				return $cart_item['quantity'];
			}
		}

		return 0;
	}

	protected function cart_item_is_product( array $cart_item, int $product_id ): bool {
		if ( $cart_item['product_id'] === $product_id ) {
			return true;
		}

		if ( empty( $cart_item['variation_id'] ) ) {
			return false;
		}

		if ( $cart_item['variation_id'] === $product_id ) {
			return true;
		}

		return wp_get_post_parent_id( $cart_item['variation_id'] ) === $product_id;
	}

	public function record_purchased() {
		$this->increment_displayed_on_purchases_count();
		$this->increment_purchased_count();
		$this->update_conversion_rate();

		$offer_product = $this->get_offer_product();

		if ( ! $offer_product ) {
			return;
		}

		if ( $this->is_valid_upsell() ) {
			$base_product = wc_get_product( $this->get_products()[0] );

			if ( ! $base_product ) {
				return;
			}

			$new_revenue = $base_product->get_price() - $this->get_price();
		} else {
			$new_revenue = $this->get_price();
		}

		$this->add_captured_revenue( $new_revenue );
	}

	public function display( string $location ): bool {
		if ( ! $this->can_be_displayed( $location ) ) {
			return false;
		}

		$link_wrap        = '<div class="cfw-order-bump-image"><a target="_blank" href="%s">%s</a></div>';
		$offer_product    = $this->get_offer_product();
		$thumb            = $offer_product->get_image( 'cfw_cart_thumb' );
		$wrapped_thumb    = $offer_product->is_visible() ? sprintf( $link_wrap, $offer_product->get_permalink(), $thumb ) : $thumb;
		$variation_parent = $this->get_offer_product()->is_type( 'variable' ) && 0 === $this->get_offer_product()->get_parent_id() && 'no' === get_post_meta( $this->get_id(), 'cfw_ob_enable_auto_match', true );
		?>
		<div class="cfw-order-bump cfw-module">
			<input type="hidden" name="cfw_displayed_order_bump[]" value="<?php echo esc_attr( $this->get_id() ); ?>"/>

			<div class="cfw-order-bump-header">
				<label>
					<input type="checkbox" class="cfw_order_bump_check"
						   name="<?php echo $variation_parent ? 'placeholder' : 'cfw_order_bump[]'; ?>"
						   value="<?php echo esc_attr( $this->get_id() ); ?>"
						   data-variable="<?php echo $variation_parent ? 'true' : 'false'; ?>"
						   data-product="<?php echo $this->get_offer_product()->get_id(); ?>"/>
					<span>
						<?php echo do_shortcode( $this->get_offer_language() ); ?>
					</span>
				</label>
			</div>
			<div class="cfw-order-bump-body">
				<div class="row">
					<div class="col-2">
						<?php echo wp_kses_post( $wrapped_thumb ); ?>
					</div>
					<div class="col-10 cfw-order-bump-content">
						<?php echo do_shortcode( $this->get_offer_description() ); ?>

						<div class="cfw-order-bump-total">
							<?php echo wp_kses_post( $this->get_offer_product_price() ); ?>
						</div>
					</div>
				</div>
			</div>
		</div>
		<?php
		return true;
	}

	public function is_excluded(): bool {
		// If excluded product is in the cart, don't show
		foreach ( $this->get_excluded_products() as $excluded_product ) {
			if ( $this->quantity_of_normal_product_in_cart( (int) $excluded_product ) ) {
				return true;
			}
		}

		cfw_debug_log( var_export( $this->get_excluded_categories(), true ) );

		// If excluded category is in the cart, don't show
		foreach ( $this->get_excluded_categories() as $excluded_category ) {
			if ( $this->quantity_of_normal_cart_items_in_category( $excluded_category ) ) {
				return true;
			}
		}

		return false;
	}

	public function can_be_displayed( $location = 'all' ): bool {
		$display_bump = $this->is_displayable() && $this->is_published() && ! $this->is_excluded() && ( 'all' === $location || $this->get_display_location() === $location );

		/**
		 * Filter whether to display the bump
		 *
		 * @param bool $display_bump Whether to display the bump
		 *
		 * @since 8.0.0
		 */
		$filtered_display_bump = apply_filters( 'cfw_display_bump', $display_bump, $this, $location );

		if ( ! $filtered_display_bump ) {
			return false;
		}

		return true;
	}

	/**
	 * @return int
	 */
	public function get_id(): int {
		return $this->id;
	}

	/**
	 * @return string
	 */
	public function get_offer_language(): string {
		return $this->offer_language;
	}

	/**
	 * @return string
	 */
	public function get_offer_description(): string {
		return $this->offer_description;
	}

	/**
	 * @return mixed
	 */
	public function get_offer_quantity() {
		return $this->offer_quantity;
	}

	/**
	 * @return false|WC_Product|null
	 */
	public function get_offer_product() {
		return wc_get_product( $this->offer_product );
	}

	/**
	 * Get the order bump offer formatted price
	 *
	 * @param int $variation_id
	 *
	 * @return string
	 */
	public function get_offer_product_price( int $variation_id = 0 ): string {
		$product = $this->get_offer_product();

		// If variable product
		if ( $product->is_type( 'variable' ) && $variation_id > 0 ) {
			$product = wc_get_product( $variation_id );
		}

		if ( $product->is_type( 'variable' ) && ! $variation_id ) {
			// Get min and max prices of variable product variations
			$prices = $product->get_variation_prices( true );

			// Get first and last key
			$min_id = key( $prices['price'] );
			$max_id = key( array_slice( $prices['price'], - 1, 1, true ) );

			$min_price = $this->get_price( 'view', $min_id );
			$max_price = $this->get_price( 'view', $max_id );

			if ( $min_price !== $max_price ) {
				return wc_format_price_range( $min_price, $max_price );
			}
		}

		$price      = wc_get_price_to_display( $product, array(
			'price'           => $product->get_regular_price(),
			'display_context' => 'cart'
		) );
		$sale_price = wc_get_price_to_display( $product, array(
			'price'           => $this->get_price( 'view', $variation_id ),
			'display_context' => 'cart'
		) );

		$sale_price_formatted = wc_price( $sale_price );

		if ( 0.00 === $price ) {
			return '<span class="woocommerce-Price-amount amount">' . cfw__( 'Free!', 'woocommerce' ) . '</span>';
		} elseif ( $price > $sale_price ) {
			return wc_format_sale_price( $price, $sale_price );
		}

		return $sale_price_formatted;
	}

	/**
	 * Get the bump price
	 *
	 * @param string $context
	 * @param int $variation_id
	 *
	 * @return float
	 */
	public function get_price( string $context = 'view', int $variation_id = 0 ): float {
		$product = $this->get_offer_product();

		$discount_type = $this->discount_type;
		$discount      = $this->offer_discount;

		if ( $product->is_type( 'variable' ) && $variation_id > 0 ) {
			// Get product variation
			$product = wc_get_product( $variation_id );
		}

		$price = $product->get_price( $context );

		if ( 'percent' === $discount_type && $discount > 0 ) {
			$discount_value = $price * ( $discount / 100 );
		} else {
			$discount_value = $discount;
		}

		// Run amount off discounts through product price filter if we're in a view context
		// This is to allow currency plugins can adjust the currency of the discounted amount properly
		if ( 'view' === $context && 'percent' !== $discount_type ) {
			$discount_value = cfw_apply_filters( 'woocommerce_product_get_price', $discount_value, $product );
		}

		/**
		 * Filter the order bump price.
		 *
		 * @param float $price The price of the order bump.
		 * @param string $context The context of the price.
		 * @param BumpInterface $order_bump The order bump object.
		 *
		 * @since 5.0.0
		 */
		return apply_filters( 'cfw_order_bump_get_price', (float) $price - (float) $discount_value, $context, $this );
	}

	public function get_display_location(): string {
		return $this->location ?? 'below_cart_items';
	}

	/**
	 * Get Displayed On Purchases Count
	 *
	 * The number of times this bump was displayed and a purchase was subsequently made.
	 *
	 * @return integer
	 */
	private function get_displayed_on_purchases_count(): int {
		return intval( get_post_meta( $this->id, 'times_bump_displayed_on_purchases', true ) );
	}

	/**
	 * Get Purchase Count
	 *
	 * The number of times this bump was added to the cart and purchased.
	 *
	 * @return integer
	 */
	public function get_purchase_count(): int {
		return intval( get_post_meta( $this->id, 'times_bump_purchased', true ) );
	}

	public function record_displayed() {
		$this->increment_displayed_on_purchases_count();
		$this->update_conversion_rate();
	}

	public function increment_displayed_on_purchases_count() {
		update_post_meta( $this->id, 'times_bump_displayed_on_purchases', $this->get_displayed_on_purchases_count() + 1 );
	}

	public function increment_purchased_count() {
		update_post_meta( $this->id, 'times_bump_purchased', $this->get_purchase_count() + 1 );
	}

	public function add_captured_revenue( float $new_revenue ) {
		$captured_revenue = max( (float) get_post_meta( $this->id, 'captured_revenue', true ), 0.0 );

		$new_revenue = apply_filters( 'cfw_order_bump_captured_revenue', $new_revenue, $this );

		update_post_meta(
			$this->id,
			'captured_revenue',
			$captured_revenue + $new_revenue
		);
	}

	public function update_conversion_rate() {
		$purchase_count  = $this->get_purchase_count();
		$displayed_count = $this->get_displayed_on_purchases_count();
		$not_calculable  = min( $purchase_count, $displayed_count ) < 1;

		$value = $not_calculable ? 0 : round( $purchase_count / $displayed_count * 100, 2 );

		update_post_meta( $this->id, 'conversion_rate', $value );
	}

	public function get_conversion_rate(): string {
		$value = get_post_meta( $this->id, 'conversion_rate', true );

		return '' === $value ? '--' : floatval( $value ) . '%';
	}

	public function get_item_removal_behavior(): string {
		$value = get_post_meta( $this->id, 'cfw_ob_item_removal_behavior', true );

		return empty( $value ) ? 'keep' : $value;
	}

	public function get_estimated_revenue(): float {
		$offer_product = $this->get_offer_product();

		if ( ! $offer_product ) {
			return 0.0;
		}

		if ( $this->is_valid_upsell() ) {
			$base_product = wc_get_product( $this->get_products()[0] );

			if ( ! $base_product ) {
				return 0.0;
			}

			return ( $base_product->get_price() - $this->get_price() ) * $this->get_purchase_count();
		}

		return $this->get_purchase_count() * $this->get_price();
	}

	public function get_captured_revenue(): float {
		return floatval( get_post_meta( $this->id, 'captured_revenue', true ) );
	}

	/**
	 * @return array
	 */
	public function get_products(): array {
		return (array) $this->products;
	}

	/**
	 * @return array
	 */
	public function get_excluded_products(): array {
		return (array) $this->excluded_products;
	}

	/**
	 * @return array
	 */
	public function get_excluded_categories(): array {
		return (array) $this->excluded_categories;
	}

	public static function get_post_type(): string {
		return 'cfw_order_bumps';
	}

	public static function init( $parent_menu_slug ) {
		$post_type = self::get_post_type();

		add_action(
			'init',
			function () use ( $post_type, $parent_menu_slug ) {
				register_post_type(
					$post_type,
					array(
						'labels'             => array(
							'name'               => cfw__( 'Order Bumps', 'checkout-wc' ),
							'singular_name'      => cfw__( 'Order Bump', 'checkout-wc' ),
							'add_new'            => cfw__( 'Add New', 'checkout-wc' ),
							'add_new_item'       => cfw__( 'Add New Order Bump', 'checkout-wc' ),
							'edit_item'          => cfw__( 'Edit Order Bump', 'checkout-wc' ),
							'new_item'           => cfw__( 'New Order Bump', 'checkout-wc' ),
							'view_item'          => cfw__( 'View Order Bump', 'checkout-wc' ),
							'search_items'       => cfw__( 'Find Order Bump', 'checkout-wc' ),
							'not_found'          => cfw__( 'No order bumps were found.', 'checkout-wc' ),
							'not_found_in_trash' => cfw__( 'Not found in trash', 'checkout-wc' ),
							'menu_name'          => cfw__( 'Order Bumps', 'checkout-wc' ),
						),
						'public'             => false,
						'publicly_queryable' => false,
						'show_ui'            => true,
						'show_in_menu'       => false,
						'show_in_rest'       => true,
						'query_var'          => false,
						'rewrite'            => false,
						'has_archive'        => false,
						'hierarchical'       => false,
						'supports'           => array( 'title', 'page-attributes', 'editor', 'custom-fields' ),
						'template'           => array(
							array(
								'cfw/order-bump-preview',
								array(
									'lock' => array(
										'move'   => true,
										'remove' => true,
									),
								)
							),
						),
						'capabilities'       => array(
							'edit_post'          => 'cfw_manage_order_bumps',
							'read_post'          => 'cfw_manage_order_bumps',
							'delete_post'        => 'cfw_manage_order_bumps',
							'edit_posts'         => 'cfw_manage_order_bumps',
							'edit_others_posts'  => 'cfw_manage_order_bumps',
							'delete_posts'       => 'cfw_manage_order_bumps',
							'publish_posts'      => 'cfw_manage_order_bumps',
							'read_private_posts' => 'cfw_manage_order_bumps',
						),
					)
				);

				add_filter( "rest_prepare_{$post_type}", function ( $response ) {
					if ( empty( $response->data['content']['raw'] ) ) {
						$response->data['template'] = array(
							array(
								'cfw/order-bump-preview',
								array(
									'lock' => array(
										'move'   => true,
										'remove' => true,
									),
								)
							)
						);
					}

					return $response;
				}, 10, 2 );
			}
		);

		// Disable visual block editor for order bumps
//		add_filter(
//			'allowed_block_types_all',
//			function ( $allowed_block_types, WP_Block_Editor_Context $block_editor_context ) {
//				if ( $block_editor_context->post && $block_editor_context->post->post_type !== BumpAbstract::get_post_type() ) {
//					return $allowed_block_types;
//				}
//				return false; // disable all blocks
//			}
//		, 10, 2 );
	}

	/**
	 * @return bool
	 */
	public function is_in_cart(): bool {
		foreach ( WC()->cart->get_cart() as $cart_item ) {
			if ( isset( $cart_item['_cfw_order_bump_id'] ) && $cart_item['_cfw_order_bump_id'] === $this->id ) {
				return true;
			}
		}

		return false;
	}

	/**
	 * @return bool
	 */
	public function can_quantity_be_updated(): bool {
		return $this->can_quantity_be_updated && ! $this->match_offer_product_quantity;
	}

	public function get_products_to_remove(): array {
		return $this->products_to_remove;
	}

	public function should_be_auto_added(): bool {
		return $this->auto_add;
	}

	public function should_match_offer_product_quantity(): bool {
		if ( $this->display_for === 'specific_products' ) {
			return false;
		}

		return $this->match_offer_product_quantity;
	}
}
