<?php
namespace Prodigy\Includes\Frontend\Pages;

use Prodigy\Includes\Content\Prodigy_Request_Maker;
use Prodigy\Includes\Frontend\Mappers\Prodigy_Active_Filter_Data_Mapper;
use Prodigy\Includes\Frontend\Mappers\Prodigy_Filter_Data_Mapper;
use Prodigy\Includes\Frontend\Mappers\Prodigy_Price_Filter_Data_Mapper;
use Prodigy\Includes\Frontend\Mappers\Prodigy_Shop_Products_Data_Mapper;
use Prodigy\Includes\Frontend\Prodigy_Public;
use Prodigy\Includes\Frontend\Shortcodes\Prodigy_Short_Code_Active_Filter;
use Prodigy\Includes\Helpers\Prodigy_Parameters;
use Prodigy\Includes\Helpers\Prodigy_Template;
use Prodigy\Includes\Helpers\Prodigy_Url_Helper;
use Prodigy\Includes\Models\Prodigy_Categories;
use Prodigy\includes\models\Prodigy_Order;
use Prodigy\Includes\Models\Prodigy_Taxonomies;
use Prodigy\Includes\Prodigy;
use Prodigy\Includes\Prodigy_Callback_Api_Listener;
use Prodigy\Includes\Prodigy_Cart;
use Prodigy\Includes\Support\Prodigy_Themes_Support;

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

/**
 * Prodigy shop page class
 *
 * @version    3.2.4
 * @package    prodigy/includes/public/pages
 */
class Prodigy_Shop_Page extends Prodigy_Page {

	public const NUMBER_ITEMS_PER_PAGE = 9;

	/** @var Prodigy_Active_Filter_Data_Mapper  */
	public Prodigy_Active_Filter_Data_Mapper $active_filter_mapper;

	/** @var Prodigy_Shop_Products_Data_Mapper  */
	public Prodigy_Shop_Products_Data_Mapper $shop_products_mapper;

	/** @var Prodigy_Price_Filter_Data_Mapper  */
	public Prodigy_Price_Filter_Data_Mapper $price_filter_mapper;

	/** @var Prodigy_Filter_Data_Mapper  */
	public Prodigy_Filter_Data_Mapper $filter_mapper;

	/** @var Prodigy_Short_Code_Active_Filter  */
	public Prodigy_Short_Code_Active_Filter $short_code_active_filter;

	/**
	 * @param Prodigy_Order                     $order_model
	 * @param Prodigy_Request_Maker             $request_maker
	 * @param Prodigy_Cart                      $cart
	 * @param Prodigy_Callback_Api_Listener     $api_listener
	 * @param Prodigy_Shop_Products_Data_Mapper $shop_product_data_mapper
	 * @param Prodigy_Active_Filter_Data_Mapper $active_filter
	 * @param Prodigy_Filter_Data_Mapper        $filter_data_mapper
	 * @param Prodigy_Short_Code_Active_Filter  $short_code_active_filter
	 * @param Prodigy_Price_Filter_Data_Mapper  $price_filter_mapper
	 *
	 * @throws \Exception
	 */
	public function __construct(
		Prodigy_Order $order_model,
		Prodigy_Request_Maker $request_maker,
		Prodigy_Cart $cart,
		Prodigy_Callback_Api_Listener $api_listener,
		Prodigy_Shop_Products_Data_Mapper $shop_product_data_mapper,
		Prodigy_Active_Filter_Data_Mapper $active_filter,
		Prodigy_Filter_Data_Mapper $filter_data_mapper,
		Prodigy_Short_Code_Active_Filter $short_code_active_filter,
		Prodigy_Price_Filter_Data_Mapper $price_filter_mapper
	) {
		parent::__construct( $order_model, $request_maker, $cart, $api_listener );

		$this->validate_taxonomy_terms();
		$this->active_filter_mapper     = $active_filter;
		$this->shop_products_mapper     = $shop_product_data_mapper;
		$this->price_filter_mapper      = $price_filter_mapper;
		$this->short_code_active_filter = $short_code_active_filter;
		$this->filter_mapper            = $filter_data_mapper;

		$this->set_elementor_shop_render_filter();
		add_action( 'wp_ajax_prodigy-load-shop-filters', array( $this, 'prodigy_get_catalog_filters' ) );
		add_action( 'wp_ajax_nopriv_prodigy-load-shop-filters', array( $this, 'prodigy_get_catalog_filters' ) );
		add_action( 'wp_ajax_prodigy-load-shop-products', array( $this, 'prodigy_get_catalog_products' ) );
		add_action( 'wp_ajax_nopriv_prodigy-load-shop-products', array( $this, 'prodigy_get_catalog_products' ) );
		add_action( 'wp_head', array( $this, 'prodigy_set_meta_tags' ) );
	}


	/**
	 * @return void
	 */
	public function set_elementor_shop_render_filter() {
		if ( Prodigy_Url_Helper::is_archive_page_url( Prodigy_Url_Helper::get_taxonomy_from_url( $this->get_current_page_url() ) ) ) {
			$priority = 10;
			if ( isset( wp_get_theme()->template ) &&
				wp_get_theme()->template === Prodigy_Themes_Support::PRODIGY_DIVI_THEME
			) {
				$priority = 210;
			}
			add_filter( 'template_include', array( $this, 'prodigy_elementor_shop_render' ), $priority );
		}
	}

