<?php

namespace App\Helper;

class TransactionCodeHelper
{
    private const VALID_CHARS = [
        '2',
        '3',
        '4',
        '5',
        '6',
        '7',
        '8',
        '9',
        'A',
        'B',
        'C',
        'D',
        'E',
        'F',
        'G',
        'H',
        'J',
        'K',
        'L',
        'M',
        'N',
        'P',
        'Q',
        'R',
        'S',
        'T',
        'U',
        'V',
        'W',
        'X',
        'Y',
        'Z', 
    ];

    private const FACTOR = 2;

    /**
     * Validate the transaction code
     * 
     * @param $key string
     * @return bool
     */
    public static function verifyKey(string $key): bool
    {
        if (strlen($key) !== 10) {
            return false;
        }

        $checkDigit = self::generateCheckCharacter(strtoupper(substr($key, 0, 9)));

        return $key[9] === $checkDigit;
    }

    /**
     * generate the check character that should correspond to the last letter of the string 
     * 
     * @param $input
     * @return string
     */
    public static function generateCheckCharacter(string $input): string
    {
        $factor = self::FACTOR;

        $sum = 0;
        $n = count(self::VALID_CHARS);

        for ($i = strlen($input) - 1; $i >= 0; $i--) {
            $code_point = array_search($input[$i], self::VALID_CHARS, true);
            $addend = $factor * $code_point;
            $factor = ($factor === 2) ? 1 : 2;
            $addend = ($addend / $n) + ($addend % $n);
            $sum += $addend;
        }

        $remainer = ($sum % $n);
        $checkCodePoint = ($n - $remainer) % $n;

        return self::VALID_CHARS[$checkCodePoint];
    }
}