use List::Util qw(sum);

my @regexes = (
	qr[^https?://.*?/01/(\d{14})\b],     # GS1 Digital Link with GTIN-14
	qr[^https?://.*?/01/0(\d{13})\b],    # GS1 Digital Link with GTIN-13
	qr[^https?://.*?/01/00(\d{12})\b],   # GS1 Digital Link with GTIN-12
	qr[^https?://.*?/01/0{6}(\d{8})\b],  # GS1 Digital Link with GTIN-8

	# "Compressed" GS1 Digital Links are not supported, as the current draft
	# specification is insanely complex: it involves base64 and hexadecimal
	# strings, binary data that isn't octet-aligned, and a vast number of
	# lookup tables, all of which are needed just to extract the GTIN. One can
	# only hope that this scheme to save a few bytes will never catch on.

	qr[^\(01\)(\d{14})\b],     # GS1 Element String with GTIN-14
	qr[^\(01\)0(\d{13})\b],    # GS1 Element String with GTIN-13
	qr[^\(01\)00(\d{12})\b],   # GS1 Element String with GTIN-12
	qr[^\(01\)0{6}(\d{8})\b],  # GS1 Element String with GTIN-8

	qr[^01(\d{14})(?=\d|$)],     # GS1-128 (without FNC) with GTIN-14
	qr[^010(\d{13})(?=\d|$)],    # GS1-128 (without FNC) with GTIN-13
	qr[^0100(\d{12})(?=\d|$)],   # GS1-128 (without FNC) with GTIN-12
	qr[^010{6}(\d{8})(?=\d|$)],  # GS1-128 (without FNC) with GTIN-8

	qr[^https://\w+url\.com/(?:q/|q/srn|srn)(\d{13})]i,  # spam with GTIN-13
);

sub command ($self, $cart, $command, @) {
	$self->{orig_command} //= $command;
	$self->{regexes} //= [ @regexes ];

	while (my $regex = shift @{ $self->{regexes} }) {
		if ($self->{orig_command} =~ $regex) {
			my $gtin = $1;

			my @digits = reverse split //, $gtin;
			my $checksum = (10 - sum(map $digits[$_] * ($_ % 2 ? 3 : 1), 1..$#digits) % 10) % 10;
			$digits[0] == $checksum or next;

			return REDO, $gtin;
		}
	}

	return NEXT;
}