<?php

namespace LWVendor\PhpOffice\PhpSpreadsheet\Calculation\TextData;

use LWVendor\PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
use LWVendor\PhpOffice\PhpSpreadsheet\Calculation\Functions;
use LWVendor\PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue;
use LWVendor\PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
use LWVendor\PhpOffice\PhpSpreadsheet\Cell\DataType;
use LWVendor\PhpOffice\PhpSpreadsheet\Shared\StringHelper;
class Concatenate
{
    use ArrayEnabled;
    /**
     * CONCATENATE.
     *
     * @param array $args
     */
    public static function CONCATENATE(...$args) : string
    {
        $returnValue = '';
        // Loop through arguments
        $aArgs = Functions::flattenArray($args);
        foreach ($aArgs as $arg) {
            $value = Helpers::extractString($arg);
            if (ErrorValue::isError($value)) {
                $returnValue = $value;
                break;
            }
            $returnValue .= Helpers::extractString($arg);
            if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) {
                $returnValue = ExcelError::CALC();
                break;
            }
        }
        return $returnValue;
    }
    /**
     * TEXTJOIN.
     *
     * @param mixed $delimiter The delimter to use between the joined arguments
     *                         Or can be an array of values
     * @param mixed $ignoreEmpty true/false Flag indicating whether empty arguments should be skipped
     *                         Or can be an array of values
     * @param mixed $args The values to join
     *
     * @return array|string The joined string
     *         If an array of values is passed for the $delimiter or $ignoreEmpty arguments, then the returned result
     *            will also be an array with matching dimensions
     */
    public static function TEXTJOIN($delimiter = '', $ignoreEmpty = \true, ...$args)
    {
        if (\is_array($delimiter) || \is_array($ignoreEmpty)) {
            return self::evaluateArrayArgumentsSubset([self::class, __FUNCTION__], 2, $delimiter, $ignoreEmpty, ...$args);
        }
        $delimiter ??= '';
        $ignoreEmpty ??= \true;
        $aArgs = Functions::flattenArray($args);
        $returnValue = self::evaluateTextJoinArray($ignoreEmpty, $aArgs);
        $returnValue ??= \implode($delimiter, $aArgs);
        if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) {
            $returnValue = ExcelError::CALC();
        }
        return $returnValue;
    }
    private static function evaluateTextJoinArray(bool $ignoreEmpty, array &$aArgs) : ?string
    {
        foreach ($aArgs as $key => &$arg) {
            $value = Helpers::extractString($arg);
            if (ErrorValue::isError($value)) {
                return $value;
            }
            if ($ignoreEmpty === \true && (\is_string($arg) && \trim($arg) === '' || $arg === null)) {
                unset($aArgs[$key]);
            } elseif (\is_bool($arg)) {
                $arg = Helpers::convertBooleanValue($arg);
            }
        }
        return null;
    }
    /**
     * REPT.
     *
     * Returns the result of builtin function round after validating args.
     *
     * @param mixed $stringValue The value to repeat
     *                         Or can be an array of values
     * @param mixed $repeatCount The number of times the string value should be repeated
     *                         Or can be an array of values
     *
     * @return array|string The repeated string
     *         If an array of values is passed for the $stringValue or $repeatCount arguments, then the returned result
     *            will also be an array with matching dimensions
     */
    public static function builtinREPT($stringValue, $repeatCount)
    {
        if (\is_array($stringValue) || \is_array($repeatCount)) {
            return self::evaluateArrayArguments([self::class, __FUNCTION__], $stringValue, $repeatCount);
        }
        $stringValue = Helpers::extractString($stringValue);
        if (!\is_numeric($repeatCount) || $repeatCount < 0) {
            $returnValue = ExcelError::VALUE();
        } elseif (ErrorValue::isError($stringValue)) {
            $returnValue = $stringValue;
        } else {
            $returnValue = \str_repeat($stringValue, (int) $repeatCount);
            if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) {
                $returnValue = ExcelError::VALUE();
                // note VALUE not CALC
            }
        }
        return $returnValue;
    }
}
