"""Classify companies by revenue band for segmentation."""

from typing import Any, Dict, Optional, Union
import re

from ._employee_count_parser import looks_like_employee_count, parse_employee_count


# Revenue bands for B2B segmentation (in USD)
REVENUE_BANDS = [
    {
        "min": 0,
        "max": 1_000_000,
        "label": "<$1M",
        "code": "micro",
        "typical_employees": "1-10",
    },
    {
        "min": 1_000_000,
        "max": 10_000_000,
        "label": "$1M-$10M",
        "code": "small",
        "typical_employees": "10-50",
    },
    {
        "min": 10_000_000,
        "max": 50_000_000,
        "label": "$10M-$50M",
        "code": "mid_market",
        "typical_employees": "50-250",
    },
    {
        "min": 50_000_000,
        "max": 100_000_000,
        "label": "$50M-$100M",
        "code": "upper_mid",
        "typical_employees": "250-500",
    },
    {
        "min": 100_000_000,
        "max": 500_000_000,
        "label": "$100M-$500M",
        "code": "enterprise",
        "typical_employees": "500-2500",
    },
    {
        "min": 500_000_000,
        "max": 1_000_000_000,
        "label": "$500M-$1B",
        "code": "large_enterprise",
        "typical_employees": "2500-5000",
    },
    {
        "min": 1_000_000_000,
        "max": float("inf"),
        "label": "$1B+",
        "code": "fortune_500",
        "typical_employees": "5000+",
    },
]

# ARR estimation multipliers by industry (SaaS benchmarks)
INDUSTRY_ARR_MULTIPLIERS = {
    "software": 1.2,  # Higher ARR per employee
    "technology": 1.15,
    "financial_services": 1.1,
    "healthcare": 0.95,
    "consulting": 1.05,
    "manufacturing": 0.7,
    "retail": 0.6,
    "education": 0.5,
    "non_profit": 0.3,
}

# Employee to revenue estimation (fallback when revenue unknown)
EMPLOYEE_TO_REVENUE = {
    # Employee count: (min_revenue, max_revenue, typical_revenue)
    (1, 10): (100_000, 2_000_000, 500_000),
    (11, 50): (1_000_000, 15_000_000, 5_000_000),
    (51, 200): (5_000_000, 50_000_000, 20_000_000),
    (201, 500): (20_000_000, 150_000_000, 75_000_000),
    (501, 1000): (50_000_000, 500_000_000, 200_000_000),
    (1001, 5000): (200_000_000, 2_000_000_000, 750_000_000),
    (5001, float("inf")): (500_000_000, 10_000_000_000, 2_000_000_000),
}


def classify_revenue_band(
    value: Union[str, int, float, Dict], **kwargs
) -> Dict[str, Any]:
    """
    Classify company into revenue bands for segmentation.

    Can accept:
    - Direct revenue number: 50000000 or "$50M"
    - Employee count (will estimate): {"employees": 200}
    - Combined data: {"revenue": "50M", "employees": 200, "industry": "software"}

    Returns:
    {
        "value": "$10M-$50M",
        "code": "mid_market",
        "confidence": 0.95,
        "revenue_estimate": 25000000,
        "arr_potential": "$500K-$2M",
        "sales_motion": "field_sales",
        "typical_deal_size": "$50K-$200K",
        "sales_cycle": "3-6 months",
        "budget_authority": "VP/Director level"
    }
    """
    # Handle None/empty
    if value is None:
        return {"value": None, "code": "unknown", "confidence": 0.0}

    # Parse input to get revenue and supporting data
    revenue = None
    employees = None
    industry = kwargs.get("industry", "")
    confidence = 1.0

    employee_reason = None

    if isinstance(value, dict):
        revenue = _parse_revenue(value.get("revenue"))
        employees, employee_reason, _ = parse_employee_count(
            value.get("employees") or value.get("company_size")
        )
        industry = value.get("industry", industry)
    elif isinstance(value, (int, float)):
        revenue = float(value)
    else:
        if looks_like_employee_count(value):
            employees, employee_reason, _ = parse_employee_count(value)
        else:
            revenue = _parse_revenue(value)
            if not revenue:
                employees, employee_reason, _ = parse_employee_count(value)

    # If we have revenue, classify directly
    if revenue:
        band = _classify_by_revenue(revenue)
        source = "revenue"
    # Otherwise estimate from employees
    elif employees:
        revenue = _estimate_revenue_from_employees(employees, industry)
        band = _classify_by_revenue(revenue)
        confidence = 0.7  # Lower confidence for estimates
        source = "employee_estimate"
    else:
        reason = "insufficient_data"
        if employee_reason == "ambiguous_range":
            reason = "ambiguous_employee_count"
        return {
            "value": None,
            "code": "unknown",
            "confidence": 0.0,
            "reason": reason,
        }

    # Calculate ARR potential (for SaaS/subscription businesses)
    arr_potential = _calculate_arr_potential(revenue, industry)

    # Determine sales motion and deal characteristics
    sales_characteristics = _determine_sales_characteristics(band["code"])

    result = {
        "value": band["label"],
        "code": band["code"],
        "confidence": round(confidence, 2),
        "revenue_estimate": int(revenue),
        "arr_potential": arr_potential,
        "source": source,
        **sales_characteristics,
    }

    # Add growth indicators if we have both revenue and employees
    if revenue and employees:
        result["revenue_per_employee"] = int(revenue / employees)
        efficiency = _assess_efficiency(revenue / employees, industry)
        result["efficiency_rating"] = efficiency

    return result


