from ..core.base import BaseValidator
import re

class RFC(BaseValidator):
    """
    Validator for Mexican RFC (Registro Federal de Contribuyentes).
    Persona Física: 13 chars.
    Persona Moral: 12 chars.
    """

    @classmethod
    def clean(cls, doc: str) -> str:
        return doc.upper().replace(' ', '').replace('-', '')

    @classmethod
    def validate(cls, doc: str) -> bool:
        doc = cls.clean(doc)
        
        if len(doc) not in [12, 13]:
            return False
            
        # Regex
        if len(doc) == 13: # Persona Física
            # 4 letters, 6 digits, 3 alphanumeric
            if not re.match(r'^[A-Z&Ñ]{4}[0-9]{6}[A-Z0-9]{3}$', doc):
                return False
        else: # Persona Moral
            # 3 letters, 6 digits, 3 alphanumeric
            if not re.match(r'^[A-Z&Ñ]{3}[0-9]{6}[A-Z0-9]{3}$', doc):
                return False
                
        # Check digit calculation is complex and often skipped or done via API.
        # However, there is a standard algorithm (Modulo 11).
        # Let's implement a basic version if possible, or stick to format for now as requested "Best in LatAm" implies robustness.
        # But RFC check digit depends on a specific table and logic for homoclave which is not public/standard for all cases.
        # Many libraries only validate format.
        # Let's stick to strict format validation + date validation.
        
        # Date validation
        try:
            year = int(doc[-9:-7])
            month = int(doc[-7:-5])
            day = int(doc[-5:-3])
            if month < 1 or month > 12: return False
            if day < 1 or day > 31: return False
        except:
            return False
            
        return True

    @classmethod
    def format(cls, doc: str) -> str:
        doc = cls.clean(doc)
        if not cls.validate(doc):
             raise ValueError("Invalid RFC format")
        return doc
