"""Calculate lead scores based on firmographic and behavioral signals."""

from typing import Dict, Any
import re


# Scoring weights (configurable)
SCORING_WEIGHTS = {
    "title_seniority": 30,  # Max 30 points
    "company_size": 25,  # Max 25 points
    "industry_fit": 20,  # Max 20 points
    "email_quality": 15,  # Max 15 points
    "completeness": 10,  # Max 10 points
}

# Title seniority scores
SENIORITY_SCORES = {
    "c_level": 1.0,  # CEO, CTO, CFO, etc.
    "vp": 0.85,  # VP level
    "director": 0.7,  # Director level
    "manager": 0.5,  # Manager level
    "senior": 0.35,  # Senior IC
    "junior": 0.2,  # Junior/Entry
    "unknown": 0.1,  # Unknown seniority
}

# Company size scores (employee count)
SIZE_SCORES = {
    "enterprise": 1.0,  # 1000+
    "mid_market": 0.85,  # 201-1000
    "smb": 0.65,  # 51-200
    "small": 0.4,  # 11-50
    "startup": 0.25,  # 1-10
    "unknown": 0.1,  # Unknown size
}

# High-value industries for B2B SaaS
HIGH_VALUE_INDUSTRIES = {
    "software",
    "technology",
    "financial services",
    "healthcare",
    "telecommunications",
    "manufacturing",
    "retail",
    "e-commerce",
    "consulting",
    "marketing technology",
    "cloud computing",
}

# Lead source quality multipliers
SOURCE_MULTIPLIERS = {
    "demo_request": 1.5,
    "contact_sales": 1.4,
    "pricing_page": 1.3,
    "content_download": 1.1,
    "webinar": 1.15,
    "event": 1.2,
    "partner": 1.25,
    "organic": 1.0,
    "paid": 0.9,
    "cold_outreach": 0.7,
    "list_upload": 0.6,
}


def calculate_lead_score(data: Dict[str, Any]) -> Dict[str, Any]:
    """
    Calculate a lead score from 0-100 based on multiple signals.

    Input data structure:
    {
        "title": "VP of Sales",
        "company_size": 500,  # or "Mid-Market"
        "industry": "Software",
        "email": "john@company.com",
        "company": "Acme Corp",
        "phone": "+14155551234",
        "lead_source": "demo_request",
        "engagement": {
            "email_opens": 3,
            "page_views": 10,
            "content_downloads": 2
        }
    }

    Returns:
    {
        "value": 75,  # Score 0-100
        "grade": "A",  # A, B, C, D, F
        "components": {
            "title_seniority": 25.5,
            "company_size": 21.25,
            "industry_fit": 20,
            "email_quality": 15,
            "completeness": 8
        },
        "factors": {
            "seniority_level": "vp",
            "company_segment": "mid_market",
            "is_target_industry": true,
            "has_business_email": true,
            "data_completeness": 0.8
        },
        "recommendations": ["High priority - VP at target company"]
    }
    """
    if not data:
        return {"value": 0, "grade": "F", "reason": "no_data"}

    score = 0
    components = {}
    factors = {}
    recommendations = []

    # 1. Title/Seniority scoring
    title = str(data.get("title", "")).lower()
    seniority_level = _detect_seniority(title)
    factors["seniority_level"] = seniority_level

    title_score = SENIORITY_SCORES.get(seniority_level, 0.1)
    components["title_seniority"] = round(
        title_score * SCORING_WEIGHTS["title_seniority"], 1
    )

    # 2. Company size scoring
    company_size = data.get("company_size")
    size_segment = _detect_size_segment(company_size)
    factors["company_segment"] = size_segment

    size_score = SIZE_SCORES.get(size_segment, 0.1)
    components["company_size"] = round(size_score * SCORING_WEIGHTS["company_size"], 1)

    # 3. Industry fit scoring
    industry = str(data.get("industry", "")).lower()
    is_target = any(ind in industry for ind in HIGH_VALUE_INDUSTRIES)
    factors["is_target_industry"] = is_target

    industry_score = 1.0 if is_target else 0.3
    components["industry_fit"] = round(
        industry_score * SCORING_WEIGHTS["industry_fit"], 1
    )

    # 4. Email quality scoring
    email = str(data.get("email", "")).lower()
    has_business_email = _is_business_email(email)
    factors["has_business_email"] = has_business_email

    email_score = 1.0 if has_business_email else 0.2
    components["email_quality"] = round(
        email_score * SCORING_WEIGHTS["email_quality"], 1
    )

    # 5. Data completeness scoring
    required_fields = ["title", "company", "email", "company_size", "industry"]
    present_fields = sum(1 for f in required_fields if data.get(f))
    completeness = present_fields / len(required_fields)
    factors["data_completeness"] = round(completeness, 2)

    components["completeness"] = round(
        completeness * SCORING_WEIGHTS["completeness"], 1
    )

    # Calculate base score
    base_score = sum(components.values())

    # Apply source multiplier if present
    lead_source = str(data.get("lead_source", "organic")).lower()
    multiplier = SOURCE_MULTIPLIERS.get(lead_source, 1.0)

    # Apply engagement boost if present
    engagement = data.get("engagement", {})
    if engagement:
        engagement_boost = _calculate_engagement_boost(engagement)
        multiplier *= 1 + engagement_boost

    # Final score (capped at 100)
    final_score = min(100, round(base_score * multiplier))

    # Determine grade
    if final_score >= 85:
        grade = "A"
        recommendations.append("High priority - immediate follow-up recommended")
    elif final_score >= 70:
        grade = "B"
        recommendations.append("Good lead - prioritize for outreach")
    elif final_score >= 55:
        grade = "C"
        recommendations.append("Qualified lead - add to nurture sequence")
    elif final_score >= 40:
        grade = "D"
        recommendations.append("Lower priority - needs qualification")
    else:
        grade = "F"
        recommendations.append("Low quality - consider for future campaigns only")

    # Add specific recommendations
    if seniority_level in ["c_level", "vp"]:
        recommendations.append(
            f"Decision maker ({seniority_level.replace('_', '-').upper()})"
        )

    if size_segment in ["enterprise", "mid_market"]:
        recommendations.append(
            f"Target company size ({size_segment.replace('_', ' ').title()})"
        )

    if is_target and has_business_email:
        recommendations.append("Ideal customer profile match")

    return {
        "value": final_score,
        "grade": grade,
        "components": components,
        "factors": factors,
        "recommendations": recommendations[:3],  # Top 3 recommendations
        "source_multiplier": round(multiplier, 2),
    }


