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

use Prodigy\Includes\Content\Prodigy_Products_List_Parser;
use Prodigy\Includes\Content\Prodigy_Request_Maker;
use Prodigy\includes\helpers\Prodigy_Elementor;
use Prodigy\includes\helpers\Prodigy_Elementor_Layouts;
use Prodigy\Includes\Helpers\Prodigy_Page;
use Prodigy\Includes\Helpers\Prodigy_Platform_Settings;
use Prodigy\Includes\Helpers\Prodigy_Widget_Options;
use Prodigy\Includes\Prodigy_Elementor_Template_Loader;
use Prodigy\Includes\Prodigy_Pagination;
use Prodigy\Includes\Support\Addons\Elementor\Widgets\Archive\Prodigy_Products;
use Prodigy\Includes\Support\Customizer\Prodigy_Customizer;

/**
 * Prodigy shop page data mapper
 *
 * @version    3.1.2
 * @package    Prodigy
 * @subpackage Prodigy/includes
 */
class Prodigy_Shop_Products_Data_Mapper extends Prodigy_Main_Data_Mapper {

	public const STOCK_ITEM_CATEGORY = 'STOCKED ITEM';


	/**
	 * @param array $options
	 *
	 * @return array
	 */
	public function get_default_parameters( array $options = array() ): array {
		$prepared_params = $this->clear_catalog_params( $_GET );
		if ( isset( $_GET['products_widget_id'] ) && Prodigy_Elementor::is_elementor_enabled() ) {
			$options = Prodigy_Elementor::get_widget_options( ( new Prodigy_Products() )->get_name(), $_GET['products_widget_id'] );
		}

		$options                = $this->prepare_elementor_options( $options );
		$query_params           = $this->build_query_params( $prepared_params, $options );
		$per_page               = $options['content_archive_products_content_items_number'] ?? Prodigy_Pagination::get_per_page_by_options();
		$products_response      = $this->fetch_products( $query_params, $per_page );
		$options['products']    = ( new Prodigy_Products_List_Parser( $products_response ) )->get_products();
		$options['image_ratio'] = $this->calculate_image_ratio( $options );
		$this->set_product_classnames( $options );
		$is_enable_logo_app = Prodigy_Platform_Settings::is_enable_logo_app();
		if ( ! Prodigy_Elementor_Layouts::is_using_archive_elementor_templates() || ! Prodigy_Elementor_Layouts::is_elementor_live_preview() ) {
			$customiser_quick_view        = ! isset( $this->customizer_shop_options['prodigy_shop_products_quick_view'] ) || $this->customizer_shop_options['prodigy_shop_products_quick_view'];
			$options['enable_quick_view'] = ! $is_enable_logo_app && $customiser_quick_view;
		} else {
			$options['enable_quick_view'] = ! $is_enable_logo_app;
		}
		$options['enable_rating']     = $this->check_setting_toggle( $options, 'rating', Prodigy_Elementor::ELEMENTOR_RATING_OPTION );
		$options['enable_sale_badge'] = $this->check_setting_toggle( $options, 'sale', Prodigy_Elementor::ELEMENTOR_SALE_OPTION );
		$options['is_show_search']    = $this->check_setting_toggle( $options, 'search_bar' );
		$options['enable_category']   = ! empty( $options['content_archive_products_content_category'] ) && Prodigy_Widget_Options::$bool_mapper[ $options['content_archive_products_content_category'] ];
		$options['quick_view_title']  = ! empty( $options['content_archive_products_content_quick_view_title'] ) ? $options['content_archive_products_content_quick_view_title'] : __( 'Quick view', 'prodigy-commerce' );
		$options['page_object']       = get_queried_object();
		$options['show_min_price']    = ! Prodigy_Platform_Settings::is_product_page_price_range_settings();

		$total_number = $options['products'][0]['attributes']['products-count'] ?? 0;

		if ( ! empty( $options['products'] ) ) {
			$options['pagination'] = $this->build_pagination( $prepared_params, $total_number, (int) $per_page );
		}

		return $options;
	}


	/**
	 * @param string $query_params
	 * @param int    $per_page
	 *
	 * @return array
	 */
	private function fetch_products( string $query_params, int $per_page ): array {
		$query        = $this->main_content->catalog_query_builder( $query_params, $per_page );
		$requestMaker = Prodigy_Request_Maker::get_instance();
		$response     = Prodigy_Page::prodigy_is_frontend()
			? $requestMaker->do_products_request( $query )
			: $requestMaker->do_admin_products_request( $query );

		return $response;
	}

	/**
	 * @param array $params
	 * @param int   $total_number
	 * @param int   $per_page
	 *
	 * @return array
	 */
	private function build_pagination( array $params, int $total_number, int $per_page ): array {
		return array(
			'pages'       => Prodigy_Pagination::calculate_count_pages( $total_number, $per_page ),
			'url'         => $this->build_catalog_url(),
			'page'        => Prodigy_Pagination::get_current_page( $params ),
			'page_number' => $params['pg'] ?? 1,
		);
	}

