<?php
/**
 * Product layout class.
 *
 * @package Neve\Views
 */

namespace Neve\Views;

/**
 * Class Product_Layout
 *
 * @package Neve\Views
 */
class Product_Layout extends Base_View {

	/**
	 * Init function.
	 */
	public function init() {
		if ( ! $this->should_load() ) {
			return;
		}
		add_action( 'woocommerce_after_single_product_summary', array( $this, 'render_exclusive_products_section' ), 20 );
		add_filter( 'body_class', array( $this, 'body_classes' ) );
		add_action( 'woocommerce_before_shop_loop_item', array( $this, 'card_content_wrapper' ), 1 );
		add_action( 'woocommerce_after_shop_loop_item', array( $this, 'wrapper_close_div' ), 100 );

		// Wrap product image in a div and add another div for buttons on image option
		add_action( 'woocommerce_before_shop_loop_item_title', array( $this, 'product_image_wrap' ), 8 );
		add_action( 'woocommerce_before_shop_loop_item_title', array( $this, 'out_of_stock_badge' ), 9 );

		// We are using this twice since product_image_wrap is opening two divs which needs to be closed.
		add_action( 'woocommerce_before_shop_loop_item_title', array( $this, 'wrapper_close_div' ), 11 );
		add_action( 'woocommerce_before_shop_loop_item_title', array( $this, 'wrapper_close_div' ), 14 );

	}

	/**
	 * Product image wrapper.
	 */
	public function product_image_wrap() {
		$product_classes = apply_filters( 'neve_wrapper_class', '' );
		echo '<div class="sp-product-image ' . esc_attr( $product_classes ) . '">';
		/**
		 * Fires before the product warpper is rendered.
		 *
		 * @since 2.11
		 */
		do_action( 'neve_product_image_wrap_before' );
		echo '<div class="img-wrap">';
	}

	/**
	 * Closing tag
	 */
	public function wrapper_close_div() {
		echo '</div>';
	}
	/**
	 * Add out of stock label.
	 */
	public function out_of_stock_badge() {
		global $product;
		if ( $product->is_in_stock() ) {
			return;
		}
		$out_of_stock_label = apply_filters( 'nv_out_of_stock_text', __( 'Out of stock', 'neve' ) );

		echo '<div class="out-of-stock-badge">';
		echo wp_kses_post( $out_of_stock_label );
		echo '</div>';
	}

	/**
	 * Wrapper for card content.
	 */
	public function card_content_wrapper() {
		$card_attributes = apply_filters(
			'nv_product_card_wrapper_attributes',
			[
				'class' => 'nv-card-content-wrapper',
			]
		);

		$attributes = '';
		foreach ( $card_attributes as $attr => $val ) {
			$attributes .= ' ' . $attr . '="' . $val . '"';
		}

		echo wp_kses_post( '<div ' . $attributes . '>' );
	}

	/**
	 * Check if the class should load.
	 *
	 * @return bool
	 */
	private function should_load() {
		return class_exists( 'WooCommerce', false );
	}

	/**
	 * Render exclusive products section
	 */
	public function render_exclusive_products_section() {
		$products_category = get_theme_mod( 'neve_exclusive_products_category', '-' );
		if ( $products_category === '-' || neve_is_amp() ) {
			return;
		}

		$title = get_theme_mod( 'neve_exclusive_products_title' );

		$query_args = array(
			'post_type'           => 'product',
			'post_status'         => 'publish',
			'ignore_sticky_posts' => 1,
			'posts_per_page'      => 10,
		);

		if ( $products_category !== 'all' ) {
			$query_args['tax_query'] = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
				array(
					'taxonomy' => 'product_cat',
					'field'    => 'term_id', // This is optional, as it defaults to 'term_id'
					'terms'    => $products_category,
					'operator' => 'IN', // Possible values are 'IN', 'NOT IN', 'AND'.
				),
				array(
					'taxonomy' => 'product_visibility',
					'field'    => 'slug',
					'terms'    => 'exclude-from-catalog', // Possibly 'exclude-from-search' too
					'operator' => 'NOT IN',
				),
			);
		}

		$loop = new \WP_Query( $query_args );
		if ( ! $loop->have_posts() ) {
			return;
		}
		$dots = 0;
		echo '<section class="' . esc_attr( apply_filters( 'neve_exclusive_products_class', 'exclusive products' ) ) . '">';
		if ( ! empty( $title ) ) {
			echo '<h2>' . wp_kses_post( $title ) . '</h2>';
		}

		echo '<ul class="products exclusive-products">';
		add_filter( 'woocommerce_post_class', array( $this, 'prefix_post_class' ), 21 );
		while ( $loop->have_posts() ) { // @phpstan-ignore-line impure WP function
			$loop->the_post();
			wc_get_template_part( 'content', 'product' );
			$dots++;
		} // @phpstan-ignore-next-line code is reachable
		remove_filter( 'woocommerce_post_class', array( $this, 'prefix_post_class' ) );
		wp_reset_postdata();
		echo '</ul>';

		if ( $loop->post_count > 4 ) {
			echo '<div class="dots-nav">';
			for ( $i = 0; $i < $dots; $i++ ) {
				echo '<a class="dot"></a>';
			}
			echo '</div>';
		}

		echo '</section>';
	}

	/**
	 * Function that remove woocommerce first / last classes on products.
	 * This function is applied only on Exclusive products.
	 *
	 * @param array $classes WooCommerce classes on products.
	 *
	 * @return array|mixed
	 */
	public function prefix_post_class( $classes ) {
		if ( 'product' === get_post_type() ) {
			$classes = array_diff( $classes, array( 'first', 'last' ) );
		}
		return $classes;
	}

	/**
	 * Add body classes contextually.
	 *
	 * @param array $classes the body classes.
	 *
	 * @return array
	 */
	public function body_classes( $classes ) {
		$products_category = get_theme_mod( 'neve_exclusive_products_category', '-' );
		if ( $products_category === '-' || ! is_product() ) {
			return $classes;
		}
		$classes[] = 'nv-exclusive';

		return $classes;
	}
}
