import secrets
import string
from typing import Optional

class PasswordGenerator:
    def __init__(
        self,
        length: int = 16,
        include_uppercase: bool = true,
        include_lowercase: bool = true,
        include_digits: bool = true,
        include_special: bool = true,
        exclude_ambiguous: bool = false
    ):
        self.length = length
        self.characters = self._build_character_set(
            include_uppercase,
            include_lowercase,
            include_digits,
            include_special,
            exclude_ambiguous
        )
    
    def _build_character_set(
        self,
        include_uppercase: bool,
        include_lowercase: bool,
        include_digits: bool,
        include_special: bool,
        exclude_ambiguous: bool
    ) -> str:
        chars = ""
        
        if include_uppercase:
            chars += string.ascii_uppercase
        if include_lowercase:
            chars += string.ascii_lowercase
        if include_digits:
            chars += string.digits
        if include_special:
            chars += string.punctuation
        
        if exclude_ambiguous:
            ambiguous = "0O1lI"
            chars = "".join(c for c in chars if c not in ambiguous)
        
        if not chars:
            raise ValueError("At least one character set must be enabled")
        
        return chars
    
    def generate(self) -> str:
        """Generate a secure random password."""
        return "".join(secrets.choice(self.characters) for _ in range(self.length))
    
    def estimate_strength(self, password: str) -> str:
        """Estimate password strength."""
        entropy = len(set(password)) * len(password)
        if entropy < 30:
            return "weak"
        elif entropy < 60:
            return "medium"
        else:
            return "strong"