	/**
	 *
	 * @return string
	 */
	public function build_catalog_url(): string {
		global $wp;

		$url       = isset( $_GET['current_url'] ) ? sanitize_url( wp_unslash( $_GET['current_url'] ) ) : '';
		$attr      = isset( $_GET['attr'] ) ? (array) $_GET['attr'] : array();
		$max_price = isset( $_GET['price_max'] ) ? sanitize_text_field( wp_unslash( $_GET['price_max'] ) ) : '';
		$min_price = isset( $_GET['price_min'] ) ? sanitize_text_field( wp_unslash( $_GET['price_min'] ) ) : '';
		$sort      = isset( $_GET['sort'] ) ? sanitize_text_field( wp_unslash( $_GET['sort'] ) ) : '';
		$page_id   = isset( $_GET['page_id'] ) ? sanitize_key( wp_unslash( $_GET['page_id'] ) ) : '';

		$current_url = ! empty( $url ) ? $url : home_url( $wp->request );

		if ( ! empty( $attr ) && ! empty( $current_url ) ) {
			$args = array();
			foreach ( $attr as $key => $value ) {
				$args[ 'attr[' . sanitize_key( $key ) . ']' ] = sanitize_text_field( $value );
			}
			$current_url = add_query_arg( $args, $current_url );
		}

		if ( ! empty( $max_price ) && ! empty( $min_price ) ) {
			$args        = array(
				'price_max' => $max_price,
				'price_min' => $min_price,
			);
			$current_url = add_query_arg( $args, $current_url );
		}

		if ( ! empty( $sort ) ) {
			$current_url = add_query_arg( compact( 'sort' ), $current_url );
		}

		if ( ! empty( $page_id ) && wp_doing_ajax() ) {
			$params      = $_GET;
			$current_url = home_url( $wp->request ) . '?' . http_build_query( $params );
		}

		return remove_query_arg( 'pg', $current_url );
	}


	/**
	 * @param array $options
	 *
	 * @return array
	 */
	private function prepare_elementor_options( array $options = array() ): array {
		$products_widget_id = isset( $_GET['products_widget_id'] ) ? sanitize_key( wp_unslash( $_GET['products_widget_id'] ) ) : null;
		if ( Prodigy_Elementor::is_elementor_enabled() && isset( $products_widget_id ) && wp_doing_ajax() && Prodigy_Elementor_Template_Loader::is_use_archive_template() ) {
			$options = Prodigy_Elementor::get_widget_options( ( new Prodigy_Products() )->get_name(), $products_widget_id );
		}

		return $options;
	}

	/**
	 * @param array $options
	 *
	 * @return string
	 */
	private function calculate_image_ratio( array &$options ): string {
		if (
			Prodigy_Elementor_Layouts::is_using_archive_elementor_templates() &&
			! empty( $options['style_archive_products_image_aspect_ratio']['width'] ) &&
			! empty( $options['style_archive_products_image_aspect_ratio']['height'] )
		) {
			return ( $options['style_archive_products_image_aspect_ratio']['height'] / $options['style_archive_products_image_aspect_ratio']['width'] ) * 100;
		}

		return Prodigy_Customizer::get_images_ratio();
	}

	/**
	 * @param array $options
	 *
	 * @return void
	 */
	private function set_product_classnames( array &$options ) {
		$options['product_list_classname'] = 'prodigy-product-list';
		$options['sale_classname']         = 'prodigy-product-list__item-label';

		if ( ! isset( $options['idwidget'] ) ) {
			$options['product_list_classname'] .= ' ';

			return;
		}

		if ( $options['style_archive_products_sale_position_vertical'] ?? '' === 'bottom' ) {
			$options['sale_classname'] .= ' prodigy-product-list__item-label--bottom';
		}

		if ( $options['style_archive_products_sale_position_horizontal'] ?? '' === 'right' ) {
			$options['sale_classname'] .= ' prodigy-product-list__item-label--right';
		}
	}

	/**
	 * @param array  $options
	 * @param string $customizer_key
	 * @param string $elementor_key
	 *
	 * @return bool
	 */
	private function check_setting_toggle( array $options, string $customizer_key, string $elementor_key = '' ): bool {
		if ( Prodigy_Elementor_Layouts::is_using_archive_elementor_templates() || Prodigy_Elementor_Layouts::is_elementor_live_preview() ) {
			if ( isset( $options[ $elementor_key ] ) ) {
				return ! empty( $options[ $elementor_key ] ) || Prodigy_Widget_Options::$bool_mapper[ $options[ $elementor_key ] ];
			}
		}

		return ! isset( $this->customizer_shop_options[ 'prodigy_shop_products_' . $customizer_key ] ) || $this->customizer_shop_options[ 'prodigy_shop_products_' . $customizer_key ];
	}
}
