import re
from typing import Optional, Tuple


class RegexPatterns:
    """Regex utility class for pattern matching and text extraction."""
    
    @staticmethod
    def normalize_step(step: str) -> Tuple[str, str]:
        """Return (step_lower, step_normalized).

        - step_lower: lowercased and stripped
        - step_normalized: quotes removed and collapsed whitespace
        """
        step_lower = (step or "").lower().strip()
        step_normalized = re.sub(r'["\']', '', step_lower)
        step_normalized = re.sub(r'\s+', ' ', step_normalized).strip()
        return step_lower, step_normalized
    
    @staticmethod
    def parse_direct_url(step: str) -> Optional[str]:
        """Extract URL starting with @ from step."""
        m = re.search(r"@https?://\S+", step)
        if m:
            return m.group(0)[1:]
        return None
    
    @staticmethod
    def is_remove_button(step: str) -> bool:
        """Check if step contains 'click on remove button' pattern."""
        return bool(re.search(r"\bclick\s+on\s+['\"]?remove['\"]?\s+button\b", step, re.IGNORECASE))
    
    @staticmethod
    def parse_type_allowed(step: str) -> Optional[str]:
        """Extract text to type for allowed sites pattern."""
        m = re.search(r"\btype\s+['\"]([^'\"]+)['\"][^\n]*?(textbox|input)[^\n]*?(allowed\s+sites|allow\s+sites)\b", step, re.IGNORECASE)
        if m:
            return m.group(1).strip()
        return None
    
    @staticmethod
    def is_open_family(step_lower: str) -> bool:
        """Check if step contains 'open family safety' pattern."""
        return bool(re.search(r"\bopen\b.*family\s+safety(\s+(web)?page)?", step_lower))
    
    @staticmethod
    def disambiguate_add_website(step_lower: str) -> Optional[str]:
        """Return 'allow', 'block', or None based on context for 'add a website' steps."""
        if not re.search(r"add\s+a\s+website", step_lower):
            return None
        if re.search(r"\ballow\s+sites\b", step_lower):
            return "allow"
        if re.search(r"\bblock\s+sites\b", step_lower):
            return "block"
        return None
    
    @staticmethod
    def parse_toggle(step: str) -> Optional[Tuple[str, bool]]:
        """Parse toggle instruction and return (label, desired_state)."""
        m = re.search(r"\bensure\s+the\s+toggle\s+for\s+['\"]?(.+?)['\"]?\s+is\s+(on|off)\b", step, re.IGNORECASE)
        if m:
            label = m.group(1).strip()
            desired = m.group(2).strip().lower() == "on"
            return label, desired
        return None
    
    @staticmethod
    def parse_verify_button(step: str) -> Optional[str]:
        """Extract button text from verify button visibility pattern."""
        m = re.search(r"\bverify\s+['\"]([^'\"]+)['\"][^\n]*\bbutton\s+is\s+visible", step, re.IGNORECASE)
        if m:
            return m.group(1).strip()
        return None
    
    @staticmethod
    def parse_verify_text(step: str) -> Optional[str]:
        """Extract text to verify from step."""
        m = re.search(r"\bverify\s+['\"]([^'\"]+)['\"][^\n]*", step, re.IGNORECASE)
        if not m:
            m = re.search(r"\bverify\s+([\w\s:/._-]{3,})", step, re.IGNORECASE)
        if m:
            return m.group(1).strip()
        return None
    
    @staticmethod
    def is_back(step: str) -> bool:
        """Check if step contains 'go back' or 'navigate back' pattern."""
        return bool(re.search(r"\b(go\s+back|navigate\s+back|back)\b", step, re.IGNORECASE))


# Backward compatibility: keep module-level functions as wrappers
def normalize_step(step: str) -> Tuple[str, str]:
    """Module-level function wrapper for backward compatibility."""
    return RegexPatterns.normalize_step(step)


def parse_direct_url(step: str) -> Optional[str]:
    """Module-level function wrapper for backward compatibility."""
    return RegexPatterns.parse_direct_url(step)


def is_remove_button(step: str) -> bool:
    """Module-level function wrapper for backward compatibility."""
    return RegexPatterns.is_remove_button(step)


def parse_type_allowed(step: str) -> Optional[str]:
    """Module-level function wrapper for backward compatibility."""
    return RegexPatterns.parse_type_allowed(step)


def is_open_family(step_lower: str) -> bool:
    """Module-level function wrapper for backward compatibility."""
    return RegexPatterns.is_open_family(step_lower)


def disambiguate_add_website(step_lower: str) -> Optional[str]:
    """Module-level function wrapper for backward compatibility."""
    return RegexPatterns.disambiguate_add_website(step_lower)


def parse_toggle(step: str) -> Optional[Tuple[str, bool]]:
    """Module-level function wrapper for backward compatibility."""
    return RegexPatterns.parse_toggle(step)


def parse_verify_button(step: str) -> Optional[str]:
    """Module-level function wrapper for backward compatibility."""
    return RegexPatterns.parse_verify_button(step)


def parse_verify_text(step: str) -> Optional[str]:
    """Module-level function wrapper for backward compatibility."""
    return RegexPatterns.parse_verify_text(step)


def is_back(step: str) -> bool:
    """Module-level function wrapper for backward compatibility."""
    return RegexPatterns.is_back(step)
