<?php
/**
 * Shared helpers for deciding when custom order may override a query.
 *
 * @package WP_PowerSuite\Ordering
 */

namespace WP_PowerSuite\Ordering;

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

/**
 * Query order guard utilities.
 */
final class QueryOrderGuard {

	/**
	 * Whether a WP_Query already defines a non-default order.
	 *
	 * @param mixed $orderby Query orderby value.
	 */
	public static function postQueryHasExplicitOrderby( $orderby, bool $respect_existing = true ): bool {
		if ( ! $respect_existing ) {
			return false;
		}

		if ( $orderby === null || $orderby === '' || $orderby === false ) {
			return false;
		}

		if ( is_string( $orderby ) ) {
			$normalized = strtolower( trim( $orderby ) );
			if ( $normalized === '' || $normalized === 'menu_order' || str_starts_with( $normalized, 'menu_order ' ) ) {
				return false;
			}

			// WordPress default blog/archive order — eligible for custom order override.
			if ( $normalized === 'date' ) {
				return false;
			}

			return true;
		}

		if ( is_array( $orderby ) ) {
			$keys = array_map( 'strtolower', array_keys( $orderby ) );
			if ( $keys === [ 'menu_order' ] || $keys === [ 'date' ] ) {
				return false;
			}

			return true;
		}

		return true;
	}

	/**
	 * Whether get_terms args already define a non-default order.
	 *
	 * @param mixed $orderby get_terms orderby value.
	 */
	public static function termQueryHasExplicitOrderby( $orderby, bool $respect_existing = true ): bool {
		if ( ! $respect_existing ) {
			return false;
		}

		if ( $orderby === null || $orderby === '' || $orderby === false ) {
			return false;
		}

		if ( ! is_string( $orderby ) ) {
			return true;
		}

		$normalized = strtolower( trim( $orderby ) );
		if ( $normalized === '' ) {
			return false;
		}

		if ( in_array( $normalized, [ 'meta_value_num', 'wpps_order', 'term_order' ], true ) ) {
			return false;
		}

		// WordPress default for get_terms.
		if ( $normalized === 'name' ) {
			return false;
		}

		return true;
	}

	/**
	 * Whether query args request filter suppression.
	 *
	 * @param array<string, mixed> $args Query arguments.
	 */
	public static function argsSuppressFilters( array $args ): bool {
		foreach ( [ 'suppress_filters', 'suppress_filter' ] as $key ) {
			if ( ! empty( $args[ $key ] ) ) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Whether a WP_Query requests filter suppression.
	 */
	public static function querySuppressesFilters( \WP_Query $query ): bool {
		return (bool) $query->get( 'suppress_filters' );
	}
}
