<?php
/**
 * Shop Page Integration Feature
 *
 * Advanced integration system for displaying product layouts on shop pages
 * at multiple positions with flexible configuration.
 *
 * @package Product_Display
 */

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

/**
 * Class PRODDISP_Shop_Integration
 *
 * Handles advanced shop page integration with multiple layout positions
 */
class PRODDISP_Shop_Integration {
	/**
	 * The single instance of the class.
	 */
	protected static $_instance = null;

	/**
	 * Available hook positions for shop page integration
	 */
	private $available_positions = array();

	/**
	 * Main Instance.
	 */
	public static function get_instance() {
		if ( is_null(self::$_instance) ) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->init_available_positions();
		$this->init_hooks();
	}

	/**
	 * Initialize available hook positions
	 */
	private function init_available_positions() {
		$this->available_positions = array(
			'before_shop' => array(
				'label' => __('Before Shop Content', 'product-display'),
				'hook' => 'woocommerce_before_main_content',
				'priority' => 5,
				'description' => __('Display above all shop content', 'product-display')
			),
			'after_shop_header' => array(
				'label' => __('After Shop Header', 'product-display'),
				'hook' => 'woocommerce_archive_description',
				'priority' => 15,
				'description' => __('Display after shop title and description', 'product-display')
			),
			'before_products' => array(
				'label' => __('Before Product Grid', 'product-display'),
				'hook' => 'woocommerce_before_shop_loop',
				'priority' => 35,
				'description' => __('Display before the product grid starts', 'product-display')
			),
			'between_products_top' => array(
				'label' => __('Between Products (Top)', 'product-display'),
				'hook' => 'woocommerce_shop_loop_item_title',
				'priority' => 5,
				'description' => __('Display after first few products', 'product-display'),
				'custom_handler' => true
			),
			'between_products_middle' => array(
				'label' => __('Between Products (Middle)', 'product-display'),
				'hook' => 'woocommerce_shop_loop_item_title',
				'priority' => 10,
				'description' => __('Display in middle of product grid', 'product-display'),
				'custom_handler' => true
			),
			'after_products' => array(
				'label' => __('After Product Grid', 'product-display'),
				'hook' => 'woocommerce_after_shop_loop',
				'priority' => 5,
				'description' => __('Display after the product grid ends', 'product-display')
			),
			'after_shop' => array(
				'label' => __('After Shop Content', 'product-display'),
				'hook' => 'woocommerce_after_main_content',
				'priority' => 5,
				'description' => __('Display below all shop content', 'product-display')
			),
			'replace_products' => array(
				'label' => __('Replace Product Grid', 'product-display'),
				'hook' => 'template_redirect',
				'priority' => 1,
				'description' => __('Completely replace the default product grid', 'product-display'),
				'custom_handler' => true
			)
		);
	}

	/**
	 * Initialize hooks
	 */
	private function init_hooks() {
		// Only initialize if shop integration is enabled
		if ( $this->is_shop_integration_enabled() ) {
			add_action('template_redirect', array( $this, 'setup_shop_integrations' ), 1);
		}
	}

	/**
	 * Check if shop integration is enabled
	 */
	private function is_shop_integration_enabled() {
		$integrations = get_option('proddisp_shop_integrations', array());
		return !empty($integrations);
	}

	/**
	 * Setup shop integrations based on current page
	 */
	public function setup_shop_integrations() {
		if ( ! $this->should_apply_integration() ) {
			return;
		}

		// Enqueue shop integration assets
		PRODDISP_Assets::get_instance()->enqueue_shop_integration_assets();

		$integrations = get_option('proddisp_shop_integrations', array());
		
		foreach ( $integrations as $integration ) {
			if ( ! $this->is_integration_active($integration) ) {
				continue;
			}

			$position = $integration['position'];
			
			if ( isset($this->available_positions[$position]) ) {
				$pos_config = $this->available_positions[$position];
				
				if ( isset($pos_config['custom_handler']) && $pos_config['custom_handler'] ) {
					$this->setup_custom_position_handler($position, $integration);
				} else {
					$this->setup_standard_position_handler($pos_config, $integration);
				}
			}
		}
	}

