"""Check if email is role-based or generic."""

from typing import Dict, Any


# Common role-based email prefixes
ROLE_BASED_PREFIXES = {
    # Sales & Support
    "sales",
    "support",
    "help",
    "contact",
    "hello",
    "hi",
    "team",
    "service",
    "customerservice",
    "customer.service",
    "cs",
    # Information
    "info",
    "information",
    "enquiry",
    "enquiries",
    "inquiry",
    "inquiries",
    "feedback",
    "questions",
    "ask",
    "general",
    # Administrative
    "admin",
    "administrator",
    "office",
    "reception",
    "frontdesk",
    "mail",
    "postmaster",
    "webmaster",
    "hostmaster",
    # Technical
    "tech",
    "technical",
    "it",
    "helpdesk",
    "help.desk",
    "support.desk",
    "noreply",
    "no-reply",
    "donotreply",
    "do-not-reply",
    # HR & Recruiting
    "hr",
    "humanresources",
    "human.resources",
    "careers",
    "jobs",
    "recruiting",
    "recruitment",
    "talent",
    "hiring",
    # Finance & Legal
    "billing",
    "accounting",
    "accounts",
    "finance",
    "payments",
    "invoices",
    "legal",
    "compliance",
    "contracts",
    # Marketing
    "marketing",
    "press",
    "media",
    "pr",
    "publicrelations",
    "communications",
    "newsletter",
    "subscribe",
    "unsubscribe",
    # Operations
    "operations",
    "ops",
    "logistics",
    "procurement",
    "purchasing",
    "vendor",
    "suppliers",
    "partners",
    "partnerships",
    # Security & Abuse
    "security",
    "abuse",
    "spam",
    "phishing",
    "fraud",
    "privacy",
    "data",
    "gdpr",
    "ccpa",
    # Generic departments
    "all",
    "everyone",
    "staff",
    "employees",
    "company",
    "group",
    "department",
    "dept",
    "division",
}

# Convert to set for O(1) lookup
ROLE_BASED_SET = set(ROLE_BASED_PREFIXES)

# Additional patterns that indicate role-based
ROLE_PATTERNS = [
    # Department-based patterns
    r"^(sales|support|info|admin|hr|it|legal|finance|marketing|ops)\d*@",
    # Generic patterns
    r"^(team|group|dept|department)[\.\-_]",
    # No-reply patterns
    r"^(no[\.\-_]?reply|donotreply)",
    # Automated/system patterns
    r"^(system|automated|auto|bot|notification)",
]


def is_role_based_email(value: str) -> Dict[str, Any]:
    """
    Check if an email address is role-based or generic (not personal).

    Role-based emails are typically:
    - Department emails (sales@, support@)
    - Generic addresses (info@, hello@)
    - System emails (noreply@, admin@)

    Examples:
        "sales@company.com" -> True
        "john.smith@company.com" -> False
        "support@company.com" -> True
    """
    # Handle None/empty
    if value is None or str(value).strip() == "":
        return {"value": False, "confidence": 0.0, "reason": "empty"}

    s = str(value).strip().lower()
    if "@" not in s:
        return {"value": False, "confidence": 0.0, "reason": "invalid_email"}

    # Split email
    try:
        local_part, domain = s.split("@", 1)
    except ValueError:
        return {"value": False, "confidence": 0, "reason": "invalid_email"}

    if not local_part or not domain:
        return {"value": False, "confidence": 0, "reason": "invalid_email"}

    # Remove any + addressing
    if "+" in local_part:
        local_part = local_part.split("+")[0]

    # Check exact match
    if local_part in ROLE_BASED_SET:
        return {
            "value": True,
            "confidence": 1.0,
            "reason": "exact_match",
            "category": _categorize_role(local_part),
        }

    # Check without dots/dashes/underscores
    cleaned = local_part.replace(".", "").replace("-", "").replace("_", "")
    if cleaned in ROLE_BASED_SET:
        return {
            "value": True,
            "confidence": 0.95,
            "reason": "match_without_separators",
            "category": _categorize_role(cleaned),
        }

    # Check if starts with role-based prefix
    for prefix in ROLE_BASED_SET:
        if local_part.startswith(prefix):
            # Check if followed by number or separator
            remainder = local_part[len(prefix) :]
            if not remainder or remainder[0] in ".-_0123456789":
                return {
                    "value": True,
                    "confidence": 0.9,
                    "reason": "prefix_match",
                    "category": _categorize_role(prefix),
                }

    # Check for numbered department emails (e.g., sales1@, support2@)
    import re

    if re.match(r"^[a-z]+\d+$", local_part):
        base = re.sub(r"\d+$", "", local_part)
        if base in ROLE_BASED_SET:
            return {
                "value": True,
                "confidence": 0.9,
                "reason": "numbered_department",
                "category": _categorize_role(base),
            }

    # Check for compound role-based (e.g., sales-team@, support-desk@)
    parts = re.split(r"[\.\-_]", local_part)
    for part in parts:
        if part in ROLE_BASED_SET:
            return {
                "value": True,
                "confidence": 0.85,
                "reason": "compound_match",
                "category": _categorize_role(part),
            }

    # If none of the above, it's likely a personal email
    return {
        "value": False,
        "confidence": 0.8,
        "reason": "likely_personal",
        "local_part": local_part,
    }


def _categorize_role(role: str) -> str:
    """Categorize the type of role-based email."""
    categories = {
        "sales": ["sales", "revenue", "account"],
        "support": ["support", "help", "service", "cs", "customerservice"],
        "information": [
            "info",
            "information",
            "enquiry",
            "inquiry",
            "contact",
            "hello",
        ],
        "admin": ["admin", "office", "reception", "frontdesk"],
        "technical": ["tech", "it", "helpdesk", "webmaster", "postmaster"],
        "noreply": ["noreply", "no-reply", "donotreply", "do-not-reply"],
        "hr": ["hr", "humanresources", "careers", "jobs", "recruiting", "talent"],
        "finance": ["billing", "accounting", "finance", "payments", "invoices"],
        "legal": ["legal", "compliance", "contracts"],
        "marketing": ["marketing", "press", "media", "pr", "communications"],
        "operations": ["operations", "ops", "logistics", "procurement"],
        "security": ["security", "abuse", "spam", "privacy", "fraud"],
        "generic": ["all", "everyone", "team", "group", "staff", "company"],
    }

    for category, keywords in categories.items():
        if role in keywords:
            return category

    return "other"