	/**
	 * @return void
	 */
	private function validate_taxonomy_terms(): void {
		Prodigy_Url_Helper::validate_prodigy_taxonomy_url();
	}

	/**
	 * Render catalog products
	 */
	public function prodigy_get_catalog_products(): array {
		$result               = $this->shop_products_mapper->get_default_parameters();
		$product_template     = empty( $result['products'] ) ? 'shop/no-search-results.php' : 'shop/products-loop.php';
		$result['pagination'] = Prodigy_Template::prodigy_get_template_html( 'shop/pagination.php', array( 'data' => $result['pagination'] ?? array() ) );
		$result['products']   = Prodigy_Template::prodigy_get_template_html( $product_template, $result );

		if ( wp_doing_ajax() ) {
			wp_send_json_success( $result );

			return array();
		}

		return $result;
	}

	/**
	 * Render catalog filters
	 */
	public function prodigy_get_catalog_filters(): array {
		$options        = array(
			'uri'            => $this->page_uri ?? '',
			'attr_shortcode' => $this->active_filter_mapper->get_widget_settings(),
		);
		$filters = $this->filter_mapper->get_default_parameters( $options );

		if ( wp_doing_ajax() ) {
			$active_filter_params   = $this->active_filter_mapper->get_default_parameters( $options );
			$result['active']       = Prodigy_Template::prodigy_get_template_html( 'shortcode/active-filters.php', $active_filter_params );
			$result['filters']      = Prodigy_Template::prodigy_get_template_html( $filters['layout'], $filters );
			$result['price_filter'] = $this->get_price_filter_html();

			wp_send_json_success( $result );

			return array();
		}

		if ( isset( $_GET['filter_widget_id'] ) ) {
			$filter_widget_options = $this->filter_mapper->get_elementor_widget_options( $_GET['filter_widget_id'] );
		}
		$key_filter_widget_options = key( array_filter( $filter_widget_options, 'is_int', ARRAY_FILTER_USE_KEY ) );
		$query_param               = Prodigy_Parameters::get_parameter( $_POST, 'query', 'sanitize_text_field', '' );

		$filter_widget_params = ! empty( $filters ) ? array(
			'filters' => $filters,
			'query'   => $query_param,
			'options' => $filter_widget_options,
		) : array();

		$result['active'] = $this->short_code_active_filter->output( $filter_widget_options[ $key_filter_widget_options ] ?? array(), null, $filter_widget_params );

		return $result;
	}

	/**
	 * @return string
	 */
	private function get_price_filter_html(): string {
		$price_filter_params = $this->price_filter_mapper->get_default_parameters();

		return Prodigy_Template::prodigy_get_template_html( 'shortcode/price-filter.php', $price_filter_params );
	}

	/**
	 * Render shop page
	 */
	public function prodigy_elementor_shop_render(): void {
		if ( Prodigy_Public::skip() ) {
			return;
		}

		$this->render_catalog_template();
	}

	/**
	 * @return void
	 */
	private function render_catalog_template(): void {
		$content_shop = $this->prodigy_get_catalog_products();
		Prodigy_Template::prodigy_get_template( 'archive-product.php', array( 'content' => $content_shop ) );
	}

	/**
	 * Set meta tags from hosted system
	 *
	 * @return void
	 */
	public function prodigy_set_meta_tags(): void {
		$url_params  = wp_parse_url( $this->page_uri );
		$path        = explode( '/', sanitize_url( $url_params['path'] ) );
		$is_category = false;
		foreach ( $path as $key => $part ) {
			if ( ! empty( $part ) && $part === Prodigy::get_prodigy_category_type() ) {
				$is_category = true;
				unset( $path[ $key ] );
				$new_array = array_values( array_diff( $path, array( '' ) ) );
			}
		}

		if ( $is_category ) {
			$category_term = Prodigy_Taxonomies::get_taxonomy_by_different_slugs(
				Prodigy::get_prodigy_category_type(),
				$new_array[0] ?? ''
			);

			if ( isset( $category_term->term_id ) ) {
				$description = get_term_meta( $category_term->term_id, Prodigy_Categories::CATEGORY_META_DESCRIPTION, true );
				$title       = get_term_meta( $category_term->term_id, Prodigy_Categories::CATEGORY_META_TITLE, true );
				?>
							<script>document.title = "<?php echo esc_attr( $title ); ?>";</script>
							<meta name="description" content="<?php echo esc_attr( $description ); ?>"/>
				<?php
			}
		}
	}

	/**
	 * @return array|false|mixed|string|null
	 */
	private function get_current_page_url() {
		$page_id = Prodigy_Parameters::get_parameter( $_GET, 'page_id', 'sanitize_key', 1 );
		if ( isset( $page_id ) ) {
			return $this->page_uri;
		}

		return wp_parse_url( $this->page_uri, PHP_URL_PATH );
	}
}
