/home/kueuepay/www/vendor/nunomaduro/termwind/src/ValueObjects/Styles.php
<?php

declare(strict_types=1);

namespace Termwind\ValueObjects;

use Closure;
use Termwind\Actions\StyleToMethod;
use Termwind\Components\Element;
use Termwind\Components\Hr;
use Termwind\Components\Li;
use Termwind\Components\Ol;
use Termwind\Components\Ul;
use Termwind\Enums\Color;
use Termwind\Exceptions\ColorNotFound;
use Termwind\Exceptions\InvalidStyle;
use Termwind\Repositories\Styles as StyleRepository;
use function Termwind\terminal;

/**
 * @internal
 */
final class Styles
{
    /**
     * Finds all the styling on a string.
     */
    public const STYLING_REGEX = "/\<[\w=#\/\;,:.&,%?-]+\>|\\e\[\d+m/";

    /** @var array<int, string> */
    private array $styles = [];

    private ?Element $element = null;

    /**
     * Creates a Style formatter instance.
     *
     * @param  array<string, mixed>  $properties
     * @param  array<string, Closure(string, array<string, string|int>, array<string, int[]>): string>  $textModifiers
     * @param  array<string, Closure(string, array<string, string|int>): string>  $styleModifiers
     * @param  string[]  $defaultStyles
     */
    final public function __construct(
        private array $properties = [
            'colors' => [],
            'options' => [],
            'isFirstChild' => false,
        ],
        private array $textModifiers = [],
        private array $styleModifiers = [],
        private array $defaultStyles = []
    ) {
    }

    /**
     * @param  Element  $element
     * @return $this
     */
    public function setElement(Element $element): self
    {
        $this->element = $element;

        return $this;
    }

    /**
     * Gets default styles.
     *
     * @return string[]
     */
    public function defaultStyles(): array
    {
        return $this->defaultStyles;
    }

    /**
     * Gets the element's style properties.
     *
     * @return array<string, mixed>
     */
    final public function getProperties(): array
    {
        return $this->properties;
    }

    /**
     * Sets the element's style properties.
     *
     * @param  array<string, mixed>  $properties
     */
    public function setProperties(array $properties): self
    {
        $this->properties = $properties;

        return $this;
    }

    /**
     * Sets the styles to the element.
     */
    final public function setStyle(string $style): self
    {
        $this->styles = array_unique(array_merge($this->styles, [$style]));

        return $this;
    }

    /**
     * Checks if the element has the style.
     */
    final public function hasStyle(string $style): bool
    {
        return in_array($style, $this->styles, true);
    }

    /**
     * Adds a style to the element.
     */
    final public function addStyle(string $style): self
    {
        return StyleToMethod::multiple($this, $style);
    }

    /**
     * Inherit styles from given Styles object.
     */
    final public function inheritFromStyles(self $styles): self
    {
        foreach (['ml', 'mr', 'pl', 'pr', 'width', 'minWidth', 'maxWidth', 'spaceY', 'spaceX'] as $style) {
            $this->properties['parentStyles'][$style] = array_merge(
                $this->properties['parentStyles'][$style] ?? [],
                $styles->properties['parentStyles'][$style] ?? []
            );

            $this->properties['parentStyles'][$style][] = $styles->properties['styles'][$style] ?? 0;
        }

        $this->properties['parentStyles']['justifyContent'] = $styles->properties['styles']['justifyContent'] ?? false;

        foreach (['bg', 'fg'] as $colorType) {
            $value = (array) ($this->properties['colors'][$colorType] ?? []);
            $parentValue = (array) ($styles->properties['colors'][$colorType] ?? []);

            if ($value === [] && $parentValue !== []) {
                $this->properties['colors'][$colorType] = $styles->properties['colors'][$colorType];
            }
        }

        if (! is_null($this->properties['options']['bold'] ?? null) ||
            ! is_null($styles->properties['options']['bold'] ?? null)) {
            $this->properties['options']['bold'] = $this->properties['options']['bold']
                ?? $styles->properties['options']['bold']
                ?? false;
        }

        return $this;
    }

