import re
from typing import Optional, Tuple


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


def parse_direct_url(step: str) -> Optional[str]:
    m = re.search(r"@https?://\S+", step)
    if m:
        return m.group(0)[1:]
    return None


def is_remove_button(step: str) -> bool:
    return bool(re.search(r"\bclick\s+on\s+['\"]?remove['\"]?\s+button\b", step, re.IGNORECASE))


def parse_type_allowed(step: str) -> Optional[str]:
    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


def is_open_family(step_lower: str) -> bool:
    return bool(re.search(r"\bopen\b.*family\s+safety(\s+(web)?page)?", step_lower))


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


def parse_toggle(step: str) -> Optional[Tuple[str, bool]]:
    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


def parse_verify_button(step: str) -> Optional[str]:
    m = re.search(r"\bverify\s+['\"]([^'\"]+)['\"][^\n]*\bbutton\s+is\s+visible", step, re.IGNORECASE)
    if m:
        return m.group(1).strip()
    return None


def parse_verify_text(step: str) -> Optional[str]:
    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


def is_back(step: str) -> bool:
    return bool(re.search(r"\b(go\s+back|navigate\s+back|back)\b", step, re.IGNORECASE))
