<?php
/**
 * Base Layout Class for WC Product Display.
 *
 * @package Product_Display.
 */

// Exit if accessed directly.
if ( ! defined('ABSPATH') ) {
	exit;
}

/**
 * Abstract Class PRODDISP_Layout_Base.
 *
 * This class serves as a base for all layout classes in the product display plugin.
 * It provides common methods for rendering product actions, content, and other utilities.
 */
abstract class PRODDISP_Layout_Base {
	/**
	 * Layout settings.
	 */
	protected $settings;

	/**
	 * Constructor.
	 *
	 * @param array $settings Layout settings.
	 */
	public function __construct( $settings ) {
		$this->settings = $settings;
	}

	/**
	 * Render the layout.
	 *
	 * @param array $products WooCommerce product objects.
	 * @return string HTML output.
	 */
	abstract public function render( $products );

	/**
	 * Render product action buttons (compare, wishlist, quickview, add to cart).
	 *
	 * @param Product_Display $product The product object.
	 * @return string HTML for the action buttons.
	 */
	protected function render_product_actions( $product ) {

		$position_class = 'wcps-actions-' . esc_attr($this->settings['action_position']);
		$output = '<div class="wcps-product-actions ' . $position_class . '">';

		// Add to Cart.
		if ( 'yes' === $this->settings['show_addtocart'] ) {
			$output .= $this->render_add_to_cart_button($product);
		}

		// Quick View.
		if ( 'yes' === $this->settings['show_quickview'] ) {
			$output .= $this->render_quickview_button($product);
		}

		// Wishlist- feature- wishlist
		if ( 'yes' === $this->settings['show_wishlist'] ) {
			$output .= $this->render_wishlist_button($product);
		}

		// Compare.
		if ( 'yes' === $this->settings['show_compare'] ) {
			$output .= $this->render_compare_button($product);
		}

		$output .= '</div>';
		return $output;
	}

	/**
	 * Render Add to Cart button.
	 *
	 * @param Product_Display $product The product object.
	 * @return string HTML for the add to cart button.
	 */
	protected function render_add_to_cart_button( $product ) {

		// Get icon and display mode settings.
		$addtocart_icon = isset($this->settings['addtocart_icon']) ? $this->settings['addtocart_icon'] : 'fas fa-shopping-cart';
		$addtocart_display = isset($this->settings['addtocart_display_mode']) ? $this->settings['addtocart_display_mode'] : 'icon_text';

		$icon_class_load = $this->settings['addtocart_display_mode'] === 'icon_only' ? 'wcps-addtocart-icon-only' : '';

		// Add product type class for proper handling of variable/grouped products
		$product_type = $product->get_type();
		$product_type_class = 'product_type_' . $product_type;

		$args = array(
			'quantity' => 1,
			'class'    => trim('wcps-add-to-cart ' . $icon_class_load . ' ' . $product_type_class),
		);

		$button_content = $this->format_button_content_with_cta(
			$addtocart_display,
			$addtocart_icon,
			$product->add_to_cart_text()
		);

		return apply_filters(
			'woocommerce_loop_add_to_cart_link',
			sprintf(
				'<a href="%s" data-quantity="%s" data-product-id="%s" class="%s wcps-add-to-cart-button" %s>%s</a>',
				esc_url($product->add_to_cart_url()),
				esc_attr(isset($args['quantity']) ? $args['quantity'] : 1),
				esc_attr($product->get_id()),
				esc_attr(isset($args['class']) ? $args['class'] : 'button'),
				isset($args['attributes']) ? wc_implode_html_attributes($args['attributes']) : '',
				$button_content
			),
			$product,
			$args
		);
	}

	/**
	 * Render Quick View button.
	 *
	 * @param Product_Display $product The product object.
	 * @return string HTML for the quickview button.
	 */
	protected function render_quickview_button( $product ) {
		// Get icon and display mode settings.
		$quickview_icon = isset($this->settings['quickview_icon']) ? $this->settings['quickview_icon'] : 'fa-eye';
		$quickview_display = isset($this->settings['quickview_display_mode']) ? $this->settings['quickview_display_mode'] : 'icon_text';
		$icon_class_load = $this->settings['quickview_display_mode'] === 'icon_only' ? 'wcps-quickview-icon-only' : '';

		$button_content = $this->format_button_content_with_cta(
			$quickview_display,
			$quickview_icon,
			esc_html__('Quick View', 'product-display')
		);

		return '<a href="#" class="' . esc_attr(trim('wcps-quickview ' . $icon_class_load)) . '" data-product-id="' . esc_attr($product->get_id()) . '">'
		. $button_content
		. '</a>';
	}

