"""
Verhoeff Checksum Algorithm
Used for generating Tax ID check digits
"""


class Verhoeff:
    """
    Implementation of Verhoeff checksum algorithm
    Used by Iranian Tax System for Tax ID validation
    """
    
    # Multiplication table
    d = [
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
        [1, 2, 3, 4, 0, 6, 7, 8, 9, 5],
        [2, 3, 4, 0, 1, 7, 8, 9, 5, 6],
        [3, 4, 0, 1, 2, 8, 9, 5, 6, 7],
        [4, 0, 1, 2, 3, 9, 5, 6, 7, 8],
        [5, 9, 8, 7, 6, 0, 4, 3, 2, 1],
        [6, 5, 9, 8, 7, 1, 0, 4, 3, 2],
        [7, 6, 5, 9, 8, 2, 1, 0, 4, 3],
        [8, 7, 6, 5, 9, 3, 2, 1, 0, 4],
        [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
    ]
    
    # Permutation table
    p = [
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
        [1, 5, 7, 6, 2, 8, 3, 0, 9, 4],
        [5, 8, 0, 3, 7, 9, 6, 1, 4, 2],
        [8, 9, 1, 6, 0, 4, 3, 5, 2, 7],
        [9, 4, 5, 3, 1, 2, 6, 8, 7, 0],
        [4, 2, 8, 6, 5, 7, 3, 9, 0, 1],
        [2, 7, 9, 3, 8, 0, 6, 4, 1, 5],
        [7, 0, 4, 6, 9, 1, 3, 2, 5, 8]
    ]
    
    # Inverse table
    inv = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9]
    
    @classmethod
    def calculate(cls, number_str: str) -> int:
        """
        Calculate Verhoeff check digit
        
        Args:
            number_str: Numeric string to calculate check digit for
            
        Returns:
            Check digit (0-9)
        """
        c = 0
        for i, digit in enumerate(reversed(number_str)):
            c = cls.d[c][cls.p[i % 8][int(digit)]]
        return cls.inv[c]
    
    @classmethod
    def validate(cls, number_str: str) -> bool:
        """
        Validate a number with Verhoeff check digit
        
        Args:
            number_str: Number including check digit
            
        Returns:
            True if valid, False otherwise
        """
        c = 0
        for i, digit in enumerate(reversed(number_str)):
            c = cls.d[c][cls.p[i % 8][int(digit)]]
        return c == 0
