<?php
/**
 * Sorting helper for recommendations engine.
 *
 * @package PRECO
 */

namespace PRECO\Includes\Frontend\Engine\Sorting;

defined( 'ABSPATH' ) || exit;

/**
 * Sorting helper for recommendations engine.
 */
class SortingHelper {

	/**
	 * Get enabled sorting rules sorted by priority DESC.
	 *
	 * @param array $sorting Sorting array.
	 * @return array
	 */
	public function get_enabled_sorting_rules( $sorting ) {
		if ( ! is_array( $sorting ) || empty( $sorting ) ) {
			return array();
		}

		$items = array();
		foreach ( $sorting as $s ) {
			if ( ! is_array( $s ) ) {
				continue;
			}
			if ( isset( $s['enabled'] ) && false === $s['enabled'] ) {
				continue;
			}

			$priority = isset( $s['priority'] ) ? (int) $s['priority'] : 0;
			$items[]  = array_merge( $s, array( 'priority' => $priority ) );
		}

		usort(
			$items,
			function ( $a, $b ) {
				return (int) $b['priority'] <=> (int) $a['priority'];
			}
		);

		return $items;
	}

	/**
	 * Pick the highest-priority sorting rule.
	 *
	 * @param array $sorting Sorting array.
	 * @return array
	 */
	public function pick_sorting_rule( $sorting ) {
		$items = $this->get_enabled_sorting_rules( $sorting );
		return isset( $items[0] ) && is_array( $items[0] ) ? $items[0] : array();
	}

	/**
	 * Resolve the WP_Query orderby value for the highest-priority sorting rule.
	 *
	 * @param array $sorting Sorting array.
	 * @param array $context Context.
	 * @return string
	 */
	public function resolve_orderby( $sorting, $context = array() ) {
		if ( isset( $context['_preferred_ids'] ) && is_array( $context['_preferred_ids'] ) ) {
			return 'post__in';
		}
		$resolved = $this->pick_sorting_rule( $sorting );
		$trigger  = $resolved['triggerType'] ?? '';
		switch ( $trigger ) {
			case 'freshness':
				return 'date';
			case 'price':
				return 'meta_value_num';
			case 'rating':
				return 'meta_value_num';
			case 'popularity':
			case 'conversion':
				return 'meta_value_num';
			case 'random':
				return 'rand';
			case 'bought_together_frequency':
				return 'post__in';
			default:
				return 'date';
		}
	}

	/**
	 * Resolve meta key used for meta_value_num ordering.
	 *
	 * @param array $sorting Sorting array.
	 * @param array $context Context.
	 * @return string
	 */
	public function resolve_orderby_meta_key( $sorting, $context = array() ) {
		if ( isset( $context['_preferred_ids'] ) && is_array( $context['_preferred_ids'] ) ) {
			return '';
		}
		$resolved = $this->pick_sorting_rule( $sorting );
		$trigger  = $resolved['triggerType'] ?? '';
		switch ( $trigger ) {
			case 'price':
				return '_price';
			case 'rating':
				return '_wc_average_rating';
			case 'popularity':
			case 'conversion':
				return 'total_sales';
			default:
				return '';
		}
	}

	/**
	 * Resolve the WP_Query order (ASC/DESC) for the highest-priority sorting rule.
	 *
	 * @param array $sorting Sorting array.
	 * @param array $context Context.
	 * @return string
	 */
	public function resolve_order( $sorting, $context = array() ) {
		if ( isset( $context['_preferred_ids'] ) && is_array( $context['_preferred_ids'] ) ) {
			return 'ASC';
		}
		$resolved = $this->pick_sorting_rule( $sorting );
		$relation = isset( $resolved['relation'] ) ? (string) $resolved['relation'] : '';
		if ( in_array( $relation, array( 'low_to_high', 'old_to_new' ), true ) ) {
			return 'ASC';
		}
		return 'DESC';
	}
}
