<?php

declare(strict_types=1);

/**
 * @return array{prefix: string, digits: string, suffix: string}
 */
function qdb_parse_client_code_pattern(string $code): array
{
    if (!preg_match('/\d/u', $code)) {
        throw new InvalidArgumentException(
            'Code must contain a numeric segment (e.g. C001 or A01Demo)',
        );
    }

    $suffix = '';
    if (preg_match('/[^0-9]+$/u', $code, $suffixMatch)) {
        $suffix = $suffixMatch[0];
        $core = substr($code, 0, -strlen($suffix));
    } else {
        $core = $code;
    }

    if (!preg_match('/^(.*?)(\d+)$/u', $core, $match) || $match[2] === '') {
        throw new InvalidArgumentException(
            'Code must contain a numeric segment (e.g. C001 or A01Demo)',
        );
    }

    return [
        'prefix' => $match[1],
        'digits' => $match[2],
        'suffix' => $suffix,
    ];
}

/**
 * Expand a client-code range such as C001…C050 or A01Demo…A10Demo.
 *
 * @return list<string>
 */
function qdb_expand_client_code_range(string $from, string $to, int $maxCount = 500): array
{
    $fromParts = qdb_parse_client_code_pattern($from);
    $toParts   = qdb_parse_client_code_pattern($to);

    if ($fromParts['prefix'] !== $toParts['prefix'] || $fromParts['suffix'] !== $toParts['suffix']) {
        throw new InvalidArgumentException(
            'Prefix and suffix must match between from and to (e.g. C001…C050 or A01Demo…A10Demo)',
        );
    }

    $prefix   = $fromParts['prefix'];
    $suffix   = $fromParts['suffix'];
    $padWidth = strlen($fromParts['digits']);
    $start    = (int) $fromParts['digits'];
    $end      = (int) $toParts['digits'];

    if ($start > $end) {
        throw new InvalidArgumentException('From number must be less than or equal to to');
    }

    $count = $end - $start + 1;
    if ($count > $maxCount) {
        throw new InvalidArgumentException("Range exceeds maximum of $maxCount clients");
    }

    $codes = [];
    for ($n = $start; $n <= $end; $n++) {
        $codes[] = $prefix . str_pad((string) $n, $padWidth, '0', STR_PAD_LEFT) . $suffix;
    }

    return $codes;
}
