<?php

namespace Illuminate\Support;

/**
 * @template TKey of array-key
 * @template TValue
 *
 * @extends \IteratorAggregate<TKey, TValue>
 * @extends \Illuminate\Contracts\Support\Arrayable<TKey, TValue>
 */
interface Enumerable extends \Countable, \IteratorAggregate, \JsonSerializable, \Illuminate\Contracts\Support\Arrayable
{
    /**
     * Search the collection for a given value and return the corresponding key if successful.
     *
     * @param  TValue|callable(TValue,TKey): bool  $value
     * @param  bool  $strict
     * @return (TKey is int ? int|false : string|false)
     */
    public function search($value, $strict = false);

    /**
    * Get one or a specified number of items randomly from the collection.
    *
    * @param  (callable(TValue): int)|int|null  $number
    * @return ($number is null ? TValue : static<int, TValue>)
    *
    * @throws \InvalidArgumentException
    */
   public function random($number = null);

   /**
    * Create a collection by using this collection for keys and another for its values.
    *
    * @template TCombineValue
    *
    * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TCombineValue>|iterable<array-key, TCombineValue>  $values
    * @return static<array-key, TCombineValue>
    */
   public function combine($values);

   /**
    * Key an associative array by a field or using a callback.
    *
    * @template TNewKey of array-key
    *
    * @param  (callable(TValue, TKey): TNewKey)|array<array-key, mixed>|string  $keyBy
    * @return static<($keyBy is string ? array-key : ($keyBy is array<int, mixed> ? array-key : TNewKey)), TValue>
    */
   public function keyBy($keyBy);

   /**
    * Group an associative array by a field or using a callback.
    *
    * @template TGroupKey of array-key
    *
    * @param  (callable(TValue, TKey): TGroupKey)|array<array-key, mixed>|string  $groupBy
    * @param  bool  $preserveKeys
    * @return static<($groupBy is string ? array-key : ($groupBy is array<int, mixed> ? array-key : TGroupKey)), static<($preserveKeys is true ? TKey : int), TValue>>
    */
   public function groupBy($groupBy, $preserveKeys = false);
}