	/**
	 * Render Wishlist button.
	 *
	 * @param Product_Display $product The product object.
	 * @return string HTML for the wishlist button.
	 * Feature: Wishlist
	 * @since 1.0.0
	 */
	protected function render_wishlist_button( $product ) {
		// Check if wishlist class exists
		if ( ! class_exists('PRODDISP_Wishlist') ) {
			// Return basic wishlist button without functionality
			$button_class = 'wcps-wishlist';
			$button_text = esc_html__('Add to Wishlist', 'product-display');
			$in_wishlist = false;
		} else {
			// Get wishlist instance.
			$wishlist = PRODDISP_Wishlist::get_instance();

			// Check if product is in wishlist.
			$in_wishlist = $wishlist->is_in_wishlist($product->get_id());

			// Set button classes and text based on wishlist status.
			$button_class = $in_wishlist ? 'wcps-wishlist in-wishlist' : 'wcps-wishlist';
			$button_text = $in_wishlist ?
				esc_html__('Remove from Wishlist', 'product-display') :
				esc_html__('Add to Wishlist', 'product-display');
		}

		// Get icon and display mode settings.
		$wishlist_icon = isset($this->settings['wishlist_icon']) ? $this->settings['wishlist_icon'] : 'fa-heart';
		$wishlist_display = isset($this->settings['wishlist_display_mode']) ? $this->settings['wishlist_display_mode'] : 'icon_text';
		$icon_class_load = $this->settings['wishlist_display_mode'] === 'icon_only' ? 'wcps-wishlist-icon-only' : '';

		// Append the icon-only class dynamically.
		$button_class .= ' ' . $icon_class_load;

		$button_content = $this->format_button_content_with_cta(
			$wishlist_display,
			$wishlist_icon,
			$button_text
		);

		return '<a href="#" class="' . esc_attr($button_class) . '" data-product-id="' . esc_attr($product->get_id()) . '">'
			. $button_content
		. '</a>';
	}

	/**
	 * Render Compare button.
	 *
	 * @param Product_Display $product The product object.
	 * @return string HTML for the compare button.
	 */
	protected function render_compare_button( $product ) {
		// Get icon and display mode settings.
		$compare_icon = isset($this->settings['compare_icon']) ? $this->settings['compare_icon'] : 'fa-chart-bar';
		$compare_display = isset($this->settings['compare_display_mode']) ? $this->settings['compare_display_mode'] : 'icon_text';
		$icon_class_load = $this->settings['compare_display_mode'] === 'icon_only' ? 'wcps-compare-icon-only' : '';

		$button_content = $this->format_button_content_with_cta(
			$compare_display,
			$compare_icon,
			esc_html__('Compare', 'product-display')
		);

		return '<a href="#" class="' . esc_attr(trim('wcps-compare ' . $icon_class_load)) . '" data-product-id="' . esc_attr($product->get_id()) . '">'
			. $button_content
		. '</a>';
	}

	/**
	 * Format button content with CTA text positioned beside icon.
	 *
	 * @param string $display_mode Display mode (icon_text, icon_only, text_only).
	 * @param string $icon Icon class.
	 * @param string $text Button text.
	 * @return string Formatted button content with CTA positioning.
	 */
	protected function format_button_content_with_cta( $display_mode, $icon, $text ) {
		$output = '';

		if ( 'text_only' === $display_mode ) {
			// For text_only mode, show text in place of icon (no CTA tooltip)
			$output .= '<span class="wcps-btn-text">' . $text . '</span>';
		} else {
			// For icon_text and icon_only modes, use the CTA structure
			if ( 'icon_text' === $display_mode || 'icon_only' === $display_mode ) {
				// Clean up icon class - remove duplicate 'fas' if it exists
				$clean_icon = $icon;
				if ( strpos($icon, 'fas ') === 0 ) {
					// Icon already has 'fas' prefix, use as is
					$output .= '<span class="wcps-btn-icon"><i class="' . esc_attr($clean_icon) . '"></i></span>';
				} else {
					// Icon doesn't have 'fas' prefix, add it
					$output .= '<span class="wcps-btn-icon"><i class="fas ' . esc_attr($clean_icon) . '"></i></span>';
				}
			}

			if ( 'icon_text' === $display_mode ) {
				$output .= '<span class="wcps-btn-cta">' . $text . '</span>';
			}
		}

		return $output;
	}