	/**
	 * Check if integration should be applied on current page
	 */
	private function should_apply_integration() {
		// Check if we're on a shop-related page
		if ( is_shop() || is_product_category() || is_product_tag() || is_product_taxonomy() ) {
			return true;
		}

		// Check for custom pages
		$custom_pages = get_option('proddisp_shop_integration_pages', array());
		if ( !empty($custom_pages) && is_page($custom_pages) ) {
			return true;
		}

		return false;
	}

	/**
	 * Check if specific integration is active
	 */
	private function is_integration_active( $integration ) {
		// Check if integration is enabled
		if ( empty($integration['enabled']) ) {
			return false;
		}

		// Check page conditions
		if ( !empty($integration['page_conditions']) ) {
			return $this->check_page_conditions($integration['page_conditions']);
		}

		return true;
	}

	/**
	 * Check page conditions for integration
	 */
	private function check_page_conditions( $conditions ) {
		foreach ( $conditions as $condition ) {
			switch ( $condition['type'] ) {
				case 'shop_page':
					if ( is_shop() ) return true;
					break;
				case 'category_page':
					if ( is_product_category() ) {
						if ( empty($condition['categories']) || in_array(get_queried_object_id(), $condition['categories']) ) {
							return true;
						}
					}
					break;
				case 'tag_page':
					if ( is_product_tag() ) {
						if ( empty($condition['tags']) || in_array(get_queried_object_id(), $condition['tags']) ) {
							return true;
						}
					}
					break;
				case 'custom_page':
					if ( is_page($condition['pages']) ) return true;
					break;
			}
		}
		return false;
	}

	/**
	 * Setup standard position handler
	 */
	private function setup_standard_position_handler( $pos_config, $integration ) {
		add_action(
			$pos_config['hook'],
			function() use ( $integration ) {
				$this->render_integration_layout($integration);
			},
			$pos_config['priority']
		);
	}

	/**
	 * Setup custom position handlers
	 */
	private function setup_custom_position_handler( $position, $integration ) {
		switch ( $position ) {
			case 'between_products_top':
				$this->setup_between_products_handler($integration, 'top');
				break;
			case 'between_products_middle':
				$this->setup_between_products_handler($integration, 'middle');
				break;
			case 'replace_products':
				$this->setup_replace_products_handler($integration);
				break;
		}
	}

	/**
	 * Setup between products handler
	 */
	private function setup_between_products_handler( $integration, $position ) {
		static $product_count = 0;
		static $rendered_positions = array();

		add_action('woocommerce_shop_loop_item_title', function() use ( $integration, $position, &$product_count, &$rendered_positions ) {
			$product_count++;
			
			// Avoid duplicate renders
			if ( in_array($position, $rendered_positions) ) {
				return;
			}

			$insert_after = $this->get_insert_position($position);
			
			if ( $product_count === $insert_after ) {
				echo '<div class="proddisp-between-products proddisp-between-' . esc_attr($position) . '">';
				$this->render_integration_layout($integration);
				echo '</div>';
				$rendered_positions[] = $position;
			}
		}, 1);
	}

	/**
	 * Get insert position for between products
	 */
	private function get_insert_position( $position ) {
		$products_per_page = wc_get_default_products_per_row() * wc_get_default_product_rows_per_page();
		
		switch ( $position ) {
			case 'top':
				return min(3, floor($products_per_page * 0.25));
			case 'middle':
				return floor($products_per_page * 0.5);
			default:
				return 3;
		}
	}

