<?php
declare( strict_types=1 );

namespace FiboFilters\Util;

/**
 * Class ArrayUtils
 */
class ArrayUtil {
	/**
	 * Check if the variable is an array of numeric values.
	 *
	 * @param mixed $variable The variable to check.
	 */
	public static function is_array_of_numeric( $variable ): bool {
		return is_array( $variable ) && count( $variable ) > 0 && count( array_filter( $variable, 'is_numeric' ) ) === count( $variable );
	}

	/**
	 * Check if the variable is an array of scalar values.
	 *
	 * @param mixed $variable The variable to check.
	 */
	public static function is_array_of_scalars( $variable ): bool {
		return is_array( $variable ) && count( $variable ) > 0 && count( array_filter( $variable, 'is_scalar' ) ) === count( $variable );
	}

	/**
	 * Check if the variable is an array of strings.
	 *
	 * @param mixed $variable The variable to check.
	 */
	public static function is_array_of_strings( $variable ): bool {
		return is_array( $variable ) && count( $variable ) > 0 && count( array_filter( $variable, 'is_string' ) ) === count( $variable );
	}

	/**
	 * Check if the variable is an indexed array.
	 *
	 * @param mixed $variable The variable to check.
	 *
	 * @return bool True if the array is indexed, false otherwise.
	 */
	public static function is_indexed_array( $variable ): bool {
		if ( is_array( $variable ) && empty( $variable ) ) {
			return true;
		}

		return is_array( $variable ) && array_keys( $variable ) === range( 0, count( $variable ) - 1 );
	}

	/**
	 * Check if the variable is an associative array.
	 *
	 * @param mixed $variable The variable to check.
	 *
	 * @return bool True if the array is associative, false otherwise.
	 */
	public static function is_assoc_array( $variable ): bool {
		if ( is_array( $variable ) && empty( $variable ) ) {
			return true;
		}

		return ! self::is_indexed_array( $variable );
	}

	/**
	 * Check if the variable is an array of arrays.
	 *
	 * @param mixed $variable The variable to check.
	 */
	public static function is_array_of_arrays( $variable ): bool {
		return is_array( $variable ) && count( $variable ) > 0 && count( array_filter( $variable, 'is_array' ) ) === count( $variable );
	}

	/**
	 * Insert a value or key/value pair after a specific key in an array.
	 *
	 * If key doesn't exist, value is appended to the end of the array.
	 *
	 * @param array  $org_array The array to insert into.
	 * @param string $key The key to insert after.
	 * @param array  $new_item The value or key/value pair to insert.
	 */
	public static function array_insert_after( array $org_array, string $key, array $new_item ): array {
		$keys  = array_keys( $org_array );
		$index = array_search( $key, $keys, true );
		$pos   = false === $index ? count( $org_array ) : $index + 1;

		return array_merge( array_slice( $org_array, 0, $pos ), $new_item, array_slice( $org_array, $pos ) );
	}

	/**
	 * Converts a value into an indexed array.
	 *
	 * @param mixed $value The value to convert.
	 *
	 * @return array The resulting array.
	 */
	public static function to_indexed_array( $value ): array {
		return self::is_indexed_array( $value ) ? $value : [ $value ];
	}
}