    /**
     * Adds a background color to the element.
     */
    final public function bg(string $color, int $variant = 0): self
    {
        return $this->with(['colors' => [
            'bg' => $this->getColorVariant($color, $variant),
        ]]);
    }

    /**
     * Adds a bold style to the element.
     */
    final public function fontBold(): self
    {
        return $this->with(['options' => [
            'bold' => true,
        ]]);
    }

    /**
     * Removes the bold style on the element.
     */
    final public function fontNormal(): self
    {
        return $this->with(['options' => [
            'bold' => false,
        ]]);
    }

    /**
     * Adds a bold style to the element.
     */
    final public function strong(): self
    {
        $this->styleModifiers[__METHOD__] = static fn ($text): string => sprintf("\e[1m%s\e[0m", $text);

        return $this;
    }

    /**
     * Adds an italic style to the element.
     */
    final public function italic(): self
    {
        $this->styleModifiers[__METHOD__] = static fn ($text): string => sprintf("\e[3m%s\e[0m", $text);

        return $this;
    }

    /**
     * Adds an underline style.
     */
    final public function underline(): self
    {
        $this->styleModifiers[__METHOD__] = static fn ($text): string => sprintf("\e[4m%s\e[0m", $text);

        return $this;
    }

    /**
     * Adds the given margin left to the element.
     */
    final public function ml(int $margin): self
    {
        return $this->with(['styles' => [
            'ml' => $margin,
        ]]);
    }

    /**
     * Adds the given margin right to the element.
     */
    final public function mr(int $margin): self
    {
        return $this->with(['styles' => [
            'mr' => $margin,
        ]]);
    }

    /**
     * Adds the given margin bottom to the element.
     */
    final public function mb(int $margin): self
    {
        return $this->with(['styles' => [
            'mb' => $margin,
        ]]);
    }

    /**
     * Adds the given margin top to the element.
     */
    final public function mt(int $margin): self
    {
        return $this->with(['styles' => [
            'mt' => $margin,
        ]]);
    }

    /**
     * Adds the given horizontal margin to the element.
     */
    final public function mx(int $margin): self
    {
        return $this->with(['styles' => [
            'ml' => $margin,
            'mr' => $margin,
        ]]);
    }

    /**
     * Adds the given vertical margin to the element.
     */
    final public function my(int $margin): self
    {
        return $this->with(['styles' => [
            'mt' => $margin,
            'mb' => $margin,
        ]]);
    }

    /**
     * Adds the given margin to the element.
     */
    final public function m(int $margin): self
    {
        return $this->my($margin)->mx($margin);
    }

    /**
     * Adds the given padding left to the element.
     */
    final public function pl(int $padding): static
    {
        return $this->with(['styles' => [
            'pl' => $padding,
        ]]);
    }

    /**
     * Adds the given padding right.
     */
    final public function pr(int $padding): static
    {
        return $this->with(['styles' => [
            'pr' => $padding,
        ]]);
    }

    /**
     * Adds the given horizontal padding.
     */
    final public function px(int $padding): self
    {
        return $this->pl($padding)->pr($padding);
    }

    /**
     * Adds the given padding top.
     */
    final public function pt(int $padding): static
    {
        return $this->with(['styles' => [
            'pt' => $padding,
        ]]);
    }

    /**
     * Adds the given padding bottom.
     */
    final public function pb(int $padding): static
    {
        return $this->with(['styles' => [
            'pb' => $padding,
        ]]);
    }

    /**
     * Adds the given vertical padding.
     */
    final public function py(int $padding): self
    {
        return $this->pt($padding)->pb($padding);
    }

    /**
     * Adds the given padding.
     */
    final public function p(int $padding): self
    {
        return $this->pt($padding)->pr($padding)->pb($padding)->pl($padding);
    }

    /**
     * Adds the given vertical margin to the childs, ignoring the first child.
     */
    final public function spaceY(int $space): self
    {
        return $this->with(['styles' => [
            'spaceY' => $space,
        ]]);
    }

