"""Email value object.

Email is an immutable value object that represents a validated email address.
"""

import re
from typing import Any


class Email:
    """Email value object.
    
    Represents a validated email address.
    Immutable - once created, cannot be changed.
    
    Attributes:
        value: The email address string
    """
    
    EMAIL_REGEX = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
    
    def __init__(self, value: str):
        """Initialize email.
        
        Args:
            value: Email address string
            
        Raises:
            ValueError: If email format is invalid
        """
        if not self._is_valid(value):
            raise ValueError(f"Invalid email format: {value}")
        self._value = value.lower().strip()
    
    @property
    def value(self) -> str:
        """Get email value.
        
        Returns:
            str: Email address
        """
        return self._value
    
    @staticmethod
    def _is_valid(email: str) -> bool:
        """Validate email format.
        
        Args:
            email: Email string to validate
            
        Returns:
            bool: True if valid
        """
        if not email or not isinstance(email, str):
            return False
        return bool(Email.EMAIL_REGEX.match(email.strip()))
    
    def __str__(self) -> str:
        """String representation.
        
        Returns:
            str: Email address
        """
        return self._value
    
    def __repr__(self) -> str:
        """Developer representation.
        
        Returns:
            str: Email representation
        """
        return f"Email('{self._value}')"
    
    def __eq__(self, other: Any) -> bool:
        """Check equality.
        
        Args:
            other: Other object
            
        Returns:
            bool: True if equal
        """
        if not isinstance(other, Email):
            return False
        return self._value == other._value
    
    def __hash__(self) -> int:
        """Hash value.
        
        Returns:
            int: Hash
        """
        return hash(self._value)

