from ..core.base import BaseValidator

class RIF(BaseValidator):
    """
    Validator for Venezuelan RIF.
    Format: L-12345678-9 (Letter V, E, J, G, P + 8 digits + 1 check digit)
    Uses Modulo 11.
    """

    @classmethod
    def validate(cls, doc: str) -> bool:
        doc = doc.upper().replace('-', '').replace(' ', '')
        
        if len(doc) != 10:
            return False
            
        letter = doc[0]
        base = doc[1:-1]
        dv = int(doc[-1])
        
        if letter not in ['V', 'E', 'J', 'G', 'P']:
            return False
            
        # Letter values
        letter_values = {'V': 4, 'E': 8, 'J': 12, 'G': 20, 'P': 16}
        
        # Weights: 3, 2, 7, 6, 5, 4, 3, 2
        weights = [3, 2, 7, 6, 5, 4, 3, 2]
        
        total = letter_values[letter] * 4 # Wait, algorithm says:
        # (Digit * Weight) sum. 
        # But letter is part of it?
        # Standard algorithm:
        # Sum = (LetterValue) + (d1*3 + d2*2 + d3*7 + d4*6 + d5*5 + d6*4 + d7*3 + d8*2)
        # Wait, letter value is added directly? Or multiplied?
        # Research: "Sumar el valor de la letra..."
        # Let's assume it's added as a base value or multiplied by a specific weight?
        # Actually, usually it's: (LetterValue * 1) + ... ?
        # Let's re-check standard RIF algorithm.
        # "Multiplicar cada dígito por su peso... Sumar... Dividir entre 11..."
        # Letter values: V=4, E=8, J=12, P=16, G=20.
        # These look like pre-calculated (Value * Weight)?
        # If V=1, E=2, J=3... and weight is 4?
        # Let's assume the total starts with letter_values[letter].
        
        total = letter_values[letter] # Initial value from letter
        
        for i, digit in enumerate(base):
            total += int(digit) * weights[i]
            
        remainder = total % 11
        calculated_dv = 0 if remainder == 0 else 11 - remainder
        if calculated_dv >= 10: # Should be single digit
             calculated_dv = 0 # Verify this rule. Usually 11-11=0, 11-1=10? 
             # If remainder is 1, 11-1=10. RIF check digit is 0-9.
             # If result is 10, is it 0? Or invalid?
             # Most sources say: If remainder=0, DV=0. If remainder=1, DV=0?
             if calculated_dv == 10: calculated_dv = 0
             
        return dv == calculated_dv

    @classmethod
    def format(cls, doc: str) -> str:
        doc = doc.upper().replace('-', '').replace(' ', '')
        if len(doc) != 10:
             raise ValueError("RIF must have 10 characters")
        return f"{doc[0]}-{doc[1:9]}-{doc[9]}"

    @classmethod
    def generate(cls) -> str:
        """Generates a valid RIF."""
        import random
        letter = random.choice(['V', 'E', 'J', 'G', 'P'])
        base = "".join([str(random.randint(0, 9)) for _ in range(8)])
        
        letter_values = {'V': 4, 'E': 8, 'J': 12, 'G': 20, 'P': 16}
        weights = [3, 2, 7, 6, 5, 4, 3, 2]
        
        total = letter_values[letter]
        for i, digit in enumerate(base):
            total += int(digit) * weights[i]
            
        remainder = total % 11
        dv = 0 if remainder == 0 else 11 - remainder
        if dv >= 10: dv = 0
        
        return cls.format(f"{letter}{base}{dv}")
