<?php

namespace Prodigy\Includes\Frontend\Mappers;

use Prodigy\Includes\Content\Prodigy_Products_List_Parser;
use Prodigy\Includes\Content\Prodigy_Request_Maker;
use Prodigy\Includes\Frontend\Pages\Prodigy_Shop_Page;
use Prodigy\Includes\Helpers\Prodigy_Page;
use Prodigy\Includes\Models\Prodigy_Products;
use Prodigy\Includes\Models\Prodigy_Taxonomies;
use Prodigy\Includes\Prodigy;
use Prodigy\Includes\Prodigy_Pagination;
use Prodigy\Includes\Support\Customizer\Prodigy_Customizer;

defined( 'ABSPATH' ) || exit;

/**
 * Prodigy products data mapper
 *
 * @version    2.9.1
 * @package    Prodigy
 * @subpackage Prodigy/includes
 */
class Prodigy_Products_Data_Mapper extends Prodigy_Main_Data_Mapper {
	public const DESCENDING_SORT = 'DESC';
	public const SLIDER          = 'slider';

	/** @var string  */
	public string $placeholder;

	public function __construct() {
		parent::__construct();
		$this->placeholder = plugin_dir_url( PRODIGY_PLUGIN_PATH . 'web/admin/images/placeholder.png' ) . 'placeholder.png';
	}


	/**
	 * Prepare data and variables to inject in template
	 *
	 * @param array $options
	 *
	 * @return array
	 */
	public function get_default_parameters( array $options ): array {
		$query                  = $this->get_products_query_builder( $options );
		$requestMaker           = Prodigy_Request_Maker::get_instance();
		$products               = Prodigy_Page::prodigy_is_frontend()
			? $requestMaker->do_products_request( $query )
			: $requestMaker->do_admin_products_request( $query );
		$options['products']    = ( new Prodigy_Products_List_Parser( $products ) )->get_products();
		$options['image_ratio'] = Prodigy_Customizer::get_images_ratio();

		return array(
			'buy_now_nonce'   => $this->buy_now_nonce,
			'display'         => $options['display'],
			'products'        => $options['products'],
			'placeholder_url' => $this->placeholder,
			'columns'         => $options['columns'],
			'attr'            => $options,
		);
	}

	/**
	 * @param array $params
	 *
	 * @return string
	 */
	public function get_products_query_builder( array $params ): string {
		$attributes = array();

		if ( isset( $params['idWidget'] ) ) {
			$attributes['widget_id'] = $params['idWidget'];
		}

		if ( ! empty( $params['product_ids'] ) ) {
			$local_product_ids = array_filter( array_map( 'trim', explode( ',', $params['product_ids'] ) ) );
			foreach ( $local_product_ids as $key => $product_id ) {
				$attributes['product_ids'][ $key ] = $product_id;
			}
		}

		if ( ! empty( $params['category_ids'] ) ) {
			$local_category_ids = array_filter( array_map( 'trim', explode( ',', $params['category_ids'] ) ) );
			foreach ( $local_category_ids as $key => $category_name ) {
				$taxonomy = Prodigy_Taxonomies::get_taxonomy_by_different_slugs( Prodigy::get_prodigy_category_type(), $category_name );
				if ( ! empty( $taxonomy ) ) {
					$category_id                        = get_term_meta( $taxonomy->term_id, Prodigy::PRODIGY_HOSTED_CATEGORY_RELATION, true );
					$attributes['category_ids'][ $key ] = $category_id;
				}
			}
		}

		if ( ! empty( $params['product_names'] ) ) {
			$product_ids_by_names = Prodigy_Products::prodigy_get_products_id_by_name( $params['product_names'] );

			if ( ! empty( $product_ids_by_names ) ) {
				foreach ( $product_ids_by_names as $key => $product_id ) {
					$remote_id                         = get_post_meta( (int) $product_id, 'prodigy_remote_product_id', true );
					$attributes['product_ids'][ $key ] = $remote_id;
				}
			}
		}

		if ( ! empty( $params['tags'] ) ) {
			$tags = array_filter( array_map( 'trim', explode( ',', $params['tags'] ) ) );
			foreach ( $tags as $key => $tag_id ) {
				$attributes['tags'][ $key ] = $tag_id;
			}
		}

		if ( isset( $params['orderby'] ) ) {
			$sort = self::mapping_sort_params( $params['orderby'] );

			if ( isset( $params['order'] ) && strtolower( $params['order'] ) === strtolower( self::DESCENDING_SORT ) ) {
				$sort = '-' . $sort;
			}

			$attributes['sort'] = $sort;
		}

		if ( isset( $params['on_sale'] ) ) {
			$attributes['on_sale'] = $params['on_sale'];
		}

		$attributes['page']['size']   = $params['number_items_per_page'] ?? Prodigy_Shop_Page::NUMBER_ITEMS_PER_PAGE;
		$attributes['page']['number'] = $params['pg'] ?? 1;

		if ( isset( $params['limit'] ) && (int) $params['limit'] > 0 ) {
			$attributes['page']['size'] = (int) $params['limit'];
		}

		if ( isset( $params['display'] ) && $params['display'] === 'grid' ) {
			$attributes['page']['size'] = $params['number_items_per_page'] ?? $attributes['page']['size'];
		}

		$attributes['sync'] = true;

		$query_string = http_build_query( $attributes );

		return urldecode( preg_replace( '/%5B(?:[0-9]|[1-9][0-9]+)%5D/', '[]', $query_string ) );
	}

	/**
	 * @param int   $current_page
	 * @param int   $item_per_page
	 * @param array $products
	 *
	 * @return array
	 */
	public function get_pagination( int $current_page, int $item_per_page, array $products ): array {
		$total_count          = $products['data'][0]['attributes']['products-count'] ?? 0;
		$base_url             = remove_query_arg( 'pg', get_permalink() );
		$params['pagination'] = array(
			'pages'       => ! empty( $products['data'] ) ? Prodigy_Pagination::calculate_count_pages( (int) $total_count, $item_per_page ) : 1,
			'url'         => $base_url,
			'page'        => $current_page,
			'page_number' => $current_page,
		);

		return $params;
	}
}
