<?php
declare( strict_types=1 );

namespace FiboFilters\Integrations\Themes;

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

/**
 * Class Uncode
 */
class Uncode extends AbstractTheme {
	protected function integrate(): void {
		$this->load_partial( 'uncode/common.php' );

		add_action(
			'init',
			function () {
				/**
				 * This is special case for getting single products on search results page.
				 *
				 * On search results page with active FiboSearch, Uncode theme
				 * uses main query, so we need to filter it to show only needed products.
				 */
				// phpcs:ignore WordPress.Security.NonceVerification.Recommended
				if ( isset( $_REQUEST['fibofilters-products'] ) && isset( $_REQUEST['dgwt_wcas'] ) ) {
					add_action(
						'pre_get_posts',
						function ( \WP_Query $query ) {
							if ( $query->is_main_query() ) {
								$single_product_ids = apply_filters( 'fibofilters/request/get_single_product_ids', [] );
								if ( ! empty( $single_product_ids ) ) {
									$query->set( 'post__in', $single_product_ids );
									$query->set( 'tax_query', [] );
									$query->set( 'meta_query', [] );
									$query->set( 'posts_per_page', - 1 );
								}
							}
						},
						PHP_INT_MAX - 5
					);
				}

				if ( ! function_exists( 'ot_get_option' ) ) {
					return;
				}

				// Choosing integration type.
				$uncode_block_id = ot_get_option( '_uncode_product_index_content_block' );
				if ( empty( ! $uncode_block_id ) && defined( 'UNCODE_IS_CUSTOM_WPB_VC' ) && UNCODE_IS_CUSTOM_WPB_VC ) {
					/**
					 * Uncode template for products built with WPBakery.
					 * See:
					 * - Content Block: https://support.undsgn.com/docs/uncode/knowledge-base/content-blocks/
					 * - Uncode >> Theme Options >> Archives >> Products >> Content >> Content Block
					 */
					$this->load_partial( 'uncode/wpbakery.php' );

					add_action( 'wp', [ $this, 'support_wpbakery_posts' ] );
				} else {
					/**
					 * Default Uncode template for products.
					 */
					$this->load_partial( 'uncode/default.php' );
				}
			}
		);
	}

	public function support_wpbakery_posts() {
		$context = apply_filters( 'fibofilters/request/get_context', [] );

		if ( empty( $context['show_filters'] ) && empty( $context['is_get_products'] ) ) {
			return;
		}

		if ( ! function_exists( 'ot_get_option' ) ) {
			return;
		}

		$uncode_block_id = ot_get_option( '_uncode_product_index_content_block' );
		// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
		$uncode_block_id = apply_filters( 'wpml_object_id', $uncode_block_id, 'post' );
		$content         = get_post_field( 'post_content', $uncode_block_id );

		if ( $this->wp_helper->has_shortcode( $content, 'uncode_index' ) ) {
			$shortcodes = $this->wp_helper->get_shortcodes( $content, 'uncode_index' );
			foreach ( $shortcodes as $shortcode ) {
				// Integrate with Uncode Index shortcode only if it uses default query (Dynamic Query === 'yes').
				if ( isset( $shortcode['atts']['auto_query'] ) && $shortcode['atts']['auto_query'] === 'yes' ) {
					$this->integrate_with_posts_widget( $shortcode['atts'] ?? [] );
					break;
				}
			}
		}
	}

	public function integrate_with_posts_widget( array $shortcode_atts ): void {
		$el_id = $shortcode_atts['el_id'] ?? '';

		/**
		 * Add required classes ('product', 'post-XX') to the Uncode Index shortcode block data.
		 */
		add_filter(
			'uncode_index_shortcode_block_data',
			function ( $block_data, $atts ) use ( $el_id ) {
				if ( ! empty( $block_data['product'] ) && ! empty( $block_data['id'] ) && $atts['el_id'] === $el_id ) {
					$block_data['classes'][] = 'product';
					$block_data['classes'][] = 'post-' . $block_data['id'];
				}

				return $block_data;
			},
			10,
			2
		);

		/**
		 * Set products loop selector.
		 */
		add_filter(
			'fibofilters/config/products_loop_selectors',
			fn() => [ sprintf( '#%s .grid-container', esc_attr( $el_id ) ) ]
		);

		/**
		 * Inject FiboFilters shortcodes before and after products loop.
		 */
		add_filter(
			'vc_shortcode_content_filter_after',
			function ( $output, $shortcode, $atts ) use ( $el_id ) {
				if ( $shortcode === 'uncode_index' && isset( $atts['el_id'] ) && $atts['el_id'] === $el_id ) {
					// Break early if "Filters location" is set to "custom".
					if ( $this->get_config_value( 'filter_location' ) === 'custom' ) {
						return $output;
					}

					$injection_start = do_shortcode( '[fibofilters layout=mobile]' ) .
										do_shortcode( '[fibofilters layout=horizontal]' ) .
										do_shortcode( '[fibofilters_applied_filters]' ) .
										do_shortcode( '[fibofilters_show_previous_products_btn]' );
					$output          = preg_replace(
						'/^(\s*<div\b[^>]*>)/i',
						'$1' . $injection_start,
						$output,
						1 // Only the first opening <div>.
					);

					$injection_end       = '';
					$pagination_strategy = $this->get_config_value( 'pagination_strategy' );
					if ( $pagination_strategy === 'show-more-button' ) {
						$injection_end = do_shortcode( '[fibofilters_show_more_products_btn]' );
					} elseif ( $pagination_strategy === 'infinite-scroll' ) {
						$injection_end = do_shortcode( '[fibofilters_infinite_scroll_trigger]' );
					}
					if ( ! empty( $injection_end ) ) {
						$output = preg_replace(
							'/(<\/div>\s*)$/i',
							$injection_end . '$1',
							$output,
							1 // Only the last closing </div>.
						);
					}
				}

				return $output;
			},
			10,
			3
		);

		add_filter( 'fibofilters/request/single_products/break_early', '__return_true' );
		add_filter( 'fibofilters/request/skip_main_query_filtering', '__return_true' );

		/**
		 * Override Uncode Index shortcode query arguments to display only selected products.
		 */
		add_filter(
			'uncode_get_uncode_index_args',
			function ( $args ) {
				// Single products request.
				$single_product_ids = apply_filters( 'fibofilters/request/get_single_product_ids', [] );
				if ( ! empty( $single_product_ids ) ) {
					$args['post__in']       = $single_product_ids;
					$args['tax_query']      = [];
					$args['meta_query']     = [];
					$args['posts_per_page'] = - 1;
				}

				// Request wit active filters.
				$filtered_products_ids = apply_filters( 'fibofilters/request/filtered_product_ids', [] );
				if ( ! empty( $filtered_products_ids ) ) {
					$args['post__in'] = $filtered_products_ids;
				}

				return $args;
			}
		);
	}
}