    /**
     * Adds the given horizontal margin to the childs, ignoring the first child.
     */
    final public function spaceX(int $space): self
    {
        return $this->with(['styles' => [
            'spaceX' => $space,
        ]]);
    }

    /**
     * Adds a border on top of each element.
     */
    final public function borderT(int $width = 1): self
    {
        if (! $this->element instanceof Hr) {
            throw new InvalidStyle('`border-t` can only be used on an "hr" element.');
        }

        $this->styleModifiers[__METHOD__] = function ($text, $styles): string {
            $length = $this->getLength($text);
            if ($length < 1) {
                $margins = (int) ($styles['ml'] ?? 0) + ($styles['mr'] ?? 0);

                return str_repeat('─', self::getParentWidth($this->properties['parentStyles'] ?? []) - $margins);
            }

            return str_repeat('─', $length);
        };

        return $this;
    }

    /**
     * Adds a text alignment or color to the element.
     */
    final public function text(string $value, int $variant = 0): self
    {
        if (in_array($value, ['left', 'right', 'center'], true)) {
            return $this->with(['styles' => [
                'text-align' => $value,
            ]]);
        }

        return $this->with(['colors' => [
            'fg' => $this->getColorVariant($value, $variant),
        ]]);
    }

    /**
     * Truncates the text of the element.
     */
    final public function truncate(int $limit = 0, string $end = '…'): self
    {
        $this->textModifiers[__METHOD__] = function ($text, $styles) use ($limit, $end): string {
            $width = $styles['width'] ?? 0;

            if (is_string($width)) {
                $width = self::calcWidthFromFraction(
                    $width,
                    $styles,
                    $this->properties['parentStyles'] ?? []
                );
            }

            [, $paddingRight, , $paddingLeft] = $this->getPaddings();
            $width -= $paddingRight + $paddingLeft;

            $limit = $limit > 0 ? $limit : $width;
            if ($limit === 0) {
                return $text;
            }

            $limit -= mb_strwidth($end, 'UTF-8');

            if ($this->getLength($text) <= $limit) {
                return $text;
            }

            return rtrim(self::trimText($text, $limit).$end);
        };

        return $this;
    }

    /**
     * Forces the width of the element.
     */
    final public function w(int|string $width): static
    {
        return $this->with(['styles' => [
            'width' => $width,
        ]]);
    }

    /**
     * Forces the element width to the full width of the terminal.
     */
    final public function wFull(): static
    {
        return $this->w('1/1');
    }

    /**
     * Removes the width set on the element.
     */
    final public function wAuto(): static
    {
        return $this->with(['styles' => [
            'width' => null,
        ]]);
    }

    /**
     * Defines a minimum width of an element.
     */
    final public function minW(int|string $width): static
    {
        return $this->with(['styles' => [
            'minWidth' => $width,
        ]]);
    }

    /**
     * Defines a maximum width of an element.
     */
    final public function maxW(int|string $width): static
    {
        return $this->with(['styles' => [
            'maxWidth' => $width,
        ]]);
    }

    /**
     * Makes the element's content uppercase.
     */
    final public function uppercase(): self
    {
        $this->textModifiers[__METHOD__] = static fn ($text): string => mb_strtoupper($text, 'UTF-8');

        return $this;
    }

    /**
     * Makes the element's content lowercase.
     */
    final public function lowercase(): self
    {
        $this->textModifiers[__METHOD__] = static fn ($text): string => mb_strtolower($text, 'UTF-8');

        return $this;
    }

    /**
     * Makes the element's content capitalize.
     */
    final public function capitalize(): self
    {
        $this->textModifiers[__METHOD__] = static fn ($text): string => mb_convert_case($text, MB_CASE_TITLE, 'UTF-8');

        return $this;
    }

    /**
     * Makes the element's content in snakecase.
     */
    final public function snakecase(): self
    {
        $this->textModifiers[__METHOD__] = static fn ($text): string => mb_strtolower(
            (string) preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2', $text),
            'UTF-8'
        );

        return $this;
    }