def _detect_seniority(title: str) -> str:
    """Detect seniority level from title."""
    if not title:
        return "unknown"

    title_lower = title.lower()

    # C-level check
    c_level_patterns = [
        r"\bc[etoxmifs]o\b",  # CEO, CTO, CFO, CMO, CIO, CSO, etc.
        r"\bchief\b",
        r"\bfounder\b",
        r"\bowner\b",
        r"\bpresident\b",
    ]
    if any(re.search(p, title_lower) for p in c_level_patterns):
        return "c_level"

    # VP check
    if any(x in title_lower for x in ["vp ", "v.p.", "vice president", "evp", "svp"]):
        return "vp"

    # Director check
    if "director" in title_lower:
        return "director"

    # Manager check
    if "manager" in title_lower or "head of" in title_lower:
        return "manager"

    # Senior check
    if any(x in title_lower for x in ["senior", "lead", "principal", "staff"]):
        return "senior"

    # Junior check
    if any(x in title_lower for x in ["junior", "jr", "associate", "entry", "intern"]):
        return "junior"

    return "unknown"


def _detect_size_segment(size: Any) -> str:
    """Detect company size segment."""
    if not size:
        return "unknown"

    # Handle numeric values
    if isinstance(size, (int, float)):
        if size >= 1000:
            return "enterprise"
        elif size >= 201:
            return "mid_market"
        elif size >= 51:
            return "smb"
        elif size >= 11:
            return "small"
        else:
            return "startup"

    # Handle string values
    size_str = str(size).lower()
    if any(x in size_str for x in ["enterprise", "1000+", "1k+", "5000+", "5k+"]):
        return "enterprise"
    elif any(x in size_str for x in ["mid", "500", "200-1000", "201-1000"]):
        return "mid_market"
    elif any(x in size_str for x in ["smb", "51-200", "100"]):
        return "smb"
    elif any(x in size_str for x in ["small", "11-50", "10-50"]):
        return "small"
    elif any(x in size_str for x in ["startup", "1-10", "<10"]):
        return "startup"

    return "unknown"


def _is_business_email(email: str) -> bool:
    """Check if email is business (not personal)."""
    if not email or "@" not in email:
        return False

    personal_domains = {
        "gmail.com",
        "yahoo.com",
        "hotmail.com",
        "outlook.com",
        "aol.com",
        "icloud.com",
        "mail.com",
        "protonmail.com",
        "yandex.com",
        "zoho.com",
        "qq.com",
        "163.com",
    }

    domain = email.split("@")[-1].lower()
    return domain not in personal_domains


def _calculate_engagement_boost(engagement: Dict) -> float:
    """Calculate engagement boost multiplier (0.0 to 0.5)."""
    boost = 0.0

    # Email engagement
    email_opens = engagement.get("email_opens", 0)
    if email_opens > 5:
        boost += 0.15
    elif email_opens > 2:
        boost += 0.08

    # Web engagement
    page_views = engagement.get("page_views", 0)
    if page_views > 20:
        boost += 0.15
    elif page_views > 10:
        boost += 0.08

    # Content engagement
    downloads = engagement.get("content_downloads", 0)
    if downloads > 3:
        boost += 0.1
    elif downloads > 0:
        boost += 0.05

    # Event participation
    if engagement.get("webinar_attended"):
        boost += 0.1

    return min(0.5, boost)  # Cap at 50% boost