	/**
	 * Setup replace products handler
	 */
	private function setup_replace_products_handler( $integration ) {
		// Completely override the shop loop by capturing and replacing it
		add_action('woocommerce_before_shop_loop', function() use ( $integration ) {
			// Start output buffering to capture and discard the default loop
			ob_start();
		}, 1);
		
		add_action('woocommerce_after_shop_loop', function() use ( $integration ) {
			// Discard the default loop output
			ob_end_clean();
			
			// Render our custom layout instead
			echo '<div class="proddisp-replaced-shop-loop">';
			$this->render_integration_layout($integration);
			echo '</div>';
			
			// Remove pagination since we're showing a custom layout
			remove_action('woocommerce_after_shop_loop', 'woocommerce_pagination', 10);
		}, 1);
		
		// Also prevent individual product templates from loading
		add_filter('wc_get_template_part', function($template, $slug, $name) {
			if ($slug === 'content' && $name === 'product') {
				return false;
			}
			return $template;
		}, 10, 3);
		
		// Handle the no products case
		add_filter('woocommerce_no_products_found', function() use ( $integration ) {
			$this->render_integration_layout($integration);
			return ''; // Return empty to prevent default message
		});
	}

	/**
	 * Render integration layout
	 */
	public function render_integration_layout( $integration ) {
		if ( empty($integration['layout_id']) ) {
			return;
		}

		// Get showcase data
		$showcases = get_option('proddisp_saved_showcases', array());
		if ( !isset($showcases[$integration['layout_id']]) ) {
			return;
		}

		$showcase = $showcases[$integration['layout_id']];
		
		// Build shortcode attributes
		$atts = array(
			'id' => $integration['layout_id']
		);

		// Apply custom settings if specified
		if ( !empty($integration['custom_settings']) ) {
			$atts = array_merge($atts, $integration['custom_settings']);
		}

		// Add wrapper classes
		$wrapper_classes = array(
			'proddisp-shop-integration',
			'proddisp-position-' . $integration['position']
		);

		if ( !empty($integration['custom_class']) ) {
			$wrapper_classes[] = $integration['custom_class'];
		}

		// Output the layout
		echo '<div class="' . esc_attr(implode(' ', $wrapper_classes)) . '">';
		
		if ( !empty($integration['title']) ) {
			echo '<h2 class="proddisp-integration-title">' . esc_html($integration['title']) . '</h2>';
		}

		echo do_shortcode(sprintf(
			'[product_display %s]',
			$this->build_shortcode_attributes($atts)
		));
		
		echo '</div>';
	}

	/**
	 * Build shortcode attributes string
	 */
	private function build_shortcode_attributes( $atts ) {
		$attributes = array();
		foreach ( $atts as $key => $value ) {
			if ( is_array($value) ) {
				$value = implode(',', $value);
			}
			$attributes[] = sprintf('%s="%s"', $key, esc_attr($value));
		}
		return implode(' ', $attributes);
	}

	/**
	 * Get available positions for admin
	 */
	public function get_available_positions() {
		return $this->available_positions;
	}

	/**
	 * Get current integrations
	 */
	public function get_integrations() {
		return get_option('proddisp_shop_integrations', array());
	}

	/**
	 * Save integrations
	 */
	public function save_integrations( $integrations ) {
		return update_option('proddisp_shop_integrations', $integrations);
	}

	/**
	 * Add new integration
	 */
	public function add_integration( $integration ) {
		$integrations = $this->get_integrations();
		$integration['id'] = uniqid('integration_');
		$integrations[] = $integration;
		return $this->save_integrations($integrations);
	}

	/**
	 * Update integration
	 */
	public function update_integration( $integration_id, $integration ) {
		$integrations = $this->get_integrations();
		foreach ( $integrations as $key => $existing ) {
			// Use string comparison to handle type mismatches
			if ( isset($existing['id']) && (string)$existing['id'] === (string)$integration_id ) {
				$integrations[$key] = array_merge($existing, $integration);
				return $this->save_integrations($integrations);
			}
		}
		return false;
	}

	/**
	 * Delete integration
	 */
	public function delete_integration( $integration_id ) {
		$integrations = $this->get_integrations();
		foreach ( $integrations as $key => $existing ) {
			if ( $existing['id'] === $integration_id ) {
				unset($integrations[$key]);
				return $this->save_integrations(array_values($integrations));
			}
		}
		return false;
	}
}