    /**
     * Makes the element's content with a line through.
     */
    final public function lineThrough(): self
    {
        $this->styleModifiers[__METHOD__] = static fn ($text): string => sprintf("\e[9m%s\e[0m", $text);

        return $this;
    }

    /**
     * Makes the element's content invisible.
     */
    final public function invisible(): self
    {
        $this->styleModifiers[__METHOD__] = static fn ($text): string => sprintf("\e[8m%s\e[0m", $text);

        return $this;
    }

    /**
     * Do not display element's content.
     */
    final public function hidden(): self
    {
        return $this->with(['styles' => [
            'display' => 'hidden',
        ]]);
    }

    /**
     * Makes a line break before the element's content.
     */
    final public function block(): self
    {
        return $this->with(['styles' => [
            'display' => 'block',
        ]]);
    }

    /**
     * Makes an element eligible to work with flex-1 element's style.
     */
    final public function flex(): self
    {
        return $this->with(['styles' => [
            'display' => 'flex',
        ]]);
    }

    /**
     * Makes an element grow and shrink as needed, ignoring the initial size.
     */
    final public function flex1(): self
    {
        return $this->with(['styles' => [
            'flex-1' => true,
        ]]);
    }

    /**
     * Justifies childs along the element with an equal amount of space between.
     */
    final public function justifyBetween(): self
    {
        return $this->with(['styles' => [
            'justifyContent' => 'between',
        ]]);
    }

    /**
     * Justifies childs along the element with an equal amount of space between
     * each item and half around.
     */
    final public function justifyAround(): self
    {
        return $this->with(['styles' => [
            'justifyContent' => 'around',
        ]]);
    }

    /**
     * Justifies childs along the element with an equal amount of space around each item.
     */
    final public function justifyEvenly(): self
    {
        return $this->with(['styles' => [
            'justifyContent' => 'evenly',
        ]]);
    }

    /**
     * Justifies childs along the center of the container’s main axis.
     */
    final public function justifyCenter(): self
    {
        return $this->with(['styles' => [
            'justifyContent' => 'center',
        ]]);
    }

    /**
     * Repeats the string given until it fills all the content.
     */
    final public function contentRepeat(string $string): self
    {
        $string = preg_replace("/\[?'?([^'|\]]+)'?\]?/", '$1', $string) ?? '';

        $this->textModifiers[__METHOD__] = static fn (): string => str_repeat($string, (int) floor(terminal()->width() / mb_strlen($string, 'UTF-8')));

        return $this->with(['styles' => [
            'contentRepeat' => true,
        ]]);
    }

    /**
     * Prepends text to the content.
     */
    final public function prepend(string $string): self
    {
        $this->textModifiers[__METHOD__] = static fn ($text): string => $string.$text;

        return $this;
    }

    /**
     * Appends text to the content.
     */
    final public function append(string $string): self
    {
        $this->textModifiers[__METHOD__] = static fn ($text): string => $text.$string;

        return $this;
    }

    /**
     * Prepends the list style type to the content.
     */
    final public function list(string $type, int $index = 0): self
    {
        if (! $this->element instanceof Ul && ! $this->element instanceof Ol && ! $this->element instanceof Li) {
            throw new InvalidStyle(sprintf(
                'Style list-none cannot be used with %s',
                $this->element !== null ? $this->element::class : 'unknown element'
            ));
        }

        if (! $this->element instanceof Li) {
            return $this;
        }

        return match ($type) {
            'square' => $this->prepend('▪ '),
            'disc' => $this->prepend('• '),
            'decimal' => $this->prepend(sprintf('%d. ', $index)),
            default => $this,
        };
    }

    /**
     * Adds the given properties to the element.
     *
     * @param  array<string, mixed>  $properties
     */
    public function with(array $properties): self
    {
        $this->properties = array_replace_recursive($this->properties, $properties);

        return $this;
    }

    /**
     * Sets the href property to the element.
     */
    final public function href(string $href): self
    {
        $href = str_replace('%', '%%', $href);

        return $this->with(['href' => array_filter([$href])]);
    }

