<?php

namespace LdapRecord\Support;

class Str
{
    /**
     * Return the remainder of a string after the last occurrence of a given value.
     *
     * @param string $subject
     * @param string $search
     *
     * @return string
     */
    public static function afterLast($subject, $search)
    {
        if ($search === '') {
            return $subject;
        }

        $position = strrpos($subject, (string) $search);

        if ($position === false) {
            return $subject;
        }

        return substr($subject, $position + strlen($search));
    }

    /**
     * Determine if a given string starts with a given substring.
     *
     * @param string          $haystack
     * @param string|string[] $needles
     *
     * @return bool
     */
    public static function startsWith($haystack, $needles)
    {
        foreach ((array) $needles as $needle) {
            if ((string) $needle !== '' && str_starts_with($haystack, $needle)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Determine if a given string ends with a given substring.
     *
     * @param string          $haystack
     * @param string|string[] $needles
     *
     * @return bool
     */
    public static function endsWith($haystack, $needles)
    {
        foreach ((array) $needles as $needle) {
            if (
                $needle !== '' && $needle !== null
                && str_ends_with($haystack, $needle)
            ) {
                return true;
            }
        }

        return false;
    }

    /**
     * Execute a callback when a needle is found in the haystack.
     *
     * @param string          $haystack
     * @param string|string[] $needles
     * @param \Closure|mixed  $callback
     * @param \Closure|mixed  $default
     *
     * @return mixed
     */
    public static function whenContains($haystack, $needles, $callback, $default = null)
    {
        foreach ((array) $needles as $needle) {
            if (static::contains($haystack, $needle)) {
                return Helpers::value($callback, $needle, $haystack);
            }
        }

        return Helpers::value($default, $haystack);
    }

    /**
     * Determine if a given string contains a given substring.
     *
     * @param string          $haystack
     * @param string|string[] $needles
     * @param bool            $ignoreCase
     *
     * @return bool
     */
    public static function contains($haystack, $needles, $ignoreCase = false)
    {
        if ($ignoreCase) {
            $haystack = mb_strtolower($haystack);
            $needles = array_map('mb_strtolower', (array) $needles);
        }

        foreach ((array) $needles as $needle) {
            if ($needle !== '' && str_contains((string) $haystack, $needle)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Returns the number of substring occurrences.
     *
     * @param string   $haystack
     * @param string   $needle
     * @param int      $offset
     * @param int|null $length
     *
     * @return int
     */
    public static function substrCount($haystack, $needle, $offset = 0, $length = null)
    {
        if (! is_null($length)) {
            return substr_count($haystack, $needle, $offset, $length);
        } else {
            return substr_count($haystack, $needle, $offset);
        }
    }
}