def _parse_revenue(value: Any) -> Optional[float]:
    """Parse revenue from various formats."""
    if isinstance(value, (int, float)):
        return float(value)

    if not value:
        return None

    s = str(value).upper().strip()

    # Remove currency symbols and commas
    s = re.sub(r"[$£€¥,]", "", s)

    # Handle millions/billions notation
    multiplier = 1
    if "B" in s or "BILLION" in s:
        multiplier = 1_000_000_000
        s = re.sub(r"B(ILLION)?", "", s)
    elif "M" in s or "MILLION" in s:
        multiplier = 1_000_000
        s = re.sub(r"M(ILLION)?", "", s)
    elif "K" in s or "THOUSAND" in s:
        multiplier = 1_000
        s = re.sub(r"K|THOUSAND", "", s)

    # Extract number
    match = re.search(r"[\d.]+", s)
    if match:
        try:
            return float(match.group()) * multiplier
        except ValueError:
            pass

    return None

def _classify_by_revenue(revenue: float) -> Dict[str, Any]:
    """Find the appropriate revenue band."""
    for band in REVENUE_BANDS:
        if band["min"] <= revenue < band["max"]:
            return band

    # Shouldn't reach here, but default to largest
    return REVENUE_BANDS[-1]


def _estimate_revenue_from_employees(employees: int, industry: str) -> float:
    """Estimate revenue based on employee count and industry."""
    # Find the appropriate employee range
    for (min_emp, max_emp), (
        min_rev,
        max_rev,
        typical_rev,
    ) in EMPLOYEE_TO_REVENUE.items():
        if min_emp <= employees <= max_emp:
            # Apply industry multiplier if known
            multiplier = INDUSTRY_ARR_MULTIPLIERS.get(
                industry.lower() if industry else "", 1.0
            )
            return typical_rev * multiplier

    # Default for very large companies
    return 2_000_000_000


def _calculate_arr_potential(revenue: float, industry: str) -> str:
    """Calculate potential ARR for SaaS sales."""
    # Typical SaaS spend is 3-7% of revenue for most companies
    min_spend_rate = 0.03
    max_spend_rate = 0.07

    # Adjust for industry
    if industry:
        industry_lower = industry.lower()
        if "tech" in industry_lower or "software" in industry_lower:
            min_spend_rate = 0.05
            max_spend_rate = 0.12
        elif "financial" in industry_lower:
            min_spend_rate = 0.04
            max_spend_rate = 0.09

    min_arr = revenue * min_spend_rate
    max_arr = revenue * max_spend_rate

    # Format the range
    return _format_money_range(min_arr, max_arr)


def _format_money_range(min_val: float, max_val: float) -> str:
    """Format a money range for display."""

    def format_single(val):
        if val >= 1_000_000_000:
            return f"${val/1_000_000_000:.1f}B"
        elif val >= 1_000_000:
            return f"${val/1_000_000:.0f}M"
        elif val >= 1_000:
            return f"${val/1_000:.0f}K"
        else:
            return f"${val:.0f}"

    return f"{format_single(min_val)}-{format_single(max_val)}"


def _determine_sales_characteristics(band_code: str) -> Dict[str, str]:
    """Determine sales motion and characteristics by band."""
    characteristics = {
        "micro": {
            "sales_motion": "self_serve",
            "typical_deal_size": "$1K-$10K",
            "sales_cycle": "0-30 days",
            "budget_authority": "Manager/Individual",
            "procurement_process": "Credit card",
            "key_stakeholders": "1-2 people",
        },
        "small": {
            "sales_motion": "inside_sales",
            "typical_deal_size": "$10K-$50K",
            "sales_cycle": "30-60 days",
            "budget_authority": "Director level",
            "procurement_process": "Simple approval",
            "key_stakeholders": "2-3 people",
        },
        "mid_market": {
            "sales_motion": "field_sales",
            "typical_deal_size": "$50K-$200K",
            "sales_cycle": "3-6 months",
            "budget_authority": "VP/Director level",
            "procurement_process": "RFP/Vendor evaluation",
            "key_stakeholders": "3-5 people",
        },
        "upper_mid": {
            "sales_motion": "field_sales",
            "typical_deal_size": "$200K-$500K",
            "sales_cycle": "4-9 months",
            "budget_authority": "VP/C-level",
            "procurement_process": "Formal RFP",
            "key_stakeholders": "5-8 people",
        },
        "enterprise": {
            "sales_motion": "enterprise_sales",
            "typical_deal_size": "$500K-$2M",
            "sales_cycle": "6-12 months",
            "budget_authority": "C-level/Board",
            "procurement_process": "Complex procurement",
            "key_stakeholders": "8-15 people",
        },
        "large_enterprise": {
            "sales_motion": "strategic_accounts",
            "typical_deal_size": "$1M-$5M",
            "sales_cycle": "9-18 months",
            "budget_authority": "C-level/Board",
            "procurement_process": "Strategic evaluation",
            "key_stakeholders": "10-20 people",
        },
        "fortune_500": {
            "sales_motion": "global_accounts",
            "typical_deal_size": "$5M+",
            "sales_cycle": "12-24 months",
            "budget_authority": "Board level",
            "procurement_process": "Enterprise agreement",
            "key_stakeholders": "20+ people",
        },
    }

    return characteristics.get(band_code, characteristics["mid_market"])


def _assess_efficiency(revenue_per_employee: float, industry: str) -> str:
    """Assess company efficiency based on revenue per employee."""
    # Benchmarks vary significantly by industry
    if revenue_per_employee > 500_000:
        return "highly_efficient"
    elif revenue_per_employee > 250_000:
        return "efficient"
    elif revenue_per_employee > 100_000:
        return "average"
    else:
        return "below_average"