    /**
     * Formats a given string.
     */
    final public function format(string $content): string
    {
        foreach ($this->textModifiers as $modifier) {
            $content = $modifier(
                $content,
                $this->properties['styles'] ?? [],
                $this->properties['parentStyles'] ?? []
            );
        }

        $content = $this->applyWidth($content);

        foreach ($this->styleModifiers as $modifier) {
            $content = $modifier($content, $this->properties['styles'] ?? []);
        }

        return $this->applyStyling($content);
    }

    /**
     * Get the format string including required styles.
     */
    private function getFormatString(): string
    {
        $styles = [];

        /** @var array<int, string> $href */
        $href = $this->properties['href'] ?? [];
        if ($href !== []) {
            $styles[] = sprintf('href=%s', array_pop($href));
        }

        $colors = $this->properties['colors'] ?? [];

        foreach ($colors as $option => $content) {
            if (in_array($option, ['fg', 'bg'], true)) {
                $content = is_array($content) ? array_pop($content) : $content;

                $styles[] = "$option=$content";
            }
        }

        $options = $this->properties['options'] ?? [];

        if ($options !== []) {
            $options = array_keys(array_filter(
                $options, fn ($option) => $option === true
            ));
            $styles[] = count($options) > 0
                ? 'options='.implode(',', $options)
                : 'options=,';
        }

        // If there are no styles we don't need extra tags
        if ($styles === []) {
            return '%s%s%s%s%s';
        }

        return '%s<'.implode(';', $styles).'>%s%s%s</>%s';
    }

    /**
     * Get the margins applied to the element.
     *
     * @return array{0: int, 1: int, 2: int, 3: int}
     */
    private function getMargins(): array
    {
        $isFirstChild = (bool) $this->properties['isFirstChild'];

        $spaceY = $this->properties['parentStyles']['spaceY'] ?? [];
        $spaceY = ! $isFirstChild ? end($spaceY) : 0;

        $spaceX = $this->properties['parentStyles']['spaceX'] ?? [];
        $spaceX = ! $isFirstChild ? end($spaceX) : 0;

        return [
            $spaceY > 0 ? $spaceY : $this->properties['styles']['mt'] ?? 0,
            $this->properties['styles']['mr'] ?? 0,
            $this->properties['styles']['mb'] ?? 0,
            $spaceX > 0 ? $spaceX : $this->properties['styles']['ml'] ?? 0,
        ];
    }

    /**
     * Get the paddings applied to the element.
     *
     * @return array{0: int, 1: int, 2: int, 3: int}
     */
    private function getPaddings(): array
    {
        return [
            $this->properties['styles']['pt'] ?? 0,
            $this->properties['styles']['pr'] ?? 0,
            $this->properties['styles']['pb'] ?? 0,
            $this->properties['styles']['pl'] ?? 0,
        ];
    }

    /**
     * It applies the correct width for the content.
     */
    private function applyWidth(string $content): string
    {
        $styles = $this->properties['styles'] ?? [];
        $minWidth = $styles['minWidth'] ?? -1;
        $width = max($styles['width'] ?? -1, $minWidth);
        $maxWidth = $styles['maxWidth'] ?? 0;

        if ($width < 0) {
            return $content;
        }

        if ($width === 0) {
            return '';
        }

        if (is_string($width)) {
            $width = self::calcWidthFromFraction(
                $width,
                $styles,
                $this->properties['parentStyles'] ?? []
            );
        }

        if ($maxWidth > 0) {
            $width = min($styles['maxWidth'], $width);
        }

        $width -= ($styles['pl'] ?? 0) + ($styles['pr'] ?? 0);
        $length = $this->getLength($content);

        preg_match_all("/\n+/", $content, $matches);

        $width *= count($matches[0] ?? []) + 1;
        $width += mb_strlen($matches[0][0] ?? '', 'UTF-8');

        if ($length <= $width) {
            $space = $width - $length;

            return match ($styles['text-align'] ?? '') {
                'right' => str_repeat(' ', $space).$content,
                'center' => str_repeat(' ', (int) floor($space / 2)).$content.str_repeat(' ', (int) ceil($space / 2)),
                default => $content.str_repeat(' ', $space),
            };
        }

        return self::trimText($content, $width);
    }

