<?php

namespace App\Support;

use Illuminate\Support\Str;

/**
 * Códigos LMS/LMSB para escaneo: solo letras y números (sin guiones) en Code128.
 * Mantiene compatibilidad con folios legacy que usaban guiones en BD.
 */
final class LaundryScanCode
{
    /** Solo A-Z y 0-9 (sin guiones ni otros símbolos). */
    public static function compact(string $code): string
    {
        return strtoupper((string) preg_replace('/[^A-Z0-9]/', '', strtoupper(trim($code))));
    }

    /** Folio de venta: LMS + Ymd + 6 alfanuméricos. */
    public static function generateFolio(): string
    {
        return 'LMS'.date('Ymd').strtoupper(Str::random(6));
    }

    /** Código de etiqueta de bolsa: LMSB + Ymd + 8 alfanuméricos. */
    public static function generateBagCode(): string
    {
        return 'LMSB'.date('Ymd').strtoupper(Str::random(8));
    }

    /** Payload Code128 / QR de operación (compacto si es LMS/LMSB). */
    public static function barcodePayload(string $code): string
    {
        $code = trim($code);
        if ($code === '') {
            return '';
        }

        if (preg_match('/^LMS/i', $code)) {
            return self::compact($code);
        }

        return $code;
    }

    /**
     * Reconstruye formato legacy con guiones (LMS-YYYYMMDD-SUFFIX).
     */
    public static function legacyHyphenated(string $code): ?string
    {
        $compact = self::compact($code);
        if (preg_match('/^LMSB(\d{8})([A-Z0-9]+)$/', $compact, $m)) {
            return 'LMSB-'.$m[1].'-'.$m[2];
        }
        if (preg_match('/^LMS(\d{8})([A-Z0-9]+)$/', $compact, $m)) {
            return 'LMS-'.$m[1].'-'.$m[2];
        }

        return null;
    }

    /**
     * @return list<string>
     */
    public static function lookupCandidates(string $input): array
    {
        $input = trim($input);
        if ($input === '') {
            return [];
        }

        $candidates = [$input];
        $compact = self::compact($input);
        if ($compact !== '' && ! in_array($compact, $candidates, true)) {
            $candidates[] = $compact;
        }

        $legacy = self::legacyHyphenated($input);
        if ($legacy !== null && ! in_array($legacy, $candidates, true)) {
            $candidates[] = $legacy;
        }

        return array_values(array_unique(array_filter($candidates, static fn (string $v): bool => $v !== '')));
    }
}