	/**
	 * Render product content (title, price, rating, description).
	 *
	 * @param Product_Display $product The product object.
	 * @return string HTML for the product content.
	 */
	protected function render_product_content( $product ) {
		$output = '<div class="wcps-product-content">';

		// Title.
		if ( 'yes' === $this->settings['show_title'] ) {
			$output .= '<h2 class="wcps-product-title" itemprop="name">
                <a href="' . esc_url(get_permalink($product->get_id())) . '">' . esc_html($product->get_name()) . '</a>
            </h2>';
		}

		// Price.
		if ( 'yes' === $this->settings['show_price'] ) {
			$output .= '<div class="wcps-product-price" itemprop="offers" itemscope itemtype="https://schema.org/Offer">';
			$output .= '<meta itemprop="price" content="' . esc_attr($product->get_price()) . '">';
			$output .= '<meta itemprop="priceCurrency" content="' . esc_attr(get_woocommerce_currency()) . '">';
			$output .= '<meta itemprop="availability" content="' . ( $product->is_in_stock() ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock' ) . '">';
			$output .= $product->get_price_html();
			$output .= '</div>';
		}

		// Rating.
		if ( 'yes' === $this->settings['show_rating'] && wc_review_ratings_enabled() && $product->get_rating_count() > 0 ) {
			$output .= '<div class="wcps-product-rating" itemprop="aggregateRating" itemscope itemtype="https://schema.org/AggregateRating">';
			$output .= '<meta itemprop="ratingValue" content="' . esc_attr($product->get_average_rating()) . '">';
			$output .= '<meta itemprop="reviewCount" content="' . esc_attr($product->get_rating_count()) . '">';
			$output .= '<meta itemprop="bestRating" content="5">';
			$output .= '<meta itemprop="worstRating" content="1">';
			$output .= wc_get_rating_html($product->get_average_rating());
			$output .= '</div>';
		}

		// Description.
		if ( 'yes' === $this->settings['show_description'] ) {
			$excerpt = $product->get_short_description();
			if ( empty($excerpt) ) {
				$excerpt = $product->get_description();
			}

			if ( ! empty($excerpt) ) {
				$excerpt = wp_trim_words($excerpt, $this->settings['excerpt_length'], '...');
				$output .= '<div class="wcps-product-description" itemprop="description"><p class="wcps-product-description-content">' . wp_kses_post($excerpt) . '</p></div>';
			}
		}

		$output .= '</div>';
		return $output;
	}

	/**
	 * Check if Product Display Pro is active.
	 *
	 * @return bool True if pro plugin is active, false otherwise.
	 */
	protected function is_pro_active() {
		return PRODDISP_Loader::is_pro_active();
	}

	/**
	 * Render locked pro layout.
	 *
	 * @param string $image_filename The locked layout image filename.
	 * @return string HTML output for locked layout.
	 */
	protected function render_locked_layout( $image_filename ) {
		return PRODDISP_Loader::render_locked_layout($image_filename);
	}

	/**
	 * Load pro layout class using Composer autoloading.
	 *
	 * @param string $layout_class The pro layout class name.
	 * @param array  $products Products array.
	 * @return string HTML output from pro layout.
	 */
	protected function load_pro_layout( $layout_class, $products ) {
		return PRODDISP_Loader::load_pro_layout($layout_class, $this->settings, $products);
	}

	/**
	 * Check if layout mode is pro and handle accordingly.
	 *
	 * @param string $layout_mode The layout mode to check.
	 * @param string $pro_class The pro class name to load.
	 * @param string $locked_image The locked image filename.
	 * @param array  $products Products array.
	 * @return string|false HTML output if pro layout is loaded, false if not pro mode.
	 */
	protected function handle_pro_layout_mode( $layout_mode, $pro_class, $locked_image, $products ) {
		if ( ! empty($this->settings['proddisp_layout_mode']) && $this->settings['proddisp_layout_mode'] === $layout_mode ) {
			if ( ! $this->is_pro_active() ) {
				return $this->render_locked_layout($locked_image);
			} else {
				return $this->load_pro_layout($pro_class, $products);
			}
		}
		return false;
	}
}