    /**
     * It applies the styling for the content.
     */
    private function applyStyling(string $content): string
    {
        $display = $this->properties['styles']['display'] ?? 'inline';

        if ($display === 'hidden') {
            return '';
        }

        $isFirstChild = (bool) $this->properties['isFirstChild'];

        [$marginTop, $marginRight, $marginBottom, $marginLeft] = $this->getMargins();
        [$paddingTop, $paddingRight, $paddingBottom, $paddingLeft] = $this->getPaddings();

        $content = (string) preg_replace('/\r[ \t]?/', "\n",
            (string) preg_replace(
                '/\n/',
                str_repeat(' ', $marginRight + $paddingRight)
                ."\n".
                str_repeat(' ', $marginLeft + $paddingLeft),
                $content)
        );

        $formatted = sprintf(
            $this->getFormatString(),
            str_repeat(' ', $marginLeft),
            str_repeat(' ', $paddingLeft),
            $content,
            str_repeat(' ', $paddingRight),
            str_repeat(' ', $marginRight),
        );

        $empty = str_replace(
            $content,
            str_repeat(' ', $this->getLength($content)),
            $formatted
        );

        $items = [];

        if (in_array($display, ['block', 'flex'], true) && ! $isFirstChild) {
            $items[] = "\n";
        }

        if ($marginTop > 0) {
            $items[] = str_repeat("\n", $marginTop);
        }

        if ($paddingTop > 0) {
            $items[] = $empty."\n";
        }

        $items[] = $formatted;

        if ($paddingBottom > 0) {
            $items[] = "\n".$empty;
        }

        if ($marginBottom > 0) {
            $items[] = str_repeat("\n", $marginBottom);
        }

        return implode('', $items);
    }

    /**
     * Get the length of the text provided without the styling tags.
     */
    public function getLength(string $text = null): int
    {
        return mb_strlen(preg_replace(
            self::STYLING_REGEX,
            '',
            $text ?? $this->element?->toString() ?? ''
        ) ?? '', 'UTF-8');
    }

    /**
     * Get the length of the element without margins.
     */
    public function getInnerWidth(): int
    {
        $innerLength = $this->getLength();
        [, $marginRight, , $marginLeft] = $this->getMargins();

        return $innerLength - $marginLeft - $marginRight;
    }

    /**
     * Get the constant variant color from Color class.
     */
    private function getColorVariant(string $color, int $variant): string
    {
        if ($variant > 0) {
            $color .= '-'.$variant;
        }

        if (StyleRepository::has($color)) {
            return StyleRepository::get($color)->getColor();
        }

        $colorConstant = mb_strtoupper(str_replace('-', '_', $color), 'UTF-8');

        if (! defined(Color::class."::$colorConstant")) {
            throw new ColorNotFound($colorConstant);
        }

        return constant(Color::class."::$colorConstant");
    }

    /**
     * Calculates the width based on the fraction provided.
     *
     * @param  array<string, int>  $styles
     * @param  array<string, array<int, int|string>>  $parentStyles
     */
    private static function calcWidthFromFraction(string $fraction, array $styles, array $parentStyles): int
    {
        $width = self::getParentWidth($parentStyles);

        preg_match('/(\d+)\/(\d+)/', $fraction, $matches);

        if (count($matches) !== 3 || $matches[2] === '0') {
            throw new InvalidStyle(sprintf('Style [%s] is invalid.', "w-$fraction"));
        }

        /** @@phpstan-ignore-next-line  */
        $width = (int) floor($width * $matches[1] / $matches[2]);
        $width -= ($styles['ml'] ?? 0) + ($styles['mr'] ?? 0);

        return $width;
    }

    /**
     * Gets the width of the parent element.
     *
     * @param  array<string, array<int|string>>  $styles
     */
    public static function getParentWidth(array $styles): int
    {
        $width = terminal()->width();
        foreach ($styles['width'] ?? [] as $index => $parentWidth) {
            $minWidth = (int) $styles['minWidth'][$index];
            $maxWidth = (int) $styles['maxWidth'][$index];
            $margins = (int) $styles['ml'][$index] + (int) $styles['mr'][$index];

            $parentWidth = max($parentWidth, $minWidth);

            if ($parentWidth < 1) {
                $parentWidth = $width;
            } elseif (is_int($parentWidth)) {
                $parentWidth += $margins;
            }

            preg_match('/(\d+)\/(\d+)/', (string) $parentWidth, $matches);

            $width = count($matches) !== 3
                ? (int) $parentWidth
                : (int) floor($width * $matches[1] / $matches[2]); //@phpstan-ignore-line

            if ($maxWidth > 0) {
                $width = min($maxWidth, $width);
            }

            $width -= $margins;
            $width -= (int) $styles['pl'][$index] + (int) $styles['pr'][$index];
        }

        return $width;
    }

    /**
     * It trims the text properly ignoring all escape codes and
     * `<bg;fg;options>` tags.
     */
    private static function trimText(string $text, int $width): string
    {
        preg_match_all(self::STYLING_REGEX, $text, $matches, PREG_OFFSET_CAPTURE);
        $text = rtrim(mb_strimwidth(preg_replace(self::STYLING_REGEX, '', $text) ?? '', 0, $width, '', 'UTF-8'));

        foreach ($matches[0] ?? [] as [$part, $index]) {
            $text = substr($text, 0, $index).$part.substr($text, $index, null);
        }

        return $text;
    }
}
FAQ

FAQ

1. What is the Kueue Pay Payment Gateway?

The Kueue Pay Payment Gateway is an innovative technology that facilitates seamless and secure transactions between merchants and their customers. It enables businesses to accept debit and credit card payments both online and in physical stores.

2. How does the Kueue Pay Payment Gateway work?

The Kueue Pay Payment Gateway acts as a bridge between a merchant’s website or point-of-sale system and the payment processing network. It securely transmits payment information, authorizes transactions, and provides real-time status updates.

3. What is the advantage of using Kueue Pay’s Developer API?

The Kueue Pay Developer API empowers developers and entrepreneurs to integrate the Kueue Pay Payment Gateway directly into their websites or applications. This streamlines the payment process for customers and provides businesses with a customizable and efficient payment solution.

4. How can I access the Kueue Pay Developer API?

To access the Kueue Pay Developer API, you need to sign up for a developer account on our platform. Once registered, you’ll receive an API key that you can use to authenticate your API requests.

5. What types of transactions can I handle with the Kueue Pay Developer API?

The Kueue Pay Developer API allows you to initiate payments, check the status of payments, and process refunds. You can create a seamless payment experience for your customers while maintaining control over transaction management.

6. Is the Kueue Pay Developer API suitable for my business size and industry?

Yes, the Kueue Pay Developer API is designed to accommodate businesses of varying sizes and industries. Whether you’re a small online store or a large enterprise, our API can be tailored to fit your specific payment needs.

7. How user-friendly is the Kueue Pay Developer API integration process?

The Kueue Pay Developer API is designed with simplicity and ease of use in mind. Our comprehensive documentation, code samples, and developer support resources ensure a smooth integration process for any web platform.

8. Are there any fees associated with using the Kueue Pay Payment Gateway and API?

We offer competitive pricing plans for using the Kueue Pay Payment Gateway and Developer API. Details about fees and pricing tiers can be found on our developer portal.

9. Can I customize the payment experience for my customers using the Kueue Pay API?

Absolutely, the Kueue Pay Developer API offers customization options that allow you to tailor the payment experience to match your brand and user interface. You can create a seamless and cohesive payment journey for your customers.

10. What kind of support is available if I encounter issues during API integration?

We provide dedicated developer support to assist you with any issues or questions you may have during the API integration process. Reach out to our support team at developersupport@NFCPay.com for prompt assistance.

Remember, our goal is to empower your business with a robust and efficient payment solution. If you have any additional questions or concerns, feel free to explore our developer portal or contact our support team.